diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index bbedf6fc..0d6bedef 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -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); diff --git a/src/public/PyList.c b/src/public/PyList.c index a30c412d..88f2c843 100644 --- a/src/public/PyList.c +++ b/src/public/PyList.c @@ -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; diff --git a/tests/660_eval.py b/tests/660_eval.py index 93c3e7a5..f0a88fc0 100644 --- a/tests/660_eval.py +++ b/tests/660_eval.py @@ -75,4 +75,11 @@ assert res == [42, 42] assert x == 33 # test removing trailing newlines -assert eval('[1, 2, 3]\n \n') == [1, 2, 3] \ No newline at end of file +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 \ No newline at end of file