FN5MOBGAHLSAECHXAJH3K54DOGLGUN7X7CAANQVCMP3ISA4B6YQAC WZ3MWMMPEI2EXM7VWKHENSKLSL4XRIB5EG7XYGPMBEUMXSYPD4NAC 5QTIOZGNTG3GABQSQSCOKM7RYG5HMCMVTLJSXRSTTQUZOBDA6AIAC BUVYRWELMJFTCPOCG4GITLVMZW2LJNPDXER4VFDYOBYE4WULDXWQC STYN6QCIAVRFWNOUBGZXNW2ABLUC2GNTFTQLEPSTC4MJEPWG5O5AC QNGWKBROYBNQFPIS4AD4GSIWVGPVEMWISKVHTBGPJ3EF2X4HBKWAC DG4L5ELJFZS5JATC47CHOCESJM5H3XSL4WDBXNV4ADTUTMMKWZDAC UW27LKXM2BJ77FQLTY4WPKDSSWI2RFNFRJ7CB4U3TS7KYVIV72LQC JDZASPALXSFZOL3MXCKBPX74CUD3W743ZJ6W2422FIJ7NJOD67ZAC NEUQJ7FRWFVZ7HPXGLLBU55FH6OSB374SQSRGIAAA233KFGEKTDAC 6WM2DD32XSC2HFLOXBDPFCU6BI2BD5ZYFGBIEIVEQOKWRCNTXROQC rsprintf rprintf with-encrypted-input-from
rsprintf rprintf with-encrypted-input-from assq** Bugs fixed*** Backslash escapes on a continuation line ending a stringA bug in a regular expression in the tokenizer made it fail torecognize the end of a string literal if there were backslash-escapedcharacters on that line, particularly right before the endingdouble-quote character. This is now tested for and fixed, and the codeand tests are commented.*** assoc vs. assqIn previous versions, the assoc function, for searching an alist foran association, was actually assq, because it used eq for comparison.assoc is supposed to use equal. This has now been set straight: assquses eq, assoc uses equal.
A bug in a regular expression in the tokenizer made it fail torecognize the end of a string literal if there were backslash-escapedcharacters on that line, particularly right before the endingdouble-quote character. This is now tested for and fixed, and the codeand tests are commented.
hdlrs = _cons(_cadr(form), hdlrs) # unevaluated fwiwx = _evprog(_cddr(form), env, env, d+1, hdlrs, st, errp)if(errp[1]) {# don't pass a true errp in: the eval will quitdelete no_errpno_errp[1] = 0return _eval3(_cons(_car(hdlrs),_cons(_cons(_symbol("quote"),_cons(st, _nil())),_nil())),env, env, d+1, _cdr(hdlrs), st, no_errp)} else {return x}
return _handle(_cdr(form), env, d+1, hdlrs, st, errp)
}}function _handle(forms, env, d, hdlrs, st, errp, x, no_errp, hp) {hdlrs = _cons(_car(forms), hdlrs) # unevaluated fwiwx = _evprog(_cdr(forms), env, env, d+1, hdlrs, st, errp)if(errp[1]) {logg_dbg("handle", "errp[2] is " errp[2], d)logg_dbg("handle", "which is " _repr(errp[2]), d)# don't pass a true errp in: the eval will quitdelete no_errpno_errp[1] = 0hp = _cons(_cons(_keyword("evaltrace"),_cons(st,_nil())),_cons(_cons(_keyword("errorform"),_cons(errp[2],_nil())),_nil()))logg_dbg("handle", "hp is " hp " which is " _repr(hp))return _eval3(_cons(_car(hdlrs),_cons(_cons(_symbol("quote"),_cons(hp,_nil())),_nil())),env, env, d+1, _cdr(hdlrs), st, no_errp)} else {return x
EXTRA_AWK_ARGS="-v KEY_FILE=keyfile" lisp_eval_should_be '(gsub "foo" S"bar" "foobarbaz")' 'S"(redacted)"' 'gsub with secret strings returns a secret string'EXTRA_AWK_ARGS="-v KEY_FILE=keyfile" lisp_eval_should_be '(unsafe-reveal (gsub "foo" S"bar" "foobarbaz"))' '"barbarbaz"' 'gsub with secret strings returns the correct secret string'
function _gsub3(r, t, s, new_s, rv) {if(_TYPE[r] == "s") {if(_TYPE[t] == "s") {if(_TYPE[s] == "s") {# whoa nelly, destructive update.new_s = _STRING[s]gsub(_STRING[r], _STRING[t], new_s)return _string(new_s)} else {logg_err("_gsub3", "non-string s " _repr(s))return _nil()}} else {logg_err("_gsub3", "non-string t " _repr(t))return _nil()}
function _gsub3(r, t, s, env, d, hdlrs, st, errp, secp, new_s, rv) {# most common case first and quickest:if(_TYPE[r] == "s" && _TYPE[t] == "s" && _TYPE[s] == "s") {# whoa nelly, destructive update.new_s = _STRING[s]gsub(_STRING[r], _STRING[t], new_s)return _string(new_s)
logg_err("_gsub3", "non-string r " _repr(r))return _nil()
secp=0if( _TYPE[r] == "s") r = _STRING[r]else if(_TYPE[r] == "S") { r = _SECRET_STRING[r]; secp=1; }else if(_TYPE[r] == "e") {r = _decrypt(_ENCRYPTED_STRING[r], env, d+1, hdlrs, st, errp)secp = 1} else return _error(_cons("_gsub3: cannot work with r param %s",_cons(r, _nil())),env, d+1, hdlrs, st, errp)if( _TYPE[t] == "s") t = _STRING[t]else if(_TYPE[t] == "S") { t = _SECRET_STRING[t]; secp=1; }else if(_TYPE[t] == "e") {t = _decrypt(_ENCRYPTED_STRING[t], env, d+1, hdlrs, st, errp)secp = 1} else return _error(_cons("_gsub3: cannot work with t param %s",_cons(t, _nil())),env, d+1, hdlrs, st, errp)if( _TYPE[s] == "s") s = _STRING[s]else if(_TYPE[s] == "S") { s = _SECRET_STRING[s]; secp=1; }else if(_TYPE[s] == "e") {s = _decrypt(_ENCRYPTED_STRING[s], env, d+1, hdlrs, st, errp)secp=1} else return _error(_cons("_gsub3: cannot work with s param %s",_cons(s, _nil())),env, d+1, hdlrs, st, errp)# gsub destructively updatesgsub(r, t, s)if(secp) return _secret_string(s)else return _string(s)