Fix an infinite loop during message generation.

Rename getWord to spvGetWord and unit test it.
This commit is contained in:
David Neto 2015-09-11 12:04:03 -04:00
parent dbdf6e122c
commit a48678ab92
3 changed files with 34 additions and 4 deletions

View File

@ -53,20 +53,23 @@ struct spv_named_id_table_t {
// Text API // Text API
std::string getWord(const char *str) { std::string spvGetWord(const char *str) {
size_t index = 0; size_t index = 0;
while (true) { while (true) {
switch (str[index]) { switch (str[index]) {
case '\0': case '\0':
case '\t': case '\t':
case '\v':
case '\r':
case '\n': case '\n':
case ' ': case ' ':
break; return std::string(str, str + index);
default: default:
index++; index++;
} }
} }
return std::string(str, str + index); assert(0 && "Unreachable");
return ""; // Make certain compilers happy.
} }
spv_named_id_table spvNamedIdTableCreate() { spv_named_id_table spvNamedIdTableCreate() {
@ -674,7 +677,7 @@ spv_result_t spvTextEncodeOpcode(
spv_opcode_desc opcodeEntry; spv_opcode_desc opcodeEntry;
error = spvOpcodeTableNameLookup(opcodeTable, pInstName, &opcodeEntry); error = spvOpcodeTableNameLookup(opcodeTable, pInstName, &opcodeEntry);
spvCheck(error, DIAGNOSTIC << "Invalid Opcode name '" spvCheck(error, DIAGNOSTIC << "Invalid Opcode name '"
<< getWord(text->str + position->index) << "'"; << spvGetWord(text->str + position->index) << "'";
return error); return error);
if (SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT == format) { if (SPV_ASSEMBLY_SYNTAX_FORMAT_ASSIGNMENT == format) {
// If this instruction has <result-id>, check it follows AAF. // If this instruction has <result-id>, check it follows AAF.

View File

@ -66,6 +66,16 @@ typedef spv_named_id_table_t *spv_named_id_table;
// Functions // Functions
/// @brief Returns the word at the beginning of the given string.
///
/// A word ends at the first space, tab, form feed, carriage return, newline,
/// or at the end of the string.
///
/// @param[in] str the source string
///
/// @return word as a string
std::string spvGetWord(const char* str);
/// @brief Advance text to the start of the next line /// @brief Advance text to the start of the next line
/// ///
/// @param[in] text to be parsed /// @param[in] text to be parsed

View File

@ -37,6 +37,23 @@ namespace {
using spvutils::BitwiseCast; using spvutils::BitwiseCast;
using test_fixture::TextToBinaryTest; using test_fixture::TextToBinaryTest;
TEST(GetWord, Simple) {
EXPECT_EQ("", spvGetWord(""));
EXPECT_EQ("", spvGetWord("\0a"));
EXPECT_EQ("", spvGetWord(" a"));
EXPECT_EQ("", spvGetWord("\ta"));
EXPECT_EQ("", spvGetWord("\va"));
EXPECT_EQ("", spvGetWord("\ra"));
EXPECT_EQ("", spvGetWord("\na"));
EXPECT_EQ("abc", spvGetWord("abc"));
EXPECT_EQ("abc", spvGetWord("abc "));
EXPECT_EQ("abc", spvGetWord("abc\t"));
EXPECT_EQ("abc", spvGetWord("abc\r"));
EXPECT_EQ("abc", spvGetWord("abc\v"));
EXPECT_EQ("abc", spvGetWord("abc\n"));
}
// TODO(dneto): Aliasing like this relies on undefined behaviour. Fix this.
union char_word_t { union char_word_t {
char cs[4]; char cs[4];
uint32_t u; uint32_t u;