2 # Tests for parsing conditional expressions.
8 # A bunch of errors, in the order that the error strings
12 data ERROR offset 6 End of string after escape
15 data ERROR offset 2 Unterminated string
18 data ERROR offset 1 Empty string is invalid
21 data ERROR offset 2 Empty string is invalid
24 data ERROR offset 11 No closing brace at end of string
27 data ERROR offset 1 Empty string is invalid
29 condition ((ok || handled) foo)
30 data ERROR offset 17 Unexpected text after condition
32 # escapes in names are illegal
33 condition (ok\ foo || handled)
34 data ERROR offset 3 Unexpected escape
36 condition (ok FOO handled)
37 data ERROR offset 4 Invalid text. Expected comparison operator
39 condition (ok !x handled)
40 data ERROR offset 4 Invalid operator
42 condition (ok =x handled)
43 data ERROR offset 4 Invalid operator
45 condition (ok =~ handled)
46 data ERROR offset 7 Expected regular expression
48 condition (ok == /foo/)
49 data ERROR offset 7 Unexpected regular expression
51 condition (ok == handled"foo")
52 data ERROR offset 14 Unexpected start of string
54 # And now we have a bunch of VALID conditions we want to parse.
57 condition ((((((ok))))))
61 # Extra braces get squashed
63 condition (&User-Name == &User-Password)
64 data &User-Name == &User-Password
73 data ERROR offset 1 Double negation is invalid
79 # These next two are identical after normalization
81 condition (&User-Name == &User-Password || &Filter-Id == &Reply-Message)
82 data &User-Name == &User-Password || &Filter-Id == &Reply-Message
84 condition ((&User-Name == &User-Password) || (&Filter-Id == &Reply-Message))
85 data &User-Name == &User-Password || &Filter-Id == &Reply-Message
87 condition (!(&User-Name == &User-Password) || (&Filter-Id == &Reply-Message))
88 data !&User-Name == &User-Password || &Filter-Id == &Reply-Message
90 # different from the previous ones.
91 condition (!((&User-Name == &User-Password) || (&Filter-Id == &Reply-Message)))
92 data !(&User-Name == &User-Password || &Filter-Id == &Reply-Message)
94 condition (!(&User-Name == &User-Password) || (&Filter-Id == &Reply-Message))
95 data !&User-Name == &User-Password || &Filter-Id == &Reply-Message
97 condition ((a == b) || (c == d)))
98 data ERROR offset 22 Unexpected closing brace
100 condition (handled && (Response-Packet-Type == Access-Challenge))
101 data handled && &Response-Packet-Type == Access-Challenge
103 # This is OK, without the braces
104 condition handled && &Response-Packet-Type == Access-Challenge
105 data handled && &Response-Packet-Type == Access-Challenge
107 # and this, though it's not a good idea.
108 condition handled &&&Response-Packet-Type == Access-Challenge
109 data handled && &Response-Packet-Type == Access-Challenge
111 condition /foo/ =~ bar
112 data ERROR offset 0 Conditional check cannot begin with a regular expression
114 condition reply == request
115 data ERROR offset 0 Cannot use list references in condition
117 condition reply == "hello"
118 data ERROR offset 0 Cannot use list references in condition
120 condition "hello" == reply
121 data ERROR offset 0 Cannot use list references in condition
123 condition request:User-Name == reply:User-Name
124 data &User-Name == &reply:User-Name
127 # Convert !~ to !(COND) for regex
129 condition foo =~ /bar/
132 condition foo !~ /bar/
135 condition !foo !~ /bar/
139 # Convert != to !(COND) for normal checks
141 condition &User-Name == &User-Password
142 data &User-Name == &User-Password
144 condition &User-Name != &User-Password
145 data !&User-Name == &User-Password
147 condition !&User-Name != &User-Password
148 data &User-Name == &User-Password
150 condition <ipv6addr>foo
151 data ERROR offset 0 Cannot do cast for existence check
153 condition <ipaddr>Filter-Id == &Framed-IP-Address
154 data <ipaddr>&Filter-Id == &Framed-IP-Address
156 condition <ipaddr>Filter-Id == <ipaddr>&Framed-IP-Address
157 data ERROR offset 21 Unnecessary cast
159 condition <ipaddr>Filter-Id == <integer>&Framed-IP-Address
160 data ERROR offset 21 Cannot cast to a different data type
162 condition <ipaddr>Filter-Id == <blerg>&Framed-IP-Address
163 data ERROR offset 22 Invalid data type in cast
168 condition <ipaddr>Filter-Id == "127.0.0.1"
169 data <ipaddr>&Filter-Id == '127.0.0.1'
171 condition <ipaddr>127.0.0.1 < &Framed-IP-Address
172 data &Framed-IP-Address > 127.0.0.1
174 # =* and !* are only for attrs / lists
175 condition "foo" !* bar
176 data ERROR offset 6 Cannot use !* on a string
178 condition "foo" =* bar
179 data ERROR offset 6 Cannot use =* on a string
181 # existence checks don't need the RHS
182 condition User-Name =* bar
185 condition User-Name !* bar
188 condition !User-Name =* bar
191 condition !User-Name !* bar
194 # redundant casts get squashed
195 condition <ipaddr>Framed-IP-Address == 127.0.0.1
196 data &Framed-IP-Address == 127.0.0.1
198 condition <cidr>Framed-IP-Address <= 192.168/16
199 data <ipv4prefix>&Framed-IP-Address <= 192.168/16
201 # string attributes must be string
202 condition User-Name == "bob"
203 data &User-Name == "bob"
205 condition User-Name == `bob`
206 data &User-Name == `bob`
208 condition User-Name == 'bob'
209 data &User-Name == "bob"
211 condition User-Name == bob
212 data ERROR offset 13 Must have string as value for attribute
214 # Integer (etc.) types must be "bare"
215 condition Session-Timeout == 10
216 data &Session-Timeout == 10
218 condition Session-Timeout == '10'
219 data ERROR offset 19 Value must be an unquoted string
221 # Except for dates, which can be humanly readable!
222 # This one is be an expansion, so it's left as-is.
223 condition Event-Timestamp == "January 1, 2012 %{blah}"
224 data &Event-Timestamp == "January 1, 2012 %{blah}"
226 # This one is NOT an expansion, so it's parsed into normal form
227 condition Event-Timestamp == 'January 1, 2012'
228 #data &Event-Timestamp == 'Jan 1 2012 00:00:00 EST'
230 # literals are parsed when the conditions are parsed
231 condition <integer>X == 1
232 data ERROR offset 9 Failed to parse field
234 condition NAS-Port == X
235 data ERROR offset 12 Failed to parse value for attribute
238 # The RHS is a static string, so this gets mashed to a literal,
239 # and then statically evaluated.
241 condition <ipaddr>127.0.0.1 == "127.0.0.1"
244 condition <ipaddr>127.0.0.1 == "%{sql: 127.0.0.1}"
245 data <ipaddr>127.0.0.1 == "%{sql: 127.0.0.1}"
247 condition <ether> 00:11:22:33:44:55 == "00:11:22:33:44:55"
250 condition <ether> 00:11:22:33:44:55 == "ff:11:22:33:44:55"
253 condition <ether> 00:11:22:33:44:55 == "%{sql:00:11:22:33:44:55}"
254 data <ether>00:11:22:33:44:55 == "%{sql:00:11:22:33:44:55}"
256 condition <ether> 00:XX:22:33:44:55 == 00:11:22:33:44:55
257 data ERROR offset 8 Failed to parse field
260 # Tests for boolean data types.
274 condition true && (User-Name == "bob")
275 data &User-Name == "bob"
277 condition false && (User-Name == "bob")
280 condition false || (User-Name == "bob")
281 data &User-Name == "bob"
283 condition true || (User-Name == "bob")
287 # Both sides static data with a cast: evaluate at parse time.
289 condition <integer>20 < 100
293 # Both sides literal: evaluate at parse time
295 condition ('foo' == 'bar')
298 condition ('foo' < 'bar')
301 condition ('foo' > 'bar')
304 condition ('foo' == 'foo')
308 # Double-quotes strings without expansions are literals
310 condition ("foo" == "%{sql: foo}")
311 data foo == "%{sql: foo}"
313 condition ("foo bar" == "%{sql: foo}")
314 data 'foo bar' == "%{sql: foo}"
316 condition ("foo" == "bar")
319 condition ("foo" == 'bar')
323 # The RHS gets parsed as a VPT_TYPE_DATA, which is
324 # a double-quoted string
326 condition (&User-Name == "bob")
327 data &User-Name == "bob"
329 condition (&User-Name == "%{sql: blah}")
330 data &User-Name == "%{sql: blah}"
332 condition <ipaddr>127.0.0.1 == 2130706433
335 # /32 suffix should be trimmed for this type
336 condition <ipaddr>127.0.0.1/32 == 127.0.0.1
339 condition <ipaddr>127.0.0.1/327 == 127.0.0.1
340 data ERROR offset 8 Failed to parse field
342 condition <ipaddr>127.0.0.1/32 == 127.0.0.1
346 data ERROR offset 1 Conditional check cannot begin with a regular expression
370 # Integers are true, as are non-zero strings
379 data ERROR offset 1 Expected a module return code
382 # Module return codes are OK
399 condition (User-name)
403 # Forbidden data types in cast
405 condition (<vsa>"foo" == &User-Name)
406 data ERROR offset 2 Forbidden data type in cast
409 # Must have attribute references on the LHS of a condition.
411 condition ("foo" == &User-Name)
412 data ERROR offset 1 Cannot use attribute reference on right side of condition
415 # If the LHS is a cast to a type, and the RHS is an attribute
416 # of the same type, then re-write it so that the attribute
417 # is on the LHS of the condition.
419 condition <string>"foo" == &User-Name
420 data &User-Name == "foo"
422 condition <integer>"%{expr: 1 + 1}" < &NAS-Port
423 data &NAS-Port > "%{expr: 1 + 1}"
425 condition &Filter-Id == &Framed-IP-Address
426 data ERROR offset 0 Attribute comparisons must be of the same data type
428 condition <ipaddr>127.0.0.1 == &Filter-Id
429 data ERROR offset 0 Attribute comparisons must be of the same data type
431 condition <ipaddr>&Tmp-Integer64-0 == &Foo-Stuff-Bar
432 data ERROR offset 0 Unknown attribute
435 # Casting attributes of different size
437 condition <ipaddr>&Tmp-Integer64-0 == &Framed-IP-Address
438 data ERROR offset 0 Cannot cast to attribute of incompatible size
440 condition <ipaddr>&PMIP6-Home-IPv4-HoA == &Framed-IP-Address
441 data ERROR offset 0 Cannot cast to attribute of incompatible size
443 # but these are allowed
444 condition <ether>&Tmp-Integer64-0 == "%{module: foo}"
445 data <ether>&Tmp-Integer64-0 == "%{module: foo}"
447 condition <ipaddr>&Filter-Id == &Framed-IP-Address
448 data <ipaddr>&Filter-Id == &Framed-IP-Address
450 condition <ipaddr>&Class == &Framed-IP-Address
451 data <ipaddr>&Class == &Framed-IP-Address
454 # Tags of zero mean restrict to attributes with no tag
456 condition &Tunnel-Password:0 == "Hello"
457 data &Tunnel-Password:0 == "Hello"
459 condition &Tunnel-Password:1 == "Hello"
460 data &Tunnel-Password:1 == "Hello"
463 # zero offset into arrays get parsed and ignored
465 condition &User-Name[0] == "bob"
466 data &User-Name[0] == "bob"
468 condition &User-Name[1] == "bob"
469 data &User-Name[1] == "bob"
471 condition &Tunnel-Password:1[0] == "Hello"
472 data &Tunnel-Password:1[0] == "Hello"
474 condition &Tunnel-Password:1[3] == "Hello"
475 data &Tunnel-Password:1[3] == "Hello"