Пример #1
0
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;
}
Пример #2
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;
    }
}
Пример #3
0
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;
}
Пример #4
0
/*
** 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);
}
Пример #5
0
    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);
	}