Merge pull request #3 from tree-sitter/fuzzer-fixes
Fix bugs found during fuzzing
This commit is contained in:
commit
e7b12d1444
15
.travis.yml
15
.travis.yml
|
@ -2,21 +2,10 @@ language: node_js
|
||||||
|
|
||||||
sudo: false
|
sudo: false
|
||||||
|
|
||||||
node_js:
|
node_js: node
|
||||||
- "node"
|
|
||||||
|
|
||||||
compiler: clang-3.6
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- CXX=clang-3.6
|
- CXX=clang
|
||||||
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources:
|
|
||||||
- llvm-toolchain-precise-3.6
|
|
||||||
- ubuntu-toolchain-r-test
|
|
||||||
packages:
|
|
||||||
- clang-3.6
|
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
|
|
|
@ -26,14 +26,18 @@ struct Scanner {
|
||||||
Scanner() {}
|
Scanner() {}
|
||||||
|
|
||||||
unsigned serialize(char *buffer) {
|
unsigned serialize(char *buffer) {
|
||||||
unsigned i = 0;
|
uint16_t tag_count = tags.size() > UINT16_MAX ? UINT16_MAX : tags.size();
|
||||||
unsigned n = tags.size();
|
uint16_t serialized_tag_count = 0;
|
||||||
std::memcpy(buffer, &n, sizeof(n));
|
|
||||||
i += sizeof(n);
|
unsigned i = sizeof(tag_count);
|
||||||
for (unsigned j = 0; j < n; j++) {
|
std::memcpy(&buffer[i], &tag_count, sizeof(tag_count));
|
||||||
Tag &tag = tags[j];
|
i += sizeof(tag_count);
|
||||||
|
|
||||||
|
for (; serialized_tag_count < tag_count; serialized_tag_count++) {
|
||||||
|
Tag &tag = tags[serialized_tag_count];
|
||||||
if (tag.type == CUSTOM) {
|
if (tag.type == CUSTOM) {
|
||||||
unsigned name_length = tag.custom_tag_name.size();
|
unsigned name_length = tag.custom_tag_name.size();
|
||||||
|
if (name_length > UINT8_MAX) name_length = UINT8_MAX;
|
||||||
if (i + 2 + name_length >= TREE_SITTER_SERIALIZATION_BUFFER_SIZE) break;
|
if (i + 2 + name_length >= TREE_SITTER_SERIALIZATION_BUFFER_SIZE) break;
|
||||||
buffer[i++] = static_cast<char>(tag.type);
|
buffer[i++] = static_cast<char>(tag.type);
|
||||||
buffer[i++] = name_length;
|
buffer[i++] = name_length;
|
||||||
|
@ -44,6 +48,8 @@ struct Scanner {
|
||||||
buffer[i++] = static_cast<char>(tag.type);
|
buffer[i++] = static_cast<char>(tag.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::memcpy(&buffer[0], &serialized_tag_count, sizeof(serialized_tag_count));
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,15 +57,20 @@ struct Scanner {
|
||||||
tags.clear();
|
tags.clear();
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
unsigned n;
|
uint16_t tag_count, serialized_tag_count;
|
||||||
std::memcpy(&n, buffer, sizeof(n));
|
|
||||||
i += sizeof(n);
|
std::memcpy(&serialized_tag_count, &buffer[i], sizeof(serialized_tag_count));
|
||||||
tags.resize(n);
|
i += sizeof(serialized_tag_count);
|
||||||
for (unsigned j = 0; j < n; j++) {
|
|
||||||
|
std::memcpy(&tag_count, &buffer[i], sizeof(tag_count));
|
||||||
|
i += sizeof(tag_count);
|
||||||
|
|
||||||
|
tags.resize(tag_count);
|
||||||
|
for (unsigned j = 0; j < serialized_tag_count; j++) {
|
||||||
Tag &tag = tags[j];
|
Tag &tag = tags[j];
|
||||||
tag.type = static_cast<TagType>(buffer[i++]);
|
tag.type = static_cast<TagType>(buffer[i++]);
|
||||||
if (tag.type == CUSTOM) {
|
if (tag.type == CUSTOM) {
|
||||||
unsigned name_length = buffer[i++];
|
uint16_t name_length = (uint16_t)buffer[i++];
|
||||||
tag.custom_tag_name.assign(&buffer[i], &buffer[i + name_length]);
|
tag.custom_tag_name.assign(&buffer[i], &buffer[i + name_length]);
|
||||||
i += name_length;
|
i += name_length;
|
||||||
}
|
}
|
||||||
|
@ -202,8 +213,10 @@ struct Scanner {
|
||||||
lexer->advance(lexer, false);
|
lexer->advance(lexer, false);
|
||||||
if (lexer->lookahead == '>') {
|
if (lexer->lookahead == '>') {
|
||||||
lexer->advance(lexer, false);
|
lexer->advance(lexer, false);
|
||||||
tags.pop_back();
|
if (!tags.empty()) {
|
||||||
lexer->result_symbol = SELF_CLOSING_TAG_DELIMITER;
|
tags.pop_back();
|
||||||
|
lexer->result_symbol = SELF_CLOSING_TAG_DELIMITER;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -310,7 +310,13 @@ struct Tag {
|
||||||
TagType type;
|
TagType type;
|
||||||
string custom_tag_name;
|
string custom_tag_name;
|
||||||
|
|
||||||
Tag() : type(DIV) {}
|
// This default constructor is used in the case where there is not enough space
|
||||||
|
// in the serialization buffer to store all of the tags. In that case, tags
|
||||||
|
// that cannot be serialized will be treated as having an unknown type. These
|
||||||
|
// tags will be closed via implicit end tags regardless of the next closing
|
||||||
|
// tag is encountered.
|
||||||
|
Tag() : type(END_OF_VOID_TAGS) {}
|
||||||
|
|
||||||
Tag(TagType type, const string &name) : type(type), custom_tag_name(name) {}
|
Tag(TagType type, const string &name) : type(type), custom_tag_name(name) {}
|
||||||
|
|
||||||
bool operator==(const Tag &other) const {
|
bool operator==(const Tag &other) const {
|
||||||
|
|
Loading…
Reference in New Issue