Re: Concatenating/inserting strings with backslashes

2012-11-10 Thread Alan DeKok
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

2012-11-09 Thread Brian Julin

 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

2012-11-09 Thread Phil Mayers

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

2012-11-09 Thread Brian Candler
 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

2012-11-09 Thread Brian Julin


 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