diff options
Diffstat (limited to 'scan_urlencoded_query.c')
| -rw-r--r-- | scan_urlencoded_query.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/scan_urlencoded_query.c b/scan_urlencoded_query.c new file mode 100644 index 0000000..7aeabab --- /dev/null +++ b/scan_urlencoded_query.c | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | #include "scan.h" | ||
| 2 | |||
| 3 | #define BREAK_AT_QUESTIONMARK (1<<0) | ||
| 4 | #define BREAK_AT_WHITESPACE (1<<1) | ||
| 5 | #define BREAK_AT_AMPERSAND (1<<2) | ||
| 6 | #define BREAK_AT_EQUALSIGN (1<<3) | ||
| 7 | |||
| 8 | #define SCAN_PATH ( BREAK_AT_QUESTIONMARK | BREAK_AT_WHITESPACE ) | ||
| 9 | #define SCAN_SEARCHPATH_PARAM ( BREAK_AT_EQUALSIGN ) | ||
| 10 | #define SCAN_SEARCHPATH_VALUE ( BREAK_AT_AMPERSAND | BREAK_AT_WHITESPACE ) | ||
| 11 | |||
| 12 | // Idea is to do a in place replacement or guarantee at least | ||
| 13 | // strlen( string ) bytes in deststring | ||
| 14 | // watch http://www.ietf.org/rfc/rfc2396.txt | ||
| 15 | // unreserved = alphanum | mark | ||
| 16 | // mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" | ||
| 17 | // we add '%' to the matrix to not stop at encoded chars. | ||
| 18 | |||
| 19 | static const unsigned char reserved_matrix[] = { 0xA2, 0x63, 0xFF, 0x03, 0xFE, 0xFF, 0xFF, 0x87, 0xFE, 0xFF, 0xFF, 0x47}; | ||
| 20 | inline int is_unreserved( unsigned char c ) const { | ||
| 21 | if( ( c <= 32 ) || ( c >= 127 ) ) return 0; return 1&(reserved_matrix[(c-32)>>3]>>(c&7)); | ||
| 22 | } | ||
| 23 | |||
| 24 | size_t scan_urlencoded_query(char **string, char *deststring, int flags) { | ||
| 25 | register const unsigned char* s=*(const unsigned char*) string; | ||
| 26 | const unsigned char *d = deststring; | ||
| 27 | register unsigned char b, c; | ||
| 28 | |||
| 29 | while ( is_unreserved( c = *s++) ) { | ||
| 30 | if (c=='%') { | ||
| 31 | if( ( c = scan_fromhex(*s++) ) < 0 ) return -1; | ||
| 32 | if( ( b = scan_fromhex(*s++) ) < 0 ) return -1; | ||
| 33 | c=(c<<4)|b; | ||
| 34 | } | ||
| 35 | *d++ = c; | ||
| 36 | } | ||
| 37 | |||
| 38 | switch( c ) { | ||
| 39 | case 0: case '\r': case '\n': case ' ': | ||
| 40 | if ( flags & BREAK_AT_WHITESPACE == 0 ) return -1; | ||
| 41 | break; | ||
| 42 | case '?': | ||
| 43 | if ( flags & BREAK_AT_QUESTIONMARK == 0 ) return -1; | ||
| 44 | break; | ||
| 45 | case '=': | ||
| 46 | if ( flags & BREAK_AT_EQUALSIGN == 0 ) return -1; | ||
| 47 | break; | ||
| 48 | case '&': | ||
| 49 | if ( flags & BREAK_AT_AMPERSAND == 0 ) return -1; | ||
| 50 | break; | ||
| 51 | default: | ||
| 52 | return -1; | ||
| 53 | } | ||
| 54 | |||
| 55 | *string = s; | ||
| 56 | return d - deststring; | ||
| 57 | } | ||
