diff options
Diffstat (limited to 'scan_urlencoded_query.c')
| -rw-r--r-- | scan_urlencoded_query.c | 97 |
1 files changed, 60 insertions, 37 deletions
diff --git a/scan_urlencoded_query.c b/scan_urlencoded_query.c index a4f89c2..2d3599d 100644 --- a/scan_urlencoded_query.c +++ b/scan_urlencoded_query.c | |||
| @@ -45,37 +45,45 @@ static const unsigned char is_unreserved[256] = { | |||
| 45 | 45 | ||
| 46 | /* Do a fast nibble to hex representation conversion */ | 46 | /* Do a fast nibble to hex representation conversion */ |
| 47 | static unsigned char fromhex(unsigned char x) { | 47 | static unsigned char fromhex(unsigned char x) { |
| 48 | x-='0'; if( x<=9) return x; | 48 | x -= '0'; |
| 49 | x&=~0x20; x-='A'-'0'; | 49 | if (x <= 9) |
| 50 | if( x<6 ) return x+10; | 50 | return x; |
| 51 | x &= ~0x20; | ||
| 52 | x -= 'A' - '0'; | ||
| 53 | if (x < 6) | ||
| 54 | return x + 10; | ||
| 51 | return 0xff; | 55 | return 0xff; |
| 52 | } | 56 | } |
| 53 | 57 | ||
| 54 | /* Skip the value of a param=value pair */ | 58 | /* Skip the value of a param=value pair */ |
| 55 | void scan_urlencoded_skipvalue( char **string ) { | 59 | void scan_urlencoded_skipvalue(char **string) { |
| 56 | const unsigned char* s=*(const unsigned char**) string; | 60 | const unsigned char *s = *(const unsigned char **)string; |
| 57 | unsigned char f; | 61 | unsigned char f; |
| 58 | 62 | ||
| 59 | /* Since we are asked to skip the 'value', we assume to stop at | 63 | /* Since we are asked to skip the 'value', we assume to stop at |
| 60 | terminators for a 'value' string position */ | 64 | terminators for a 'value' string position */ |
| 61 | while( ( f = is_unreserved[ *s++ ] ) & SCAN_SEARCHPATH_VALUE ); | 65 | while ((f = is_unreserved[*s++]) & SCAN_SEARCHPATH_VALUE) |
| 66 | ; | ||
| 62 | 67 | ||
| 63 | /* If we stopped at a hard terminator like \0 or \n, make the | 68 | /* If we stopped at a hard terminator like \0 or \n, make the |
| 64 | next scan_urlencoded_query encounter it again */ | 69 | next scan_urlencoded_query encounter it again */ |
| 65 | if( f & SCAN_SEARCHPATH_TERMINATOR ) --s; | 70 | if (f & SCAN_SEARCHPATH_TERMINATOR) |
| 71 | --s; | ||
| 66 | 72 | ||
| 67 | *string = (char*)s; | 73 | *string = (char *)s; |
| 68 | } | 74 | } |
| 69 | 75 | ||
| 70 | int scan_find_keywords( const ot_keywords * keywords, char **string, SCAN_SEARCHPATH_FLAG flags) { | 76 | int scan_find_keywords(const ot_keywords *keywords, char **string, SCAN_SEARCHPATH_FLAG flags) { |
| 71 | char *deststring = *string; | 77 | char *deststring = *string; |
| 72 | ssize_t match_length = scan_urlencoded_query(string, deststring, flags ); | 78 | ssize_t match_length = scan_urlencoded_query(string, deststring, flags); |
| 73 | 79 | ||
| 74 | if( match_length < 0 ) return match_length; | 80 | if (match_length < 0) |
| 75 | if( match_length == 0 ) return -3; | 81 | return match_length; |
| 82 | if (match_length == 0) | ||
| 83 | return -3; | ||
| 76 | 84 | ||
| 77 | while( keywords->key ) { | 85 | while (keywords->key) { |
| 78 | if( !strncmp( keywords->key, deststring, match_length ) && !keywords->key[match_length] ) | 86 | if (!strncmp(keywords->key, deststring, match_length) && !keywords->key[match_length]) |
| 79 | return keywords->value; | 87 | return keywords->value; |
| 80 | keywords++; | 88 | keywords++; |
| 81 | } | 89 | } |
| @@ -84,59 +92,74 @@ int scan_find_keywords( const ot_keywords * keywords, char **string, SCAN_SEARCH | |||
| 84 | } | 92 | } |
| 85 | 93 | ||
| 86 | ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_FLAG flags) { | 94 | ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_FLAG flags) { |
| 87 | const unsigned char* s=*(const unsigned char**) string; | 95 | const unsigned char *s = *(const unsigned char **)string; |
| 88 | unsigned char *d = (unsigned char*)deststring; | 96 | unsigned char *d = (unsigned char *)deststring; |
| 89 | unsigned char b, c; | 97 | unsigned char b, c; |
| 90 | 98 | ||
| 91 | /* This is the main decoding loop. | 99 | /* This is the main decoding loop. |
| 92 | 'flag' determines, which characters are non-terminating in current context | 100 | 'flag' determines, which characters are non-terminating in current context |
| 93 | (ie. stop at '=' and '&' if scanning for a 'param'; stop at '?' if scanning for the path ) | 101 | (ie. stop at '=' and '&' if scanning for a 'param'; stop at '?' if scanning for the path ) |
| 94 | */ | 102 | */ |
| 95 | while( is_unreserved[ c = *s++ ] & flags ) { | 103 | while (is_unreserved[c = *s++] & flags) { |
| 96 | 104 | ||
| 97 | /* When encountering an url escaped character, try to decode */ | 105 | /* When encountering an url escaped character, try to decode */ |
| 98 | if( c=='%') { | 106 | if (c == '%') { |
| 99 | if( ( b = fromhex(*s++) ) == 0xff ) return -1; | 107 | if ((b = fromhex(*s++)) == 0xff) |
| 100 | if( ( c = fromhex(*s++) ) == 0xff ) return -1; | 108 | return -1; |
| 101 | c|=(b<<4); | 109 | if ((c = fromhex(*s++)) == 0xff) |
| 110 | return -1; | ||
| 111 | c |= (b << 4); | ||
| 102 | } | 112 | } |
| 103 | 113 | ||
| 104 | /* Write (possibly decoded) character to output */ | 114 | /* Write (possibly decoded) character to output */ |
| 105 | *d++ = c; | 115 | *d++ = c; |
| 106 | } | 116 | } |
| 107 | 117 | ||
| 108 | switch( c ) { | 118 | switch (c) { |
| 109 | case 0: case '\r': case '\n': case ' ': | 119 | case 0: |
| 120 | case '\r': | ||
| 121 | case '\n': | ||
| 122 | case ' ': | ||
| 110 | /* If we started scanning on a hard terminator, indicate we've finished */ | 123 | /* If we started scanning on a hard terminator, indicate we've finished */ |
| 111 | if( d == (unsigned char*)deststring ) return -2; | 124 | if (d == (unsigned char *)deststring) |
| 125 | return -2; | ||
| 112 | 126 | ||
| 113 | /* Else make the next call to scan_urlencoded_param encounter it again */ | 127 | /* Else make the next call to scan_urlencoded_param encounter it again */ |
| 114 | --s; | 128 | --s; |
| 115 | break; | 129 | break; |
| 116 | case '?': | 130 | case '?': |
| 117 | if( flags != SCAN_PATH ) return -1; | 131 | if (flags != SCAN_PATH) |
| 132 | return -1; | ||
| 118 | break; | 133 | break; |
| 119 | case '=': | 134 | case '=': |
| 120 | if( flags != SCAN_SEARCHPATH_PARAM ) return -1; | 135 | if (flags != SCAN_SEARCHPATH_PARAM) |
| 136 | return -1; | ||
| 121 | break; | 137 | break; |
| 122 | case '&': | 138 | case '&': |
| 123 | if( flags == SCAN_PATH ) return -1; | 139 | if (flags == SCAN_PATH) |
| 124 | if( flags == SCAN_SEARCHPATH_PARAM ) --s; | 140 | return -1; |
| 141 | if (flags == SCAN_SEARCHPATH_PARAM) | ||
| 142 | --s; | ||
| 125 | break; | 143 | break; |
| 126 | default: | 144 | default: |
| 127 | return -1; | 145 | return -1; |
| 128 | } | 146 | } |
| 129 | 147 | ||
| 130 | *string = (char *)s; | 148 | *string = (char *)s; |
| 131 | return d - (unsigned char*)deststring; | 149 | return d - (unsigned char *)deststring; |
| 132 | } | 150 | } |
| 133 | 151 | ||
| 134 | ssize_t scan_fixed_int( char *data, size_t len, int *tmp ) { | 152 | ssize_t scan_fixed_int(char *data, size_t len, int *tmp) { |
| 135 | int minus = 0; | 153 | int minus = 0; |
| 136 | *tmp = 0; | 154 | *tmp = 0; |
| 137 | if( *data == '-' ) --len, ++data, ++minus; | 155 | if (*data == '-') |
| 138 | while( (len > 0) && (*data >= '0') && (*data <= '9') ) { --len; *tmp = 10**tmp + *data++-'0'; } | 156 | --len, ++data, ++minus; |
| 139 | if( minus ) *tmp = -*tmp; | 157 | while ((len > 0) && (*data >= '0') && (*data <= '9')) { |
| 158 | --len; | ||
| 159 | *tmp = 10 * *tmp + *data++ - '0'; | ||
| 160 | } | ||
| 161 | if (minus) | ||
| 162 | *tmp = -*tmp; | ||
| 140 | return len; | 163 | return len; |
| 141 | } | 164 | } |
| 142 | 165 | ||
