URL-Decode Funktion richtig?



  • Hi,
    ich brauche eine Funktion die eine hex-codierte URL dekodiert.

    Aus Hallo%20Welt soll Hallo Welt werden.

    Im Code eines Webservers habe ich dann das gefunden:

    static void strdecode( char* to, char* from )
        {
        for ( ; *from != '\0'; ++to, ++from )
    	{
    	if ( from[0] == '%' && isxdigit( from[1] ) && isxdigit( from[2] ) )
    	    {
    	    *to = hexit( from[1] ) * 16 + hexit( from[2] );
    	    from += 2;
    	    }
    	else
    	    *to = *from;
    	}
        *to = '\0';
        }
    

    Nur bei dieser Funktion habe ich das Gefühl das sie falsch ist, wenn nach dem % keine Zeichen mehr kommen greift er trotzdem auf die nächsten beiden Zeichen zu, oder?

    Als ich das kompiliert hab und Hallo% übergeben habe ist es aber nicht abgestürzt. Fängt die Funktion das doch irgendwo ab?



  • Hier wird es abgefangt:

    // Annahme: from = "%"; // [0: '%'] [1: '\0'] [2: Access denied]
    // from[0] == '%' -> Ja, weiter
    // isxdigit(from[1]) -> Nein, da '\0', Abbruch
     if ( from[0] == '%' && isxdigit( from[1] ) && isxdigit( from[2] ) )
    

    Die letzte Anweisung die einen Speicherzugriffsfehler bringen würde wird gar nicht mehr ausgeführt (garantiert).

    MfG SideWinder



  • int convertHexDigitToDecimalNumber(char hexDigit)
    {
    	assert(isxdigit(hexDigit));
    
    	switch(hexDigit)
    	{
    	case '0':
    	case '1':
    	case '2':
    	case '3':
    	case '4':
    	case '5':
    	case '6':
    	case '7':
    	case '8':
    	case '9':
    		return hexDigit - '0';
    	case 'A':
    	case 'B':
    	case 'C':
    	case 'D':
    	case 'E':
    	case 'F':
    		return hexDigit - 'A' + 10;
    	case 'a':
    	case 'b':
    	case 'c':
    	case 'd':
    	case 'e':
    	case 'f':
    		return hexDigit - 'a' + 10;
    	}
    
    	assert(false); // should never happen
    	return 0;
    }
    
    bool convertTwoDigitHexStringToChar(const std::string& input, unsigned char& output)
    {
    	if(input.length() != 2)
    	{
    		return false;
    	}
    
    	if(!isxdigit(input[0]) || !isxdigit(input[1]))
    	{
    		return false;
    	}
    
    	output = convertHexDigitToDecimalNumber(input[0]) * 16;
    	output += convertHexDigitToDecimalNumber(input[1]);
    
    	return true;
    }
    
    std::string decodeURL(const std::string& input)
    {
    	std::string output;
    	unsigned char decodedCharacter;
    
    	for(size_t i = 0; i < input.length(); ++i)
    	{
    		if(input[i] == '%' && convertTwoDigitHexStringToChar(input.substr(i + 1, 2), decodedCharacter))
    		{
    			output += decodedCharacter;
    			i += 2;
    		}
    		else if(input[i] == '+')
    		{
    			output += ' ';
    		}
    		else
    		{
    			output += input[i];
    		}
    	}
    
    	return output;
    }
    

Anmelden zum Antworten