fix(scanner): serialize buffer size check
During the check that we dont overflow the serialization buffer we erroneously checked with size(uint32_t) == 1 which could cause us to crash with some input strings. Signed-off-by: Michael Hoffmann <mhoffm@posteo.de>
This commit is contained in:
@@ -100,7 +100,7 @@ typedef struct {
|
|||||||
String string_new() { return (String){.cap = 16, .len = 0, .data = calloc(1, sizeof(char) * 17)}; }
|
String string_new() { return (String){.cap = 16, .len = 0, .data = calloc(1, sizeof(char) * 17)}; }
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
enum ContextType type;
|
ContextType type;
|
||||||
|
|
||||||
// valid if type == HEREDOC_TEMPLATE
|
// valid if type == HEREDOC_TEMPLATE
|
||||||
String heredoc_identifier;
|
String heredoc_identifier;
|
||||||
@@ -131,13 +131,14 @@ static unsigned serialize(Scanner *scanner, char *buf) {
|
|||||||
size += sizeof(uint32_t);
|
size += sizeof(uint32_t);
|
||||||
for (int i = 0; i < scanner->context_stack.len; i++) {
|
for (int i = 0; i < scanner->context_stack.len; i++) {
|
||||||
Context *context = &scanner->context_stack.data[i];
|
Context *context = &scanner->context_stack.data[i];
|
||||||
if (size + 2 + context->heredoc_identifier.len >= TREE_SITTER_SERIALIZATION_BUFFER_SIZE) {
|
if (size + sizeof(ContextType) + sizeof(uint32_t) + context->heredoc_identifier.len >= TREE_SITTER_SERIALIZATION_BUFFER_SIZE) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (context->heredoc_identifier.len > CHAR_MAX) {
|
if (context->heredoc_identifier.len > CHAR_MAX) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
buf[size++] = context->type;
|
memcpy(&buf[size], &(context->type), sizeof(ContextType));
|
||||||
|
size += sizeof(ContextType);
|
||||||
memcpy(&buf[size], &(context->heredoc_identifier.len), sizeof(uint32_t));
|
memcpy(&buf[size], &(context->heredoc_identifier.len), sizeof(uint32_t));
|
||||||
size += sizeof(uint32_t);
|
size += sizeof(uint32_t);
|
||||||
memcpy(&buf[size], context->heredoc_identifier.data, context->heredoc_identifier.len);
|
memcpy(&buf[size], context->heredoc_identifier.data, context->heredoc_identifier.len);
|
||||||
@@ -160,7 +161,9 @@ static void deserialize(Scanner *scanner, const char *buffer, unsigned length) {
|
|||||||
for (uint32_t j = 0; j < context_stack_size; j++) {
|
for (uint32_t j = 0; j < context_stack_size; j++) {
|
||||||
Context ctx;
|
Context ctx;
|
||||||
ctx.heredoc_identifier = string_new();
|
ctx.heredoc_identifier = string_new();
|
||||||
ctx.type = (enum ContextType)buffer[size++];
|
|
||||||
|
memcpy(&(ctx.type), &buffer[size], sizeof(ContextType));
|
||||||
|
size += sizeof(ContextType);
|
||||||
|
|
||||||
uint32_t heredoc_identifier_size;
|
uint32_t heredoc_identifier_size;
|
||||||
memcpy(&heredoc_identifier_size, &buffer[size], sizeof(uint32_t));
|
memcpy(&heredoc_identifier_size, &buffer[size], sizeof(uint32_t));
|
||||||
|
|||||||
@@ -84,12 +84,12 @@ enum TokenType {
|
|||||||
HEREDOC_IDENTIFIER,
|
HEREDOC_IDENTIFIER,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ContextType {
|
typedef enum ContextType {
|
||||||
TEMPLATE_INTERPOLATION,
|
TEMPLATE_INTERPOLATION,
|
||||||
TEMPLATE_DIRECTIVE,
|
TEMPLATE_DIRECTIVE,
|
||||||
QUOTED_TEMPLATE,
|
QUOTED_TEMPLATE,
|
||||||
HEREDOC_TEMPLATE,
|
HEREDOC_TEMPLATE,
|
||||||
};
|
} ContextType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t cap;
|
uint32_t cap;
|
||||||
@@ -100,7 +100,7 @@ typedef struct {
|
|||||||
String string_new() { return (String){.cap = 16, .len = 0, .data = calloc(1, sizeof(char) * 17)}; }
|
String string_new() { return (String){.cap = 16, .len = 0, .data = calloc(1, sizeof(char) * 17)}; }
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
enum ContextType type;
|
ContextType type;
|
||||||
|
|
||||||
// valid if type == HEREDOC_TEMPLATE
|
// valid if type == HEREDOC_TEMPLATE
|
||||||
String heredoc_identifier;
|
String heredoc_identifier;
|
||||||
@@ -131,13 +131,14 @@ static unsigned serialize(Scanner *scanner, char *buf) {
|
|||||||
size += sizeof(uint32_t);
|
size += sizeof(uint32_t);
|
||||||
for (int i = 0; i < scanner->context_stack.len; i++) {
|
for (int i = 0; i < scanner->context_stack.len; i++) {
|
||||||
Context *context = &scanner->context_stack.data[i];
|
Context *context = &scanner->context_stack.data[i];
|
||||||
if (size + 2 + context->heredoc_identifier.len >= TREE_SITTER_SERIALIZATION_BUFFER_SIZE) {
|
if (size + sizeof(ContextType) + sizeof(uint32_t) + context->heredoc_identifier.len >= TREE_SITTER_SERIALIZATION_BUFFER_SIZE) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (context->heredoc_identifier.len > CHAR_MAX) {
|
if (context->heredoc_identifier.len > CHAR_MAX) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
buf[size++] = context->type;
|
memcpy(&buf[size], &(context->type), sizeof(ContextType));
|
||||||
|
size += sizeof(ContextType);
|
||||||
memcpy(&buf[size], &(context->heredoc_identifier.len), sizeof(uint32_t));
|
memcpy(&buf[size], &(context->heredoc_identifier.len), sizeof(uint32_t));
|
||||||
size += sizeof(uint32_t);
|
size += sizeof(uint32_t);
|
||||||
memcpy(&buf[size], context->heredoc_identifier.data, context->heredoc_identifier.len);
|
memcpy(&buf[size], context->heredoc_identifier.data, context->heredoc_identifier.len);
|
||||||
@@ -160,7 +161,9 @@ static void deserialize(Scanner *scanner, const char *buffer, unsigned length) {
|
|||||||
for (uint32_t j = 0; j < context_stack_size; j++) {
|
for (uint32_t j = 0; j < context_stack_size; j++) {
|
||||||
Context ctx;
|
Context ctx;
|
||||||
ctx.heredoc_identifier = string_new();
|
ctx.heredoc_identifier = string_new();
|
||||||
ctx.type = (enum ContextType)buffer[size++];
|
|
||||||
|
memcpy(&(ctx.type), &buffer[size], sizeof(ContextType));
|
||||||
|
size += sizeof(ContextType);
|
||||||
|
|
||||||
uint32_t heredoc_identifier_size;
|
uint32_t heredoc_identifier_size;
|
||||||
memcpy(&heredoc_identifier_size, &buffer[size], sizeof(uint32_t));
|
memcpy(&heredoc_identifier_size, &buffer[size], sizeof(uint32_t));
|
||||||
|
|||||||
Reference in New Issue
Block a user