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.
This commit is contained in:
Alan Modra
2025-10-09 14:46:39 +10:30
parent 7b67c40b51
commit 937aa6a37d

View File

@@ -292,32 +292,32 @@ 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] == '!')
if (in->ptr[idx] == '!' && idx + 1 < in->len)
idx++;
else if (in->ptr[idx] == '>')
{
if (nest == 0)
{
idx++;
sb_add_char (acc, in->ptr[idx++]);
break;
}
else
{
if (in->ptr[idx] == '>')
nest--;
if (in->ptr[idx] == '<')
}
else if (in->ptr[idx] == '<')
nest++;
sb_add_char (acc, in->ptr[idx++]);
}
}
sb_add_char (acc, in->ptr[idx]);
idx++;
}
}
else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
{
char tchar = in->ptr[idx];
int escaped = 0;
idx++;
while (idx < in->len)
{
if (in->ptr[idx - 1] == '\\')
@@ -325,35 +325,22 @@ 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 ++;
}
else
{
if (in->ptr[idx] == tchar)
else if (!escaped && in->ptr[idx] == tchar)
{
idx++;
if (idx >= in->len || in->ptr[idx] != tchar)
break;
}
sb_add_char (acc, in->ptr[idx]);
idx++;
}
}
}
}
return idx;
}