Issue: Segfault on parser name mismatch
Program crashes with segfault when mpca_lang() references a parser name that doesn't exist (in my case, due to case mismatch). A better quality-of-life improvement for the library users would be to handle this crash more gracefully.
Reproduce
mpc_parser_t *MyParser = mpc_new("myparser"); // lowercase
mpca_lang(MPCA_LANG_DEFAULT,
"rule : <MyParser> ;", // uppercase - won't match
MyParser);
// Segfault at mpc.c:4087
Root Cause
Location: mpc.c line ~4105-4120 in mpca_grammar_find_parser()
When searching for a non-existent parser:
- Loop exhausts
va_arg() looking for matching name
va_arg() returns garbage when exhausted
- Code accesses
p->name before NULL check → segfault
while (1) {
p = va_arg(*st->va, mpc_parser_t *);
st->parsers_num++;
st->parsers = realloc(...); // Using p before validation
if (p == NULL || p->name == NULL) { // Too late
return mpc_failf("Unknown Parser '%s'!", x);
}
In the book, it occurred while following this part: https://www.buildyourownlisp.com/chapter6_parsing
At the line:
mpc_parser_t* Lispy = mpc_new("lispy");
I have made a typo there and passed "Lispy" instead of "lispy" which led to the segfault and took me for ride 💃🏻
Enhacement
Check pointer validity immediately after va_arg() and provide a better error message:
while (1) {
p = va_arg(*st->va, mpc_parser_t *);
if (p == NULL || p->name == NULL) {
// Helpful message with available parser names
char msg[1024] = "Available: ";
for (int i = 0; i < st->parsers_num; i++) {
if (st->parsers[i] && st->parsers[i]->name) {
strcat(msg, "'"); strcat(msg, st->parsers[i]->name); strcat(msg, "' ");
}
}
return mpc_failf("Parser '<%s>' not found. %s", x, msg);
}
st->parsers_num++;
st->parsers = realloc(...);
// ... rest
}
Happy to send a PR your way if you think it's worth it! 😄
Environment
- mpc: Latest from GitHub (0.9.0)
- OS: Linux (Arch)
- Compiler: GCC
Issue: Segfault on parser name mismatch
Program crashes with segfault when
mpca_lang()references a parser name that doesn't exist (in my case, due to case mismatch). A better quality-of-life improvement for the library users would be to handle this crash more gracefully.Reproduce
Root Cause
Location:
mpc.cline ~4105-4120 inmpca_grammar_find_parser()When searching for a non-existent parser:
va_arg()looking for matching nameva_arg()returns garbage when exhaustedp->namebefore NULL check → segfaultIn the book, it occurred while following this part: https://www.buildyourownlisp.com/chapter6_parsing
At the line:
I have made a typo there and passed "Lispy" instead of "lispy" which led to the segfault and took me for ride 💃🏻
Enhacement
Check pointer validity immediately after
va_arg()and provide a better error message:Happy to send a PR your way if you think it's worth it! 😄
Environment