[binutils-gdb] gas/macro.c getstring

Alan Modra amodra@sourceware.org
Thu Oct 9 05:34:40 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=937aa6a37d23b6fd24150824a003abaeaef87910

commit 937aa6a37d23b6fd24150824a003abaeaef87910
Author: Alan Modra <amodra@gmail.com>
Date:   Thu Oct 9 14:46:39 2025 +1030

    gas/macro.c getstring
    
    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.

Diff:
---
 gas/macro.c | 61 ++++++++++++++++++++++++-------------------------------------
 1 file changed, 24 insertions(+), 37 deletions(-)

diff --git a/gas/macro.c b/gas/macro.c
index 13202d3f58a..b272800388a 100644
--- a/gas/macro.c
+++ b/gas/macro.c
@@ -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++;
 	    }
 	}
     }


More information about the Binutils-cvs mailing list