diff options
-rw-r--r-- | opentracker.c | 24 | ||||
-rw-r--r-- | scan_urlencoded_query.c | 32 | ||||
-rw-r--r-- | scan_urlencoded_query.h | 17 |
3 files changed, 42 insertions, 31 deletions
diff --git a/opentracker.c b/opentracker.c index b77773d..380168e 100644 --- a/opentracker.c +++ b/opentracker.c | |||
@@ -237,10 +237,10 @@ LOG_TO_STDERR( "sync: %d.%d.%d.%d\n", h->ip[0], h->ip[1], h->ip[2], h->ip[3] ); | |||
237 | switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { | 237 | switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { |
238 | case -2: scanon = 0; break; /* TERMINATOR */ | 238 | case -2: scanon = 0; break; /* TERMINATOR */ |
239 | case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */ | 239 | case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */ |
240 | default: scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); break; | 240 | default: scan_urlencoded_skipvalue( &c ); break; |
241 | case 9: | 241 | case 9: |
242 | if(byte_diff(data,9,"changeset")) { | 242 | if(byte_diff(data,9,"changeset")) { |
243 | scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); | 243 | scan_urlencoded_skipvalue( &c ); |
244 | continue; | 244 | continue; |
245 | } | 245 | } |
246 | /* ignore this, when we dont at least see "d4:syncdee" */ | 246 | /* ignore this, when we dont at least see "d4:syncdee" */ |
@@ -273,10 +273,10 @@ LOG_TO_STDERR( "sync: %d.%d.%d.%d\n", h->ip[0], h->ip[1], h->ip[2], h->ip[3] ); | |||
273 | switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { | 273 | switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { |
274 | case -2: scanon = 0; break; /* TERMINATOR */ | 274 | case -2: scanon = 0; break; /* TERMINATOR */ |
275 | case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */ | 275 | case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */ |
276 | default: scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); break; | 276 | default: scan_urlencoded_skipvalue( &c ); break; |
277 | case 4: | 277 | case 4: |
278 | if( byte_diff(data,4,"mode")) { | 278 | if( byte_diff(data,4,"mode")) { |
279 | scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); | 279 | scan_urlencoded_skipvalue( &c ); |
280 | continue; | 280 | continue; |
281 | } | 281 | } |
282 | if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 4 ) HTTPERROR_400_PARAM; | 282 | if( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) != 4 ) HTTPERROR_400_PARAM; |
@@ -362,10 +362,10 @@ SCRAPE_WORKAROUND: | |||
362 | switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { | 362 | switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { |
363 | case -2: scanon = 0; break; /* TERMINATOR */ | 363 | case -2: scanon = 0; break; /* TERMINATOR */ |
364 | case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */ | 364 | case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */ |
365 | default: scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); break; | 365 | default: scan_urlencoded_skipvalue( &c ); break; |
366 | case 9: | 366 | case 9: |
367 | if(byte_diff(data,9,"info_hash")) { | 367 | if(byte_diff(data,9,"info_hash")) { |
368 | scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); | 368 | scan_urlencoded_skipvalue( &c ); |
369 | continue; | 369 | continue; |
370 | } | 370 | } |
371 | /* ignore this, when we have less than 20 bytes */ | 371 | /* ignore this, when we have less than 20 bytes */ |
@@ -407,7 +407,7 @@ ANNOUNCE_WORKAROUND: | |||
407 | switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { | 407 | switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_PARAM ) ) { |
408 | case -2: scanon = 0; break; /* TERMINATOR */ | 408 | case -2: scanon = 0; break; /* TERMINATOR */ |
409 | case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */ | 409 | case -1: HTTPERROR_400_PARAM; /* PARSE ERROR */ |
410 | default: scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); break; | 410 | default: scan_urlencoded_skipvalue( &c ); break; |
411 | #ifdef WANT_IP_FROM_QUERY_STRING | 411 | #ifdef WANT_IP_FROM_QUERY_STRING |
412 | case 2: | 412 | case 2: |
413 | if(!byte_diff(data,2,"ip")) { | 413 | if(!byte_diff(data,2,"ip")) { |
@@ -416,7 +416,7 @@ ANNOUNCE_WORKAROUND: | |||
416 | if( ( len <= 0 ) || scan_fixed_ip( data, len, ip ) ) HTTPERROR_400_PARAM; | 416 | if( ( len <= 0 ) || scan_fixed_ip( data, len, ip ) ) HTTPERROR_400_PARAM; |
417 | OT_SETIP( &peer, ip ); | 417 | OT_SETIP( &peer, ip ); |
418 | } else | 418 | } else |
419 | scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); | 419 | scan_urlencoded_skipvalue( &c ); |
420 | break; | 420 | break; |
421 | #endif | 421 | #endif |
422 | case 4: | 422 | case 4: |
@@ -429,11 +429,11 @@ ANNOUNCE_WORKAROUND: | |||
429 | if( scan_fixed_int( data, len, &tmp ) ) tmp = 0; | 429 | if( scan_fixed_int( data, len, &tmp ) ) tmp = 0; |
430 | if( !tmp ) OT_FLAG( &peer ) |= PEER_FLAG_SEEDING; | 430 | if( !tmp ) OT_FLAG( &peer ) |= PEER_FLAG_SEEDING; |
431 | } else | 431 | } else |
432 | scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); | 432 | scan_urlencoded_skipvalue( &c ); |
433 | break; | 433 | break; |
434 | case 5: | 434 | case 5: |
435 | if( byte_diff( data, 5, "event" ) ) | 435 | if( byte_diff( data, 5, "event" ) ) |
436 | scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); | 436 | scan_urlencoded_skipvalue( &c ); |
437 | else switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) { | 437 | else switch( scan_urlencoded_query( &c, data = c, SCAN_SEARCHPATH_VALUE ) ) { |
438 | case -1: | 438 | case -1: |
439 | HTTPERROR_400_PARAM; | 439 | HTTPERROR_400_PARAM; |
@@ -456,11 +456,11 @@ ANNOUNCE_WORKAROUND: | |||
456 | if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) HTTPERROR_400_PARAM; | 456 | if( ( len <= 0 ) || scan_fixed_int( data, len, &tmp ) ) HTTPERROR_400_PARAM; |
457 | if( !tmp ) HTTPERROR_400_COMPACT; | 457 | if( !tmp ) HTTPERROR_400_COMPACT; |
458 | } else | 458 | } else |
459 | scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); | 459 | scan_urlencoded_skipvalue( &c ); |
460 | break; | 460 | break; |
461 | case 9: | 461 | case 9: |
462 | if(byte_diff(data,9,"info_hash")) { | 462 | if(byte_diff(data,9,"info_hash")) { |
463 | scan_urlencoded_query( &c, NULL, SCAN_SEARCHPATH_VALUE ); | 463 | scan_urlencoded_skipvalue( &c ); |
464 | continue; | 464 | continue; |
465 | } | 465 | } |
466 | /* ignore this, when we have less than 20 bytes */ | 466 | /* ignore this, when we have less than 20 bytes */ |
diff --git a/scan_urlencoded_query.c b/scan_urlencoded_query.c index a11b65c..f754fdc 100644 --- a/scan_urlencoded_query.c +++ b/scan_urlencoded_query.c | |||
@@ -15,10 +15,10 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | static const unsigned char is_unreserved[256] = { | 17 | static const unsigned char is_unreserved[256] = { |
18 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 18 | 8,0,0,0,0,0,0,0,0,0,8,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
19 | 0,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0, | 19 | 8,7,0,0,0,7,0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,7,6, |
20 | 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1, | 20 | 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, |
21 | 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,0, | 21 | 0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,0,0,0,7,0, |
22 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 22 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
23 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 23 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
24 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | 24 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
@@ -32,31 +32,35 @@ static unsigned char fromhex(unsigned char x) { | |||
32 | return 0xff; | 32 | return 0xff; |
33 | } | 33 | } |
34 | 34 | ||
35 | ssize_t scan_urlencoded_query(char **string, char *deststring, int flags) { | 35 | void scan_urlencoded_skipvalue( char **string ) { |
36 | const unsigned char* s=*(const unsigned char**) string; | ||
37 | unsigned char f; | ||
38 | |||
39 | while( ( f = is_unreserved[ *s++ ] ) & SCAN_SEARCHPATH_VALUE ); | ||
40 | if( f & SCAN_SEARCHPATH_TERMINATOR ) --s; | ||
41 | *string = (char*)s; | ||
42 | } | ||
43 | |||
44 | ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_FLAG flags) { | ||
36 | const unsigned char* s=*(const unsigned char**) string; | 45 | const unsigned char* s=*(const unsigned char**) string; |
37 | unsigned char *d = (unsigned char*)deststring; | 46 | unsigned char *d = (unsigned char*)deststring; |
38 | register unsigned char b, c; | 47 | unsigned char b, c, f; |
39 | 48 | ||
40 | retry_parsing: | 49 | while( ( f = is_unreserved[ c = *s++ ] ) & flags ) { |
41 | while( is_unreserved[ c = *s++ ] ) { | ||
42 | if( c=='%') { | 50 | if( c=='%') { |
43 | if( ( b = fromhex(*s++) ) == 0xff ) return -1; | 51 | if( ( b = fromhex(*s++) ) == 0xff ) return -1; |
44 | if( ( c = fromhex(*s++) ) == 0xff ) return -1; | 52 | if( ( c = fromhex(*s++) ) == 0xff ) return -1; |
45 | c|=(b<<4); | 53 | c|=(b<<4); |
46 | } | 54 | } |
47 | if( d ) *d++ = c; | 55 | *d++ = c; |
48 | } | 56 | } |
49 | 57 | ||
50 | switch( c ) { | 58 | switch( c ) { |
51 | case 0: case '\r': case '\n': case ' ': | 59 | case 0: case '\r': case '\n': case ' ': |
52 | if( d && ( d == (unsigned char*)deststring ) ) return -2; | 60 | if( d == (unsigned char*)deststring ) return -2; |
53 | --s; | 61 | --s; |
54 | break; | 62 | break; |
55 | case '?': | 63 | case '?': |
56 | if( flags != SCAN_PATH ) { | ||
57 | if( d ) *d++ = c; | ||
58 | goto retry_parsing; | ||
59 | } | ||
60 | break; | 64 | break; |
61 | case '=': | 65 | case '=': |
62 | if( flags != SCAN_SEARCHPATH_PARAM ) return -1; | 66 | if( flags != SCAN_SEARCHPATH_PARAM ) return -1; |
diff --git a/scan_urlencoded_query.h b/scan_urlencoded_query.h index 56d93c8..4fa35c4 100644 --- a/scan_urlencoded_query.h +++ b/scan_urlencoded_query.h | |||
@@ -4,17 +4,24 @@ | |||
4 | #ifndef __SCAN_URLENCODED_QUERY_H__ | 4 | #ifndef __SCAN_URLENCODED_QUERY_H__ |
5 | #define __SCAN_URLENCODED_QUERY_H__ | 5 | #define __SCAN_URLENCODED_QUERY_H__ |
6 | 6 | ||
7 | #define SCAN_PATH 0 | 7 | typedef enum { |
8 | #define SCAN_SEARCHPATH_PARAM 1 | 8 | SCAN_PATH = 1, |
9 | #define SCAN_SEARCHPATH_VALUE 2 | 9 | SCAN_SEARCHPATH_PARAM = 2, |
10 | SCAN_SEARCHPATH_VALUE = 4, | ||
11 | SCAN_SEARCHPATH_TERMINATOR = 8 | ||
12 | } SCAN_SEARCHPATH_FLAG; | ||
10 | 13 | ||
11 | /* string pointer to source, pointer to after terminator on return | 14 | /* string pointer to source, pointer to next scan position on return |
12 | deststring pointer to destination | 15 | deststring pointer to destination |
13 | flags determines, what to parse | 16 | flags determines, what to parse |
14 | returns number of valid converted characters in deststring | 17 | returns number of valid converted characters in deststring |
15 | or -1 for parse error | 18 | or -1 for parse error |
16 | */ | 19 | */ |
17 | ssize_t scan_urlencoded_query(char **string, char *deststring, int flags); | 20 | ssize_t scan_urlencoded_query(char **string, char *deststring, SCAN_SEARCHPATH_FLAG flags); |
21 | |||
22 | /* string pointer to source, pointer to next scan position on return | ||
23 | */ | ||
24 | void scan_urlencoded_skipvalue( char **string ); | ||
18 | 25 | ||
19 | /* data pointer to len chars of string | 26 | /* data pointer to len chars of string |
20 | len length of chars in data to parse | 27 | len length of chars in data to parse |