Closed dolik-rce closed 3 years ago
How about this change ? https://github.com/universal-ctags/packcc/commit/37c1b8863550001441e0e7eb40c69c2ea6aae0fe
Interestingly, this fails:
rule <- ("A;" / _)+
_ <- [ \n]*
while this correctly ends with syntax error:
rule <- ("A;" / [ \n]*)+
Semantically, both should be the same, so this is definitely a bug.
@arithy: Is it intended behavior that some cached answers can be kept in pcc_lr_table
after pcc_commit_buffer
is called?
Assuming this grammar:
rule <- ("A;" / _)+
_ <- [ \n]*
I believe this is what happens:
len == 4
)rule
matching is ended.pcc_commit_buffer
is called and the buffer is shofted by 3 bytes (because it matched "A;\n"
)pcc_commit_buffer
lr_table is shifted by ctx->pos
bytes, which is three. But since it was originally 4 entries long, so one remains.ppc_parse
again, starting on the begging of second line."A\n"
).So, it seems like either
pcc_commit_buffer
It seems to me, that the last option makes most sense, since it is possible that during backtracking some matches might have been done in the further parts of buffer and it would be wasteful to just delete them. Is my reasoning correct?
I did modify the PackCC to test this hypothesis, by making it emit this code for the shifting:
static void pcc_lr_table__shift(pcc_auxil_t auxil, pcc_lr_table_t *table, size_t count) {
size_t i;
if (count > table->len) count = table->len;
for (i = 0; i < count; i++) pcc_lr_table_entry__destroy(auxil, table->buf[i]);
memmove(table->buf, table->buf + count, sizeof(pcc_lr_table_entry_t *) * (table->len - count));
table->len -= count;
for (i = 0; i < table->len; i++) {
if (table->buf[i]) {
table->buf[i]->memos.buf->answer->pos -= count;
}
}
}
It seems to fix this issue and works for all the tests but one. It seems that there was similar, but more subtle error in character_classed_1.d, that caused it to return incorrect value I missed when writing the test. But it did not crash, which is actually more misleading :slightly_smiling_face:
Your understanding is absolutely right.
I missed the update of the position value in pcc_lr_answer_t::pos
.
Thanks a lot for pointing it out.
Grammar:
Input:
Expected output:
Syntax error should be reported.
Debugger session:
Somehow,
ctx->pos > ctx->buffer.len
, which leads to segfault, becausesize_t
is unsigned, so this overflows and it effectively tries to copy 18446744073709551615 bytes of memory, which is waaaay outside of the allocated memory.