evaluate.c & strings with "\" in them

Phil Mayers p.mayers at imperial.ac.uk
Wed Oct 10 19:51:17 CEST 2012


If I do this:

echo User-Name='foo\bar' | radclient ...

...and try to match this in unlang:

if (User-Name =~ /^(.+)\\\\(.+)$/) {

...which corresponds to a regex:

^(.+)\\(.+)$

...it doesn't work. I think this is because evaluate.c:radius_do_cmp 
calls vp_print_value(..., 0) for T_OP_REG_*. That final arugment "0" 
means "escape the string" so the value compared against gets turned into:

foo\\bar

...which needs a regex:

^(.+)\\\\(.+)$

...which needs a condition:

if (User-Name =~ /^(.+)\\\\\\\\(.+)$/) {

This seems a bit crazy, but is also inconsistent with the "users"-file 
stuff in valuepair.c - this uses radius_xlat (or vp_prints_value 
directly, now) which finishes up in "vp_prints_value(..., -1) which 
means "value verbatim", so doesn't need quad-escaping.

The fix is pretty simple:

https://github.com/philmayers/freeradius-server/commit/2695a37464560dbd42b108a46d0fa70ab7ae45af

...but is sadly not a backwards-compatible change.


The other thing is, do we actually need to handle "\" inside // at all, 
with the exception of escaping the regex delimiter? Or could we just 
pass "\" straight through to to the regex engine? To give you an idea of 
what I mean (with a bit of extra flags magic too):

https://github.com/philmayers/freeradius-server/commit/7c322b36d603d0189c729477eab5ef704ba317b0

if (User-Name =~ !^(.+)\\(.+)$!ims8) {
   ...
}

The choice of "!" is arbitrary, could be anything, indeed, could be 
selectable sed-style by inspecting the 1st character:

if (User-Name =~ @regex at flags)

...but letting it be something other than "/" helps avoid leaning 
toothpick syndrome.

Thoughts welcome. Just idly playing here really.


More information about the Freeradius-Devel mailing list