commit bc91254d2236b9f66b98e260b7a4a92cb0f8bd4b
Author: Alexander Zubkov <green@qrator.net>
Date:   Mon Jun 12 11:56:09 2023 +0200

    Conf: strict IPv6 regexp to allow shorter hexadecimal strings
    
    Make IPv6 regexp more strict so that it does not match extra similar strings.
    It makes possible to shorten the length of hexadecimal strings so that they
    do not collide with IPv6 notation.
    
    Because IPv6 regexp is strict and it should not match other tokens, it can be
    placed before the hexadecimal string regexp to have precedence over it.
    
    Add additional regexp to catch possible typos in IPv6 addresses and hexadecial
    strings to show the error message about it.

diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index 9555949d..a7d18e71 100644
--- a/conf/cf-lex.l
+++ b/conf/cf-lex.l
@@ -255,7 +255,28 @@ WHITE [ \t]
   return IP4;
 }
 
-{XIGIT}{2}((:{XIGIT}{2}){15,}|({XIGIT}{2}){15,}) {
+({XIGIT}{1,4}:){7}{XIGIT}{1,4} |
+::(({XIGIT}{1,4}:){0,6}{XIGIT}{1,4})? |
+{XIGIT}{1,4}::(({XIGIT}{1,4}:){0,5}{XIGIT}{1,4})? |
+({XIGIT}{1,4}:){1}{XIGIT}{1,4}::(({XIGIT}{1,4}:){0,4}{XIGIT}{1,4})? |
+({XIGIT}{1,4}:){2}{XIGIT}{1,4}::(({XIGIT}{1,4}:){0,3}{XIGIT}{1,4})? |
+({XIGIT}{1,4}:){3}{XIGIT}{1,4}::(({XIGIT}{1,4}:){0,2}{XIGIT}{1,4})? |
+({XIGIT}{1,4}:){4}{XIGIT}{1,4}::(({XIGIT}{1,4}:){0,1}{XIGIT}{1,4})? |
+({XIGIT}{1,4}:){5}{XIGIT}{1,4}::({XIGIT}{1,4})? |
+({XIGIT}{1,4}:){6}{XIGIT}{1,4}:: |
+({XIGIT}{1,4}:){6}({DIGIT}+\.){3}{DIGIT}+ |
+::({XIGIT}{1,4}:){0,5}({DIGIT}+\.){3}{DIGIT}+ |
+{XIGIT}{1,4}::({XIGIT}{1,4}:){0,4}({DIGIT}+\.){3}{DIGIT}+ |
+({XIGIT}{1,4}:){1}{XIGIT}{1,4}::({XIGIT}{1,4}:){0,3}({DIGIT}+\.){3}{DIGIT}+ |
+({XIGIT}{1,4}:){2}{XIGIT}{1,4}::({XIGIT}{1,4}:){0,2}({DIGIT}+\.){3}{DIGIT}+ |
+({XIGIT}{1,4}:){3}{XIGIT}{1,4}::({XIGIT}{1,4}:){0,1}({DIGIT}+\.){3}{DIGIT}+ |
+({XIGIT}{1,4}:){4}{XIGIT}{1,4}::({DIGIT}+\.){3}{DIGIT}+ {
+  if (!ip6_pton(yytext, &cf_lval.ip6))
+    cf_error("Invalid IPv6 address %s", yytext);
+  return IP6;
+}
+
+({XIGIT}{2}){16,}|({XIGIT}{2}(:{XIGIT}{2}){5,}) {
   char *s = yytext;
   size_t len = 0, i;
   struct bytestring *bytes;
@@ -286,12 +307,6 @@ WHITE [ \t]
   return BYTESTRING;
 }
 
-({XIGIT}*::|({XIGIT}*:){3,})({XIGIT}*|{DIGIT}+\.{DIGIT}+\.{DIGIT}+\.{DIGIT}+) {
-  if (!ip6_pton(yytext, &cf_lval.ip6))
-    cf_error("Invalid IPv6 address %s", yytext);
-  return IP6;
-}
-
 0x{XIGIT}+ {
   char *e;
   unsigned long int l;
@@ -314,6 +329,10 @@ WHITE [ \t]
   return NUM;
 }
 
+({XIGIT}|:)*:({XIGIT}|:)*:({XIGIT}|:)* {
+  cf_error("Malformed IPv6 address or hexadecimal string: %s", yytext);
+}
+
 else: {
   /* Hack to distinguish if..else from else: in case */
   return ELSECOL;
