[nasm:nasm-2.15.xx] preproc: BR 2292698: fix handling of whitespace around %+
nasm-bot for H. Peter Anvin (Intel)
hpa at zytor.com
Wed Jul 15 16:21:06 PDT 2020
Commit-ID: 4c0bd9e73696c2643e7823489e56ad3b70290a4a
Gitweb: http://repo.or.cz/w/nasm.git?a=commitdiff;h=4c0bd9e73696c2643e7823489e56ad3b70290a4a
Author: H. Peter Anvin (Intel) <hpa at zytor.com>
AuthorDate: Wed, 15 Jul 2020 16:16:57 -0700
Committer: H. Peter Anvin (Intel) <hpa at zytor.com>
CommitDate: Wed, 15 Jul 2020 16:16:57 -0700
preproc: BR 2292698: fix handling of whitespace around %+
The previous code to fix whitespace around and multiple %+ symbols in
a row (checkin 122c5fb75986adc37dfb147cc2a613e3ebc66e80) had some
seriously broken pointer handling when zapping tokens. This could
cause paste_tokens() to go into an infinite loop because it would
attach %+ to another token and then immediately break them apart
again, over and over.
Reported-by: <alexfru at gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa at zytor.com>
---
asm/preproc.c | 53 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 30 insertions(+), 23 deletions(-)
diff --git a/asm/preproc.c b/asm/preproc.c
index 8415d572..2f8fb3cd 100644
--- a/asm/preproc.c
+++ b/asm/preproc.c
@@ -4728,7 +4728,7 @@ static inline bool pp_concat_match(const Token *t, unsigned int mask)
static bool paste_tokens(Token **head, const struct tokseq_match *m,
size_t mnum, bool handle_explicit)
{
- Token *tok, *t, *next, **prev_next, **prev_nonspace;
+ Token *tok, *t, *next, **prev_next, **prev_nonspace, **nextp;
bool pasted = false;
char *buf, *p;
size_t len, i;
@@ -4765,30 +4765,28 @@ static bool paste_tokens(Token **head, const struct tokseq_match *m,
if (!handle_explicit)
break;
+ did_paste = true;
+
/* Left pasting token is start of line, just drop %+ */
if (!prev_nonspace) {
- tok = delete_Token(tok);
- break;
+ prev_next = nextp = head;
+ t = NULL;
+ } else {
+ prev_next = prev_nonspace;
+ t = *prev_next;
+ nextp = &t->next;
}
- did_paste = true;
-
- prev_next = prev_nonspace;
- t = *prev_nonspace;
-
- /* Delete leading whitespace */
- next = zap_white(t->next);
-
/*
- * Delete the %+ token itself, followed by any whitespace.
+ * Delete the %+ token itself plus any whitespace.
* In a sequence of %+ ... %+ ... %+ pasting sequences where
* some expansions in the middle have ended up empty,
* we can end up having multiple %+ tokens in a row;
* just drop whem in that case.
*/
- while (next) {
+ while ((next = *nextp)) {
if (next->type == TOK_PASTE || next->type == TOK_WHITESPACE)
- next = delete_Token(next);
+ *nextp = delete_Token(next);
else
break;
}
@@ -4796,11 +4794,16 @@ static bool paste_tokens(Token **head, const struct tokseq_match *m,
/*
* Nothing after? Just leave the existing token.
*/
- if (!next) {
- t->next = tok = NULL; /* End of line */
+ if (!next)
+ break;
+
+ if (!t) {
+ /* Nothing to actually paste, just zapping the paste */
+ *prev_next = tok = next;
break;
}
+ /* An actual paste */
p = buf = nasm_malloc(t->len + next->len + 1);
p = mempcpy(p, tok_text(t), t->len);
p = mempcpy(p, tok_text(next), next->len);
@@ -4814,10 +4817,10 @@ static bool paste_tokens(Token **head, const struct tokseq_match *m,
* No output at all? Replace with a single whitespace.
* This should never happen.
*/
- t = new_White(NULL);
+ tok = t = new_White(NULL);
+ } else {
+ *prev_nonspace = tok = t;
}
-
- *prev_nonspace = tok = t;
while (t->next)
t = t->next; /* Find the last token produced */
@@ -4825,7 +4828,7 @@ static bool paste_tokens(Token **head, const struct tokseq_match *m,
t->next = delete_Token(next);
/* We want to restart from the head of the pasted token */
- next = tok;
+ *prev_next = next = tok;
break;
default:
@@ -4861,10 +4864,14 @@ static bool paste_tokens(Token **head, const struct tokseq_match *m,
* Connect pasted into original stream,
* ie A -> new-tokens -> B
*/
- while (t->next)
- t = t->next;
+ while ((tok = t->next)) {
+ if (tok->type != TOK_WHITESPACE && tok->type != TOK_PASTE)
+ prev_nonspace = &t->next;
+ t = tok;
+ }
+
t->next = next;
- prev_next = prev_nonspace = &t->next;
+ prev_next = &t->next;
did_paste = true;
break;
}
More information about the Nasm-commits
mailing list