From: Alan T. DeKok Date: Sat, 15 Jan 2022 12:46:45 +0000 (-0500) Subject: prefer "allowed" to "terminals" X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0dbb6d95da7d362f76f3e788d5c2f9bf61ca499c;p=thirdparty%2Ffreeradius-server.git prefer "allowed" to "terminals" If we want to parse &Service-Type = Framed-User then we don't want to parse it as (&Service - Type) = (Framed - User) or (&Service-Type = Framed) - User etc. The tmpl_afrom_attr_substr() calls fr_dict_attr_by_name_substr() which calls fr_dict_attr_by_name_substr(), which then ignores terminals. So this change makes parsing the RHS enum name behave the same as parsing the LHS attribute name. --- diff --git a/src/lib/util/sbuff.c b/src/lib/util/sbuff.c index b6586bf98b..22bb7cca77 100644 --- a/src/lib/util/sbuff.c +++ b/src/lib/util/sbuff.c @@ -1691,8 +1691,45 @@ size_t fr_sbuff_adv_past_allowed(fr_sbuff_t *sbuff, size_t len, bool end = CONSTRAINED_END(sbuff, len, total); p = sbuff->p; - while ((p < end) && allowed[(uint8_t)*p] && - ((needle_len == 0) || !fr_sbuff_terminal_search(sbuff, p, idx, tt, needle_len))) p++; + while ((p < end) && allowed[(uint8_t)*p]) { + if (needle_len == 0) { + p++; + continue; + } + + /* + * If this character is allowed, BUT is also listed as a one-character terminal, + * then we still allow it. This decision implements "greedy" parsing. + */ + if (fr_sbuff_terminal_search(sbuff, p, idx, tt, 1)) { + p++; + continue; + } + + /* + * Otherwise if the next *set* of characters) is not in the terminals, then + * allow the current character. + */ + if (!fr_sbuff_terminal_search(sbuff, p, idx, tt, needle_len)) { + p++; + continue; + } + + /* + * The character is allowed, and is NOT listed as a terminal character by itself. + * However, it is part of a multi-character terminal sequence. We therefore + * stop. + * + * This decision allows us to parse things like "Framed-User", where we might + * normally stop at the "-". However, we will still stop at "Framed-=User", as + * "-=" may be a terminal sequence. + * + * There is no perfect solution here, other than to fix the input grammer so that + * it has no ambiguity. Since we can't do that, we choose to err on the side of + * allowing the existing grammar, where it makes sense + */ + break; + } total += fr_sbuff_set(sbuff, p); if (p != end) break; /* stopped early, break */