[PATCH] libdep plugin: fix bugs in parser and improve escaping
Harmen Stoppels
me@harmenstoppels.nl
Wed Jun 19 10:03:34 GMT 2024
Fix bugs in the __.LIBDEP string to argument list parser in the libdep
plugin.
PR ld/31906
* libdep_plugin.c (st2vec): fix bug where null byte was not copied
on memmove, repeating the last character. Allow literal \ by escaping
it with \\. Allow escaping of quotes inside quoted strings. Fix out
of bounds errors leading to segfaults on input strings like
`-L/'a\'b'`.
Signed-off-by: Harmen Stoppels <me@harmenstoppels.nl>
---
ld/libdep_plugin.c | 63 +++++++++++++++++++---------------------------
1 file changed, 26 insertions(+), 37 deletions(-)
diff --git a/ld/libdep_plugin.c b/ld/libdep_plugin.c
index 414f3cffe12..44fb7cbd588 100644
--- a/ld/libdep_plugin.c
+++ b/ld/libdep_plugin.c
@@ -138,7 +138,7 @@ str2vec (char *in)
{
char **res;
char *s, *first, *end;
- char *sq, *dq;
+ char *quote;
int i;
end = in + strlen (in);
@@ -157,55 +157,44 @@ str2vec (char *in)
return res;
i = 0;
- sq = NULL;
- dq = NULL;
+ quote = NULL;
res[0] = first;
- for (s = first; *s; s++)
+ for (s = first; *s;)
{
if (*s == '\\')
{
- memmove (s, s+1, end-s-1);
- end--;
+ /* trailing backslash is not an escape character */
+ if (s + 1 == end)
+ break;
+ memmove (s, s + 1, end - s);
+ --end;
+ ++s;
}
- if (isspace ((unsigned char) *s))
+ else if (*s == '\'' || *s == '\"')
{
- if (sq || dq)
- continue;
- *s++ = '\0';
- while (isspace ((unsigned char) *s)) s++;
- if (*s)
- res[++i] = s;
- }
- if (*s == '\'' && !dq)
- {
- if (sq)
+ if (!quote)
+ quote = s++;
+ else if (*s == *quote)
{
- memmove (sq, sq+1, s-sq-1);
- memmove (s-2, s+1, end-s-1);
+ memmove (quote, quote + 1, s - quote - 1);
+ memmove (s - 1, s + 1, end - s);
end -= 2;
- s--;
- sq = NULL;
+ --s;
+ quote = NULL;
}
else
- {
- sq = s;
- }
+ ++s;
}
- if (*s == '"' && !sq)
+ else if (!quote && isspace ((unsigned char) *s))
{
- if (dq)
- {
- memmove (dq, dq+1, s-dq-1);
- memmove (s-2, s+1, end-s-1);
- end -= 2;
- s--;
- dq = NULL;
- }
- else
- {
- dq = s;
- }
+ *s++ = '\0';
+ while (isspace ((unsigned char) *s))
+ s++;
+ if (*s)
+ res[++i] = s;
}
+ else
+ ++s;
}
res[++i] = NULL;
return res;
--
2.40.1
More information about the Binutils
mailing list