]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gas/macro.c getstring
authorAlan Modra <amodra@gmail.com>
Thu, 9 Oct 2025 04:16:39 +0000 (14:46 +1030)
committerAlan Modra <amodra@gmail.com>
Thu, 9 Oct 2025 05:34:06 +0000 (16:04 +1030)
This code:
      if (in->ptr[idx] == '!')
{
  idx++;
  sb_add_char (acc, in->ptr[idx++]);
}
and similar code in the other loop, blindly accessed the next element
of the string buffer without first checking idx against in->len,
leading to uninitialised accesses or buffer overruns.  Fix that, and
tidy the loops so that the function always returns the index one past
the last char consumed.  (It could return idx == in->len + 1).

* macro.c (getstring): Don't access past end of input string
buffer.  Tidy loops.  Don't return an index past in->len.

gas/macro.c

index 13202d3f58a5e21913e47b2a5be521f92a84086d..b272800388a4f96b7692baa449feb778de938275 100644 (file)
@@ -292,24 +292,25 @@ getstring (size_t idx, sb *in, sb *acc)
        {
          int nest = 0;
          idx++;
-         while (idx < in->len
-                && (in->ptr[idx] != '>' || nest))
+         while (idx < in->len)
            {
-             if (in->ptr[idx] == '!')
-               {
-                 idx++;
-                 sb_add_char (acc, in->ptr[idx++]);
-               }
-             else
+             if (in->ptr[idx] == '!' && idx + 1 < in->len)
+               idx++;
+             else if (in->ptr[idx] == '>')
                {
-                 if (in->ptr[idx] == '>')
-                   nest--;
-                 if (in->ptr[idx] == '<')
-                   nest++;
-                 sb_add_char (acc, in->ptr[idx++]);
+                 if (nest == 0)
+                   {
+                     idx++;
+                     break;
+                   }
+                 nest--;
                }
+             else if (in->ptr[idx] == '<')
+               nest++;
+
+             sb_add_char (acc, in->ptr[idx]);
+             idx++;
            }
-         idx++;
        }
       else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
        {
@@ -317,7 +318,6 @@ getstring (size_t idx, sb *in, sb *acc)
          int escaped = 0;
 
          idx++;
-
          while (idx < in->len)
            {
              if (in->ptr[idx - 1] == '\\')
@@ -325,32 +325,19 @@ getstring (size_t idx, sb *in, sb *acc)
              else
                escaped = 0;
 
-             if (flag_macro_alternate && in->ptr[idx] == '!')
+             if (flag_macro_alternate
+                 && in->ptr[idx] == '!' && idx + 1 < in->len)
                {
-                 idx ++;
-
-                 sb_add_char (acc, in->ptr[idx]);
-
-                 idx ++;
-               }
-             else if (escaped && in->ptr[idx] == tchar)
-               {
-                 sb_add_char (acc, tchar);
-                 idx ++;
+                 idx++;
                }
-             else
+             else if (!escaped && in->ptr[idx] == tchar)
                {
-                 if (in->ptr[idx] == tchar)
-                   {
-                     idx ++;
-
-                     if (idx >= in->len || in->ptr[idx] != tchar)
-                       break;
-                   }
-
-                 sb_add_char (acc, in->ptr[idx]);
-                 idx ++;
+                 idx++;
+                 if (idx >= in->len || in->ptr[idx] != tchar)
+                   break;
                }
+             sb_add_char (acc, in->ptr[idx]);
+             idx++;
            }
        }
     }