]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
lua-format: Accept null precision. Limit width and precision to two digits.
authorBruno Haible <bruno@clisp.org>
Sat, 21 Jun 2025 23:37:58 +0000 (01:37 +0200)
committerBruno Haible <bruno@clisp.org>
Sat, 21 Jun 2025 23:37:58 +0000 (01:37 +0200)
Proof that it's valid:
$ lua
print(string.format("%.f", 3.1415926535))

* gettext-tools/src/format-lua.c: Fix comment regarding the width and the
precision.
(format_parse): Recognize at most two digits for the width. Recognize at most
two digits for the precision.
* gettext-tools/tests/format-lua-1: Add test cases with large width, null
precision, and large precision.

gettext-tools/src/format-lua.c
gettext-tools/tests/format-lua-1

index d392216d99500f774eaf0507c38d192bed5e727a..7f06d6711f785c0c176e6e2e7c97809e1f8b8d64 100644 (file)
 /* The Lua format strings are described in the Lua manual,
    which can be found at:
    https://www.lua.org/manual/5.2/manual.html
+   They are implemented in lua-5.2.4/src/lstrlib.c.
 
    A directive
    - starts with '%'
    - is optionally followed by any of the characters '0', '-', ' ', or
      each of which acts as a flag,
    - is optionally followed by a width specification: a nonempty digit
-     sequence,
-   - is optionally followed by '.' and a precision specification: a nonempty
-     digit sequence,
+     sequence with at most 2 digits,
+   - is optionally followed by '.' and a precision specification: an optional
+     nonempty digit sequence with at most 2 digits,
    - is finished by a specifier
        - 's', 'q', that needs a string argument,
        - 'd', 'i', 'o', 'u', 'X', 'x', that need an integer argument,
@@ -99,17 +100,25 @@ format_parse (const char *format, bool translated, char *fdi,
             {
               enum format_arg_type type;
 
-              /* Remove width. */
-              while (c_isdigit (*fatstr))
-                fatstr++;
+              /* Parse width. */
+              if (c_isdigit (*fatstr))
+                {
+                  fatstr++;
+                  if (c_isdigit (*fatstr))
+                    fatstr++;
+                }
 
               if (*fatstr == '.')
                 {
                   fatstr++;
 
-                  /* Remove precision. */
-                  while (c_isdigit (*fatstr))
-                    fatstr++;
+                  /* Parse precision. */
+                  if (c_isdigit (*fatstr))
+                    {
+                      fatstr++;
+                      if (c_isdigit (*fatstr))
+                        fatstr++;
+                    }
                 }
 
               switch (*fatstr)
index 502342c705c8055ae7528b03042725285bda9c38..6da0dd5363a4672479678afd959345ec258a1910 100755 (executable)
@@ -50,6 +50,12 @@ cat <<\EOF > f-lu-1.data
 "abc%T"
 # Invalid: unknown modifier
 "abc%lf"
+# Invalid: width with more than two digits
+"abc%120f"
+# Valid: null precision
+"abc%.f"
+# Invalid: precision with more than two digits
+"abc%.120f"
 # Invalid: extra precision
 "abc%1.1.1f"
 # Invalid: unterminated