fix lexer EOF OOB read and list.sort comparator signature

This commit is contained in:
Steve 2026-06-17 05:36:09 -04:00
parent db8d52cab0
commit c18322444e
3 changed files with 25 additions and 6 deletions

View File

@ -37,16 +37,24 @@ static void Lexer__dtor(Lexer* self) {
c11_vector__dtor(&self->indents);
}
static const char* lexer_source_end(Lexer* self) {
return self->src->source->data + self->src->source->size;
}
static char eatchar(Lexer* self) {
const char* end = lexer_source_end(self);
if(self->curr_char > end) return '\0';
char c = *self->curr_char;
assert(c != '\n'); // eatchar() cannot consume a newline
self->curr_char++;
self->curr_char = (self->curr_char < end) ? self->curr_char + 1 : end + 1;
return c;
}
static char eatchar_include_newline(Lexer* self) {
const char* end = lexer_source_end(self);
if(self->curr_char > end) return '\0';
char c = *self->curr_char;
self->curr_char++;
self->curr_char = (self->curr_char < end) ? self->curr_char + 1 : end + 1;
if(c == '\n') {
self->current_line++;
c11_vector__push(const char*, &self->src->line_starts, self->curr_char);
@ -189,7 +197,8 @@ static Error* LexerError(Lexer* self, const char* fmt, ...) {
err->src = self->src;
PK_INCREF(self->src);
err->lineno = self->current_line;
if(*self->curr_char == '\n') { err->lineno--; }
const char* end = lexer_source_end(self);
if(self->curr_char <= end && *self->curr_char == '\n') { err->lineno--; }
va_list args;
va_start(args, fmt);
vsnprintf(err->msg, sizeof(err->msg), fmt, args);

View File

@ -384,7 +384,10 @@ static bool list_insert(int argc, py_Ref argv) {
return true;
}
static int lt_with_key(py_TValue* a, py_TValue* b, py_TValue* key) {
static int lt_with_key(const void* a_, const void* b_, void* extra) {
py_TValue* a = (py_TValue*)a_;
py_TValue* b = (py_TValue*)b_;
py_TValue* key = (py_TValue*)extra;
if(!key) return py_less(a, b);
VM* vm = pk_current_vm;
// project a
@ -416,7 +419,7 @@ static bool list_sort(int argc, py_Ref argv) {
bool ok = c11__stable_sort(self->data,
self->length,
sizeof(py_TValue),
(int (*)(const void*, const void*, void*))lt_with_key,
lt_with_key,
key);
if(!ok) return false;

View File

@ -76,3 +76,10 @@ assert x == 33
# test removing trailing newlines
assert eval('[1, 2, 3]\n \n') == [1, 2, 3]
# lexer doesn't read past NUL on error at end of input
try:
eval('"\\x4')
exit(1)
except SyntaxError:
pass