]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
format-python-brace: Fix error handling.
authorBruno Haible <bruno@clisp.org>
Tue, 28 Jan 2025 10:03:32 +0000 (11:03 +0100)
committerBruno Haible <bruno@clisp.org>
Tue, 28 Jan 2025 10:03:49 +0000 (11:03 +0100)
* gettext-tools/src/format.h (FDI_SET): Improve comment.
* gettext-tools/src/format-python-brace.c (parse_directive): Improve error
messages. Respect FDI_SET constraint.

gettext-tools/src/format-python-brace.c
gettext-tools/src/format.h

index a0306f61f214e69e6ede4fbe70eb0d58e4b168d4..12a7af9927adb749d2734889b6d774b34d0df81c 100644 (file)
@@ -1,5 +1,5 @@
 /* Python brace format strings.
-   Copyright (C) 2004-2024 Free Software Foundation, Inc.
+   Copyright (C) 2004-2025 Free Software Foundation, Inc.
    Written by Daiki Ueno <ueno@gnu.org>, 2013.
 
    This program is free software: you can redistribute it and/or modify
@@ -156,10 +156,21 @@ parse_directive (struct spec *spec,
   if (!parse_named_field (spec, &format, translated, fdi, invalid_reason)
       && !parse_numeric_field (spec, &format, translated, fdi, invalid_reason))
     {
-      *invalid_reason =
-        xasprintf (_("In the directive number %u, '%c' cannot start a field name."),
-                   spec->directives, *format);
-      FDI_SET (format, FMTDIR_ERROR);
+      if (*format == '\0')
+        {
+          *invalid_reason = INVALID_UNTERMINATED_DIRECTIVE ();
+          FDI_SET (format - 1, FMTDIR_ERROR);
+        }
+      else
+        {
+          *invalid_reason =
+            (c_isprint (*format)
+             ? xasprintf (_("In the directive number %u, '%c' cannot start a field name."),
+                          spec->directives, *format)
+             : xasprintf (_("In the directive number %u, a field name starts with a character that is not alphanumerical or underscore."),
+                          spec->directives));
+          FDI_SET (format, FMTDIR_ERROR);
+        }
       return false;
     }
 
@@ -176,10 +187,21 @@ parse_directive (struct spec *spec,
           if (!parse_named_field (spec, &format, translated, fdi,
                                   invalid_reason))
             {
-              *invalid_reason =
-                xasprintf (_("In the directive number %u, '%c' cannot start a getattr argument."),
-                           spec->directives, *format);
-              FDI_SET (format, FMTDIR_ERROR);
+              if (*format == '\0')
+                {
+                  *invalid_reason = INVALID_UNTERMINATED_DIRECTIVE ();
+                  FDI_SET (format - 1, FMTDIR_ERROR);
+                }
+              else
+                {
+                  *invalid_reason =
+                    (c_isprint (*format)
+                     ? xasprintf (_("In the directive number %u, '%c' cannot start a getattr argument."),
+                                  spec->directives, *format)
+                     : xasprintf (_("In the directive number %u, a getattr argument starts with a character that is not alphabetical or underscore."),
+                                  spec->directives));
+                  FDI_SET (format, FMTDIR_ERROR);
+                }
               return false;
             }
         }
@@ -191,10 +213,21 @@ parse_directive (struct spec *spec,
               && !parse_numeric_field (spec, &format, translated, fdi,
                                        invalid_reason))
             {
-              *invalid_reason =
-                xasprintf (_("In the directive number %u, '%c' cannot start a getitem argument."),
-                           spec->directives, *format);
-              FDI_SET (format, FMTDIR_ERROR);
+              if (*format == '\0')
+                {
+                  *invalid_reason = INVALID_UNTERMINATED_DIRECTIVE ();
+                  FDI_SET (format - 1, FMTDIR_ERROR);
+                }
+              else
+                {
+                  *invalid_reason =
+                    (c_isprint (*format)
+                     ? xasprintf (_("In the directive number %u, '%c' cannot start a getitem argument."),
+                                  spec->directives, *format)
+                     : xasprintf (_("In the directive number %u, a getitem argument starts with a character that is not alphanumerical or underscore."),
+                                  spec->directives));
+                  FDI_SET (format, FMTDIR_ERROR);
+                }
               return false;
             }
 
@@ -203,7 +236,7 @@ parse_directive (struct spec *spec,
               *invalid_reason =
                 xasprintf (_("In the directive number %u, there is an unterminated getitem argument."),
                            spec->directives);
-              FDI_SET (format, FMTDIR_ERROR);
+              FDI_SET (format - 1, FMTDIR_ERROR);
               return false;
             }
           format++;
@@ -257,9 +290,9 @@ parse_directive (struct spec *spec,
           if (c1 == '\0')
             {
               *invalid_reason =
-                xasprintf (_("In the directive number %u, there is an unterminated format directive."),
+                xasprintf (_("The directive number %u is unterminated."),
                            spec->directives);
-              FDI_SET (format, FMTDIR_ERROR);
+              FDI_SET (format - 1, FMTDIR_ERROR);
               return false;
             }
 
@@ -310,9 +343,9 @@ parse_directive (struct spec *spec,
   if (*format != '}')
     {
       *invalid_reason =
-        xasprintf (_("In the directive number %u, there is an unterminated format directive."),
+        xasprintf (_("The directive number %u is unterminated."),
                    spec->directives);
-      FDI_SET (format, FMTDIR_ERROR);
+      FDI_SET (format - 1, FMTDIR_ERROR);
       return false;
     }
 
index b769af0ed37f524881e49140d33d0b29180093a1..d5c196b9188eb03b057b77ad49e8038f368c9323 100644 (file)
@@ -1,5 +1,5 @@
 /* Format strings.
-   Copyright (C) 2001-2024 Free Software Foundation, Inc.
+   Copyright (C) 2001-2025 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
    This program is free software: you can redistribute it and/or modify
@@ -47,7 +47,9 @@ enum
 
 /* Macro for use inside a parser:
    Sets an indicator at the position corresponding to PTR.
-   Assumes local variables 'fdi' and 'format_start' are defined.  */
+   Assumes local variables 'fdi' and 'format_start' are defined.
+   *PTR must not be the terminating NUL character; if it might be NUL, you need
+   to pass PTR - 1 instead of PTR.  */
 #define FDI_SET(ptr, flag) \
   if (fdi != NULL) \
     fdi[(ptr) - format_start] |= (flag)/*;*/