]> git.ipfire.org Git - thirdparty/make.git/commitdiff
[SV 64402] Correct locating "," in ifeq/ifneq conditionals
authorPaul Smith <psmith@gnu.org>
Sat, 6 Jan 2024 22:42:40 +0000 (17:42 -0500)
committerPaul Smith <psmith@gnu.org>
Sat, 6 Jan 2024 22:42:40 +0000 (17:42 -0500)
Ensure that we correctly skip the entirety of a macro or function
reference when searching for the "," separator in an ifeq/ifneq
conditional, including using "$," and also "${foo,bar}".  Note that
this change means that parenthesis OTHER than those used for variable
expansion are not considered special, any longer.

* NEWS: Announce the change.
* src/read.c (conditional_line): Skip variable references when looking
  for "," and ensure that we match closing parens/braces properly.
* tests/scripts/features/conditionals: Add tests for this behavior.

NEWS
src/read.c
tests/scripts/features/conditionals

diff --git a/NEWS b/NEWS
index ea81d397daa5c4707f491c6fd50a5f7f8aa1caaa..4844cf63ed2333fe6f0bb2ec1b9c8dac26ce5d6b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -9,11 +9,6 @@ which is contained in this distribution as the file doc/make.texi.
 See the README file and the GNU Make manual for instructions for
 reporting bugs.
 
-* 'make --print-data-base' (or 'make -p') now outputs time of day
-  using the same form as for file timestamps, e.g., "2023-05-10
-  10:43:57.570558743".  Previously it used the form "Wed May 10
-  10:43:57 2023", which has less detail and is harder to compare.
-
 \f
 Version 4.4.90 (26 Feb 2023)
 
@@ -34,6 +29,14 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=111&se
   your initialization function can check the provided ABI version to verify
   it's being loaded correctly.
 
+* WARNING: Backward-incompatibility!
+  Parsing of the first argument in ifeq/ifneq with () has been cleaned up.
+  When locating the separating "," any variable reference (single char as well
+  as using $() or ${}) is skipped.  However parentheses that are not part of
+  or contained in variable references will not be counted.  This means that
+  things like "ifeq ((foo,bar),)" are now syntax errors.  Use a variable to
+  hide the comma if needed: "COMMA = ," / "ifeq ((foo$(COMMA)bar),)".
+
 * New feature: Unload function for loaded objects
   When a loaded object needs to be unloaded by GNU Make, it will invoke an
   unload function (if one is defined) beforehand that allows the object to
@@ -53,6 +56,11 @@ https://sv.gnu.org/bugs/index.php?group=make&report_id=111&fix_release_id=111&se
   invoked recursively, warnings can be controlled only for the current
   instance of make using the .WARNINGS variable.
 
+* 'make --print-data-base' (or 'make -p') now outputs time of day
+  using the same form as for file timestamps, e.g., "2023-05-10
+  10:43:57.570558743".  Previously it used the form "Wed May 10
+  10:43:57 2023", which has less detail and is harder to compare.
+
 * Conditional statements starting with the recipe prefix were sometimes
   interpreted in previous versions.  As per the documentation, lines starting
   with the recipe prefix are now never considered conditional statements.
index 6748486e76069af71c8759868389f35573a58395..a5754a95878205a87cc8d9e199b095c02d1dfb05 100644 (file)
@@ -1672,13 +1672,27 @@ conditional_line (char *line, size_t len, const floc *flocp)
       if (termin == ',')
         {
           int count = 0;
-          for (; *line != '\0'; ++line)
-            if (*line == '(')
-              ++count;
-            else if (*line == ')')
-              --count;
-            else if (*line == ',' && count <= 0)
-              break;
+          char *delim = xmalloc (strlen (line));
+          while (*line != '\0')
+            {
+              if (*line == '$')
+                {
+                  ++line;
+                  if (*line == '(')
+                    delim[count++] = ')';
+                  else if (*line == '{')
+                    delim[count++] = '}';
+                }
+              else if (count == 0)
+                {
+                  if (*line == ',')
+                    break;
+                }
+              else if (*line == delim[count-1])
+                --count;
+              ++line;
+            }
+          free (delim);
         }
       else
         while (*line != '\0' && *line != termin)
index c1eee95c45290e9d78a22f4c176f19c9c030986b..c8f142152598fe7d69e6716a60e7120d3431d382 100644 (file)
@@ -215,6 +215,44 @@ endif
 !,
     '', "#MAKE#: 'all' is up to date.");
 
+# SV 64402: parse braces in ifeq/ifneq properly
+
+run_make_test(q!
+ifeq ($(and a,b),)
+endif
+ifeq (${and a,b},)
+endif
+ifeq (${and $(x),${or $(z),${q}}},)
+endif
+ifeq (${and ),(},)
+endif
+ifeq ($(and },{),)
+endif
+# We can hide the comma in a variable
+C = ,
+ifeq ((and a$Cb),)
+endif
+all:;
+!,
+    '', "#MAKE#: 'all' is up to date.");
+
+# The "," in "$," is a variable name not a comma
+run_make_test(q!
+ifeq ($,,)
+$(info ok)
+endif
+all:;
+!,
+    '', "ok\n#MAKE#: 'all' is up to date.");
+
+# Without variable references we don't do anything special with parens
+run_make_test(q!
+ifeq ((and a,b),)
+endif
+all:;
+!,
+    '', "#MAKEFILE#:2: extraneous text after 'ifeq' directive\n#MAKE#: 'all' is up to date.");
+
 # This tells the test driver that the perl test script executed properly.
 1;