fix SkSL lexer's handling of invalid characters

Bug: skia:8831
Change-Id: I3198c86af971c3340ccf7cc1d7dede6dd48939fb
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/204980
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Kevin Lubick <kjlubick@google.com>
Auto-Submit: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
This commit is contained in:
Ethan Nicholas 2019-03-29 14:16:50 -04:00 committed by Skia Commit-Bot
parent 5f8a62bd18
commit 10be9d5f45
3 changed files with 14 additions and 10 deletions

View File

@ -11,6 +11,7 @@
namespace SkSL {
static const uint8_t INVALID_CHAR = 18;
static int8_t mappings[127] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 4, 3, 5, 6, 7, 8, 3, 9, 10, 11, 12,
@ -1012,11 +1013,11 @@ Token Lexer::next() {
}
int16_t state = 1;
while (fOffset < fLength) {
if ((uint8_t)fText[fOffset] >= 127) {
++fOffset;
break;
uint8_t c = (uint8_t)fText[fOffset];
if (c <= 8 || c >= 127) {
c = INVALID_CHAR;
}
int16_t newState = transitions[mappings[(int)fText[fOffset]]][state];
int16_t newState = transitions[mappings[c]][state];
if (!newState) {
break;
}
@ -1027,4 +1028,4 @@ Token Lexer::next() {
return Token(kind, startOffset, fOffset - startOffset);
}
} // namespace SkSL
} // namespace

View File

@ -241,5 +241,5 @@ private:
int32_t fOffset;
};
} // namespace SkSL
} // namespace
#endif

View File

@ -98,6 +98,9 @@ void writeCPP(const DFA& dfa, const char* lexer, const char* token, const char*
for (const auto& row : dfa.fTransitions) {
states = std::max(states, row.size());
}
// arbitrarily-chosen character which is greater than START_CHAR and should not appear in actual
// input
out << "static const uint8_t INVALID_CHAR = 18;";
out << "static int8_t mappings[" << dfa.fCharMappings.size() << "] = {\n ";
const char* separator = "";
for (int m : dfa.fCharMappings) {
@ -143,11 +146,11 @@ void writeCPP(const DFA& dfa, const char* lexer, const char* token, const char*
out << " }\n";
out << " int16_t state = 1;\n";
out << " while (fOffset < fLength) {\n";
out << " if ((uint8_t) fText[fOffset] >= " << dfa.fCharMappings.size() << ") {";
out << " ++fOffset;\n";
out << " break;";
out << " uint8_t c = (uint8_t) fText[fOffset];";
out << " if (c <= 8 || c >= " << dfa.fCharMappings.size() << ") {";
out << " c = INVALID_CHAR;";
out << " }";
out << " int16_t newState = transitions[mappings[(int) fText[fOffset]]][state];\n";
out << " int16_t newState = transitions[mappings[c]][state];\n";
out << " if (!newState) {\n";
out << " break;\n";
out << " }\n";