Re: Concatenating/inserting strings with backslashes
Brian Candler wrote: Here's something weird. I'm trying to concatenate some strings which contain backslash n (i.e. not a newline). Well... that's all pretty hacky. It's made worse by Reply-Message being automatically expanded, whereas other attributes aren't. Try your tests below using Filter-Id, and they will be different. The server has grown over the years in a fairly ad-hoc way. I welcome suggestions for sanitizing how it deals with string. Alan DeKok. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
RE: Concatenating/inserting strings with backslashes
Brian Candler writes: Or is there another way I can concatenate strings, which doesn't involve expanding them into another string? The workaround I've used for this is to feed the value through a regexp match to get it into %{1}, which does not seem to be subject to unescaping. try: if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message = stuff %{1} } } - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Concatenating/inserting strings with backslashes
On 09/11/12 15:39, Brian Candler wrote: Here's something weird. I'm trying to concatenate some strings which contain backslash n (i.e. not a newline). Uh oh... here be dragons! In a normal string literal, I have to enter four backslashes: update reply { Reply-Message := anb } (\\n gives a newline, \\\n gives backslash followed by newline) Yeah; I think there is a similar thing happening here to the regexp stuff I discussed on -devel recently. I think what happens in the code is this: 1. lib/token.c:gettoken loads the config file and performs backslash processing on any quoted strings 2. conffile.c:cf_pairtovp loads the VP update list at config load time, and sets the do_xlat flag on any that are double-quoted 3. modcall.c:modcall calls radius_update_attrlist 4. evaluate.c:radius_update_attrlist checks the do_xlat flag on the VP, which was set at config load, and calls expand_string (which calls radius_xlat) followed by pairparsevalue. The net effect is that: update x { Foo = an } ...is de-escaped many times: * into abackslashbackslashn by the gettoken / config file loader * into abackslashn by radius_xlat * into anewline by pairparsevalue (on the result of radius_xlat) This kind of thing is pretty common - exim has a similar problem. It's difficult to know what to do about it in a manner that's universally satisfactory. One solution is to not process \x anywhere except loading from config files, but that's likely a very significant backwards compatibility break... you also might *want* to provide a way for people to interpret escapes again (though this can be done with an xlat e.g. %{unescape:%{something-that-returns-backslash-n}} == newline Others options exist. Personally I find the existing behaviour quite surprising, but it's also something I very seldom run into, so don't worry too much about. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
Re: Concatenating/inserting strings with backslashes
try: if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message = stuff %{1} } } Nice idea, but it appears to suffer the same expansion problem. As you have written it gives this error: Bare %{...} is invalid in condition at: %{reply:Reply-Message} =~ /(.*)/) Adding the double quotes: update reply { Reply-Message := foo } if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message := %{1}nbar } } if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message := %{1}nbaz } } This gives foo newline bar newline baz update reply { Reply-Message := foo } if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message := %{1}nbar } } if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message := %{1}nbaz } } This gives foo newline bar backslash n baz Regards, Brian. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
RE: Concatenating/inserting strings with backslashes
Brian Candler wrote try: if (%{reply:Reply-Message} =~ /(.*)/) { update reply { Reply-Message = stuff %{1} } } Nice idea, but it appears to suffer the same expansion problem. As you have written it gives this error: Bare %{...} is invalid in condition at: %{reply:Reply-Message} =~ /(.*)/) Adding the double quotes: Oh right. I usually do this with e.g. User-Name without having to specify the attribute list explicitly; I forget whether syntax works to do that with a raw variable. I know outer.VarName works raw, so maybe just reply:Reply-Message without the braces or quotes? - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html