MathLib::characterLiteralToLongNumber now reports more specific error messages for unsupported unicode literals (see #7162)

This commit is contained in:
Alexander Mai 2015-11-22 07:38:38 +01:00
parent 714579401f
commit 517922feb6
2 changed files with 63 additions and 53 deletions

View File

@ -316,73 +316,81 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
MathLib::bigint MathLib::characterLiteralToLongNumber(const std::string& str) MathLib::bigint MathLib::characterLiteralToLongNumber(const std::string& str)
{ {
if (str.empty())
return 0; // for unit-testing...
if (str.size()==1) if (str.size()==1)
return str[0] & 0xff; return str[0] & 0xff;
if (str[0] != '\\') if (str[0] != '\\')
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant " + str); throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant " + str);
if (str[1]=='x') { switch (str[1]) {
case 'x':
return toLongNumber("0x" + str.substr(2)); return toLongNumber("0x" + str.substr(2));
} case 'u': // 16bit unicode character
char c; throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled 16-bit unicode char constant " + str);
switch (str.size()-1) { case 'U': // 16bit unicode character
case 1: throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled 32-bit unicode char constant " + str);
switch (str[1]) { default: {
case '0': char c;
case '1': switch (str.size()-1) {
case '2': case 1:
case '3': switch (str[1]) {
case '4': case '0':
case '5': case '1':
case '6': case '2':
case '7': case '3':
return str[1]-'0'; case '4':
case 'a': case '5':
c = '\a'; case '6':
case '7':
return str[1]-'0';
case 'a':
c = '\a';
break;
case 'b':
c = '\b';
break;
case 'f':
c = '\f';
break;
case 'n':
c = '\n';
break;
case 'r':
c = '\r';
break;
case 't':
c = '\t';
break;
case 'v':
c = '\v';
break;
case '\\':
case '\?':
case '\'':
case '\"':
c = str[1];
break;
default:
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant " + str);
break;
}
return c & 0xff;
case 2:
if (isOctalDigit(str[1]) && isOctalDigit(str[2]))
return toLongNumber("0" + str.substr(1));
break; break;
case 'b': case 3:
c = '\b'; if (isOctalDigit(str[1]) && isOctalDigit(str[2]) && isOctalDigit(str[3]))
break; return toLongNumber("0" + str.substr(1));
case 'f':
c = '\f';
break;
case 'n':
c = '\n';
break;
case 'r':
c = '\r';
break;
case 't':
c = '\t';
break;
case 'v':
c = '\v';
break;
case '\\':
case '\?':
case '\'':
case '\"':
c = str[1];
break;
default:
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant " + str);
break; break;
} }
return c & 0xff; }
case 2:
if (isOctalDigit(str[1]) && isOctalDigit(str[2]))
return toLongNumber("0" + str.substr(1));
break;
case 3:
if (isOctalDigit(str[1]) && isOctalDigit(str[2]) && isOctalDigit(str[3]))
return toLongNumber("0" + str.substr(1));
break;
} }
throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant " + str); throw InternalError(0, "Internal Error. MathLib::toLongNumber: Unhandled char constant " + str);
} }
MathLib::bigint MathLib::toLongNumber(const std::string & str) MathLib::bigint MathLib::toLongNumber(const std::string & str)
{ {
// hexadecimal numbers: // hexadecimal numbers:

View File

@ -282,6 +282,8 @@ private:
ASSERT_EQUALS((int)('\134'), MathLib::toLongNumber("'\\134'")); ASSERT_EQUALS((int)('\134'), MathLib::toLongNumber("'\\134'"));
ASSERT_THROW(MathLib::toLongNumber("'\\9'"), InternalError); ASSERT_THROW(MathLib::toLongNumber("'\\9'"), InternalError);
ASSERT_THROW(MathLib::toLongNumber("'\\934'"), InternalError); ASSERT_THROW(MathLib::toLongNumber("'\\934'"), InternalError);
ASSERT_THROW(MathLib::toLongNumber("'\\u9343'"), InternalError);
ASSERT_THROW(MathLib::toLongNumber("'\\U0001f34c'"), InternalError);
ASSERT_EQUALS(-8552249625308161526, MathLib::toLongNumber("0x89504e470d0a1a0a")); ASSERT_EQUALS(-8552249625308161526, MathLib::toLongNumber("0x89504e470d0a1a0a"));
ASSERT_EQUALS(-8481036456200365558, MathLib::toLongNumber("0x8a4d4e470d0a1a0a")); ASSERT_EQUALS(-8481036456200365558, MathLib::toLongNumber("0x8a4d4e470d0a1a0a"));