static uint8_t readHexByte(std::istream & s) { std::istream::sentry sentry(s, true); if (sentry) { char c1 = 0, c2 = 0; s.get(c1); s.get(c2); if (s.fail()) { if (s.eof()) { throw std::runtime_error("Unexpected end of line."); } else { throw std::runtime_error("Failed to read hex digit."); } } int v1 = hexDigitValue(c1); int v2 = hexDigitValue(c2); if (v1 < 0 || v2 < 0) { throw std::runtime_error("Invalid hex digit."); } return v1 * 16 + v2; } return 0; }
static void unescapeUri(const char *const uriComponent, const char **const unescapedP, const char **const errorP) { /*---------------------------------------------------------------------------- Unescape a component of a URI, e.g. the host name. That component may have %HH encoding, especially of characters that are delimiters within a URI like slash and colon. Return the unescaped version as *unescapedP in newly malloced storage. -----------------------------------------------------------------------------*/ char *buffer; buffer = strdup(uriComponent); if (!buffer) xmlrpc_asprintf(errorP, "Couldn't get memory for URI unescape buffer"); else { const char *src; char *dst; src = dst = buffer; *errorP = NULL; /* initial value */ while (*src && !*errorP) { switch (*src) { case '%': { unsigned int digit0; hexDigitValue(*src++, &digit0, errorP); if (!*errorP) { unsigned int digit1; hexDigitValue(*src++, &digit1, errorP); if (!*errorP) *dst++ = ((digit0 << 4) | digit1); } } break; default: *dst++ = *src++; break; } } *dst = '\0'; if (*errorP) xmlrpc_strfree(buffer); else *unescapedP = buffer; } }
static void parsePerCentEscape(const char ** const srcP, char * const unescapedP, const char ** const errorP) { /*----------------------------------------------------------------------------- With *srcP pointing to a supposed %HH escape sequence in a buffer, set *unescapedP to the character that the sequence represents and advance *srcP past it. -----------------------------------------------------------------------------*/ unsigned int digit0; const char * src; src = *srcP; /* initial value */ ++src; /* Move past per cent sign */ if (!*src) xmlrpc_asprintf(errorP, "URI ends after the %%"); else { *errorP = NULL; /* initial assumption */ hexDigitValue(*src++, &digit0, errorP); if (!*errorP) { unsigned int digit1; if (!*src) xmlrpc_asprintf(errorP, "URI ends after the first digit"); else { hexDigitValue(*src++, &digit1, errorP); if (!*errorP) *unescapedP = ((digit0 << 4) | digit1); } } } *srcP = src; }
/* ** Interpret zArg as an integer value, possibly with suffixes. */ static int integerValue(const char *zArg) { sqlite3_int64 v = 0; static const struct { char *zSuffix; int iMult; } aMult[] = { { "KiB", 1024 }, { "MiB", 1024*1024 }, { "GiB", 1024*1024*1024 }, { "KB", 1000 }, { "MB", 1000000 }, { "GB", 1000000000 }, { "K", 1000 }, { "M", 1000000 }, { "G", 1000000000 }, }; int i; int isNeg = 0; if( zArg[0]=='-' ) { isNeg = 1; zArg++; } else if( zArg[0]=='+' ) { zArg++; } if( zArg[0]=='0' && zArg[1]=='x' ) { int x; zArg += 2; while( (x = hexDigitValue(zArg[0]))>=0 ) { v = (v<<4) + x; zArg++; } } else { while( ISDIGIT(zArg[0]) ) { v = v*10 + zArg[0] - '0'; zArg++; } } for(i=0; i<sizeof(aMult)/sizeof(aMult[0]); i++) { if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ) { v *= aMult[i].iMult; break; } } if( v>0x7fffffff ) fatalError("parameter too large - max 2147483648"); return (int)(isNeg? -v : v); }
void Properties::parseProperty(const QString &rProperty, int line) { Q_ASSERT_X(rProperty == trimLeft(rProperty), "parseProperty()", "rProperty has leading spaces"); enum State { KEY_STATE, KEYSPACE_STATE, SPACEVALUE_STATE, VALUE_STATE, KEYESCAPE_STATE, VALUEESCAPE_STATE, UNICODEESCAPE_STATE }; const QString value_escape_codes =QLatin1String(msValueEscapeCodes); const QString value_escape_chars = QLatin1String(msValueEscapeChars); Q_ASSERT_X(value_escape_codes.length() == value_escape_chars.length(), "parseProperty()", "Value escape sequence character definition does not map"); const QString key_escape_codes = QLatin1String(msKeyEscapeCodes); const QString key_escape_chars = QLatin1String(msKeyEscapeChars); Q_ASSERT_X(key_escape_codes.length() == key_escape_chars.length(), "parseProperty()", "Key escape sequence character definition does not map"); if (rProperty.isEmpty()) return; int i = 0; QChar c; char ch; State state = KEY_STATE; QString key; QString value; QString *p_string = &key; uint ucs; int ucs_digits; while (i < rProperty.length()) { // i points to the current character. // c contains the current character // ch contains the Latin1 equivalent of the current character // i is incremented at the end of the loop to consume the character. // continue is used to change state without consuming the character c = rProperty.at(i); ch = c.toLatin1(); switch (state) { case KEY_STATE: if (ch == '!' || ch == '#' ) return; else if (c.isSpace()) { p_string = &value; state = KEYSPACE_STATE; } else if (ch == '=' || ch == ':') { p_string = &value; state = SPACEVALUE_STATE; } else if (ch == msEscapeChar) state = KEYESCAPE_STATE; else *p_string += c; break; case KEYSPACE_STATE: if (ch == '=' || ch == ':') state = SPACEVALUE_STATE; else if (!c.isSpace()) { *p_string += c; state = VALUE_STATE; } break; case SPACEVALUE_STATE: if (!c.isSpace()) { *p_string += c; state = VALUE_STATE; } break; case VALUE_STATE: if (ch == msEscapeChar) state = VALUEESCAPE_STATE; else *p_string += c; break; case KEYESCAPE_STATE: { int convert = key_escape_codes.indexOf(c); if (convert >= 0) *p_string += key_escape_chars.at(convert); else { logger()->warn("Unknown escape sequence '\\%1' in key of property starting at line %2", QString(c), line); *p_string += c; } state = KEY_STATE; break; } case VALUEESCAPE_STATE: { int convert = value_escape_codes.indexOf(c); if (convert >= 0) { *p_string += value_escape_chars.at(convert); state = VALUE_STATE; } else if (ch == 'u') { ucs = 0; ucs_digits = 0; state = UNICODEESCAPE_STATE; } else { logger()->warn("Unknown escape sequence '\\%1' in value of property starting at line %2", QString(c), line); *p_string += c; state = VALUE_STATE; } break; } case UNICODEESCAPE_STATE: { int hex = hexDigitValue(c); if (hex >= 0) { ucs = ucs * 16 + hex; ucs_digits++; if (ucs_digits == 4 || i == rProperty.length() - 1) { *p_string += QChar(ucs); state = VALUE_STATE; } } else { if (ucs_digits > 0) *p_string += QChar(ucs); state = VALUE_STATE; continue; } break; } default: Q_ASSERT_X(false, "Properties::parseProperty()", "Unknown state constant"); return; } i++; } if (key.isEmpty() && !value.isEmpty()) logger()->warn("Found value with no key in property starting at line %1", line); logger()->trace("Loaded property '%1' : '%2'", key, value); insert(key, value); }