Fixed returns for urlDecodeUni, urlDecode, urlEncode and normalisePathWin. See #439.

This commit is contained in:
brectanus 2007-12-20 23:29:07 +00:00
parent 9551218d23
commit 6dd6156466
4 changed files with 52 additions and 21 deletions

View File

@ -208,6 +208,7 @@ int parse_arguments(modsec_rec *msr, const char *s, apr_size_t inputlength,
char *value = NULL; char *value = NULL;
char *buf; char *buf;
int status; int status;
int changed;
if (s == NULL) return -1; if (s == NULL) return -1;
if (inputlength == 0) return 1; if (inputlength == 0) return 1;
@ -249,7 +250,7 @@ int parse_arguments(modsec_rec *msr, const char *s, apr_size_t inputlength,
} }
if (status == 0) { if (status == 0) {
arg->name_len = urldecode_nonstrict_inplace_ex((unsigned char *)buf, arg->name_origin_len, invalid_count); arg->name_len = urldecode_nonstrict_inplace_ex((unsigned char *)buf, arg->name_origin_len, invalid_count, &changed);
arg->name = apr_pstrmemdup(msr->mp, buf, arg->name_len); arg->name = apr_pstrmemdup(msr->mp, buf, arg->name_len);
if (s[i] == argument_separator) { if (s[i] == argument_separator) {
@ -270,7 +271,7 @@ int parse_arguments(modsec_rec *msr, const char *s, apr_size_t inputlength,
} }
} }
else { else {
arg->value_len = urldecode_nonstrict_inplace_ex((unsigned char *)value, arg->value_origin_len, invalid_count); arg->value_len = urldecode_nonstrict_inplace_ex((unsigned char *)value, arg->value_origin_len, invalid_count, &changed);
arg->value = apr_pstrmemdup(msr->mp, value, arg->value_len); arg->value = apr_pstrmemdup(msr->mp, value, arg->value_len);
add_argument(msr, arguments, arg); add_argument(msr, arguments, arg);

View File

@ -74,10 +74,12 @@ int parse_name_eq_value(apr_pool_t *mp, const char *input, char **name, char **v
* *
* IMP1 Assumes NUL-terminated * IMP1 Assumes NUL-terminated
*/ */
char *url_encode(apr_pool_t *mp, char *input, unsigned int input_len) { char *url_encode(apr_pool_t *mp, char *input, unsigned int input_len, int *changed) {
char *rval, *d; char *rval, *d;
unsigned int i, len; unsigned int i, len;
*changed = 0;
len = input_len * 3 + 1; len = input_len * 3 + 1;
d = rval = apr_palloc(mp, len); d = rval = apr_palloc(mp, len);
if (rval == NULL) return NULL; if (rval == NULL) return NULL;
@ -89,6 +91,7 @@ char *url_encode(apr_pool_t *mp, char *input, unsigned int input_len) {
if (c == ' ') { if (c == ' ') {
*d++ = '+'; *d++ = '+';
*changed = 1;
} else } else
if ( (c == 42) || ((c >= 48)&&(c <= 57)) || ((c >= 65)&&(c <= 90)) if ( (c == 42) || ((c >= 48)&&(c <= 57)) || ((c >= 65)&&(c <= 90))
|| ((c >= 97)&&(c <= 122)) || ((c >= 97)&&(c <= 122))
@ -98,6 +101,7 @@ char *url_encode(apr_pool_t *mp, char *input, unsigned int input_len) {
*d++ = '%'; *d++ = '%';
c2x(c, (unsigned char *)d); c2x(c, (unsigned char *)d);
d += 2; d += 2;
*changed = 1;
} }
} }
@ -700,10 +704,12 @@ int js_decode_nonstrict_inplace(unsigned char *input, long int input_len) {
* *
* IMP1 Assumes NUL-terminated * IMP1 Assumes NUL-terminated
*/ */
int urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_len) { int urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_len, int *changed) {
unsigned char *d = input; unsigned char *d = input;
long int i, count; long int i, count;
*changed = 0;
if (input == NULL) return -1; if (input == NULL) return -1;
i = count = 0; i = count = 0;
@ -732,6 +738,7 @@ int urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_len)
d++; d++;
count++; count++;
i += 6; i += 6;
*changed = 1;
} else { } else {
/* Invalid data, skip %u. */ /* Invalid data, skip %u. */
*d++ = input[i++]; *d++ = input[i++];
@ -761,6 +768,7 @@ int urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_len)
*d++ = x2c(&input[i + 1]); *d++ = x2c(&input[i + 1]);
count++; count++;
i += 3; i += 3;
*changed = 1;
} else { } else {
/* Not a valid encoding, skip this % */ /* Not a valid encoding, skip this % */
*d++ = input[i++]; *d++ = input[i++];
@ -777,6 +785,7 @@ int urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_len)
/* Character is not a percent sign. */ /* Character is not a percent sign. */
if (input[i] == '+') { if (input[i] == '+') {
*d++ = ' '; *d++ = ' ';
*changed = 1;
} else { } else {
*d++ = input[i]; *d++ = input[i];
} }
@ -795,10 +804,12 @@ int urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_len)
* *
* IMP1 Assumes NUL-terminated * IMP1 Assumes NUL-terminated
*/ */
int urldecode_nonstrict_inplace_ex(unsigned char *input, long int input_len, int *invalid_count) { int urldecode_nonstrict_inplace_ex(unsigned char *input, long int input_len, int *invalid_count, int *changed) {
unsigned char *d = (unsigned char *)input; unsigned char *d = (unsigned char *)input;
long int i, count; long int i, count;
*changed = 0;
if (input == NULL) return -1; if (input == NULL) return -1;
i = count = 0; i = count = 0;
@ -816,6 +827,7 @@ int urldecode_nonstrict_inplace_ex(unsigned char *input, long int input_len, int
*d++ = x2c(&input[i + 1]); *d++ = x2c(&input[i + 1]);
count++; count++;
i += 3; i += 3;
*changed = 1;
} else { } else {
/* Not a valid encoding, skip this % */ /* Not a valid encoding, skip this % */
*d++ = input[i++]; *d++ = input[i++];
@ -832,6 +844,7 @@ int urldecode_nonstrict_inplace_ex(unsigned char *input, long int input_len, int
/* Character is not a percent sign. */ /* Character is not a percent sign. */
if (input[i] == '+') { if (input[i] == '+') {
*d++ = ' '; *d++ = ' ';
*changed = 1;
} else { } else {
*d++ = input[i]; *d++ = input[i];
} }
@ -1071,16 +1084,21 @@ int ansi_c_sequences_decode_inplace(unsigned char *input, int input_len) {
* *
* IMP1 Assumes NUL-terminated * IMP1 Assumes NUL-terminated
*/ */
int normalise_path_inplace(unsigned char *input, int input_len, int win) { int normalise_path_inplace(unsigned char *input, int input_len, int win, int *changed) {
unsigned char *d = input; unsigned char *d = input;
int i, count; int i, count;
*changed = 0;
i = count = 0; i = count = 0;
while ((i < input_len)&&(count < input_len)) { while ((i < input_len)&&(count < input_len)) {
char c = input[i]; char c = input[i];
/* Convert backslash to forward slash on Windows only. */ /* Convert backslash to forward slash on Windows only. */
if ((win)&&(c == '\\')) c = '/'; if ((win)&&(c == '\\')) {
c = '/';
*changed = 1;
}
if (c == '/') { if (c == '/') {
/* Is there a directory back-reference? Yes, we /* Is there a directory back-reference? Yes, we
@ -1091,6 +1109,8 @@ int normalise_path_inplace(unsigned char *input, int input_len, int win) {
unsigned char *cd = d - 4; unsigned char *cd = d - 4;
int ccount = count - 4; int ccount = count - 4;
*changed = 1;
/* Go back until we reach the beginning or a forward slash. */ /* Go back until we reach the beginning or a forward slash. */
while ((ccount > 0)&&(*cd != '/')) { while ((ccount > 0)&&(*cd != '/')) {
ccount--; ccount--;
@ -1107,12 +1127,14 @@ int normalise_path_inplace(unsigned char *input, int input_len, int win) {
/* Ignore the last two bytes. */ /* Ignore the last two bytes. */
d -= 2; d -= 2;
count -= 2; count -= 2;
*changed = 1;
} else } else
/* Or are there just multiple occurences of forward slash? */ /* Or are there just multiple occurences of forward slash? */
if ((count >= 1)&&(*(d - 1) == '/')) { if ((count >= 1)&&(*(d - 1) == '/')) {
/* Ignore the last one byte. */ /* Ignore the last one byte. */
d--; d--;
count--; count--;
*changed = 1;
} }
} }

View File

@ -13,13 +13,13 @@
#include "modsecurity.h" #include "modsecurity.h"
int DSOLOCAL normalise_path_inplace(unsigned char *input, int len, int win); int DSOLOCAL normalise_path_inplace(unsigned char *input, int len, int win, int *changed);
int DSOLOCAL parse_boolean(const char *input); int DSOLOCAL parse_boolean(const char *input);
int DSOLOCAL parse_name_eq_value(apr_pool_t *mp, const char *input, char **name, char **value); int DSOLOCAL parse_name_eq_value(apr_pool_t *mp, const char *input, char **name, char **value);
char DSOLOCAL *url_encode(apr_pool_t *mp, char *input, unsigned int input_len); char DSOLOCAL *url_encode(apr_pool_t *mp, char *input, unsigned int input_len, int *changed);
char DSOLOCAL *strnurlencat(char *destination, char *source, unsigned int maxlen); char DSOLOCAL *strnurlencat(char *destination, char *source, unsigned int maxlen);
@ -68,9 +68,9 @@ char DSOLOCAL *_log_escape(apr_pool_t *p, const unsigned char *input,
int DSOLOCAL js_decode_nonstrict_inplace(unsigned char *input, long int input_len); int DSOLOCAL js_decode_nonstrict_inplace(unsigned char *input, long int input_len);
int DSOLOCAL urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_length); int DSOLOCAL urldecode_uni_nonstrict_inplace_ex(unsigned char *input, long int input_length, int * changed);
int DSOLOCAL urldecode_nonstrict_inplace_ex(unsigned char *input, long int input_length, int *invalid_count); int DSOLOCAL urldecode_nonstrict_inplace_ex(unsigned char *input, long int input_length, int *invalid_count, int *changed);
int DSOLOCAL html_entities_decode_inplace(apr_pool_t *mp, unsigned char *input, int len); int DSOLOCAL html_entities_decode_inplace(apr_pool_t *mp, unsigned char *input, int len);

View File

@ -279,12 +279,13 @@ static int msre_fn_urlDecode_execute(apr_pool_t *mptmp, unsigned char *input,
{ {
long int length; long int length;
int invalid_count; int invalid_count;
int changed;
length = urldecode_nonstrict_inplace_ex(input, input_len, &invalid_count); length = urldecode_nonstrict_inplace_ex(input, input_len, &invalid_count, &changed);
*rval = (char *)input; *rval = (char *)input;
*rval_len = length; *rval_len = length;
return (*rval_len == input_len ? 0 : 1); return changed;
} }
/* urlDecodeUni */ /* urlDecodeUni */
@ -293,12 +294,13 @@ static int msre_fn_urlDecodeUni_execute(apr_pool_t *mptmp, unsigned char *input,
long int input_len, char **rval, long int *rval_len) long int input_len, char **rval, long int *rval_len)
{ {
long int length; long int length;
int changed;
length = urldecode_uni_nonstrict_inplace_ex(input, input_len); length = urldecode_uni_nonstrict_inplace_ex(input, input_len, &changed);
*rval = (char *)input; *rval = (char *)input;
*rval_len = length; *rval_len = length;
return (*rval_len == input_len ? 0 : 1); return changed;
} }
/* urlEncode */ /* urlEncode */
@ -306,10 +308,12 @@ static int msre_fn_urlDecodeUni_execute(apr_pool_t *mptmp, unsigned char *input,
static int msre_fn_urlEncode_execute(apr_pool_t *mptmp, unsigned char *input, static int msre_fn_urlEncode_execute(apr_pool_t *mptmp, unsigned char *input,
long int input_len, char **rval, long int *rval_len) long int input_len, char **rval, long int *rval_len)
{ {
*rval = url_encode(mptmp, (char *)input, input_len); int changed;
*rval = url_encode(mptmp, (char *)input, input_len, &changed);
*rval_len = strlen(*rval); *rval_len = strlen(*rval);
return (*rval_len == input_len ? 0 : 1); return changed;
} }
/* base64Encode */ /* base64Encode */
@ -430,10 +434,12 @@ static int msre_fn_escapeSeqDecode_execute(apr_pool_t *mptmp, unsigned char *inp
static int msre_fn_normalisePath_execute(apr_pool_t *mptmp, unsigned char *input, static int msre_fn_normalisePath_execute(apr_pool_t *mptmp, unsigned char *input,
long int input_len, char **rval, long int *rval_len) long int input_len, char **rval, long int *rval_len)
{ {
*rval_len = normalise_path_inplace(input, input_len, 0); int changed;
*rval_len = normalise_path_inplace(input, input_len, 0, &changed);
*rval = (char *)input; *rval = (char *)input;
return (*rval_len == input_len ? 0 : 1); return changed;
} }
/* normalisePathWin */ /* normalisePathWin */
@ -441,10 +447,12 @@ static int msre_fn_normalisePath_execute(apr_pool_t *mptmp, unsigned char *input
static int msre_fn_normalisePathWin_execute(apr_pool_t *mptmp, unsigned char *input, static int msre_fn_normalisePathWin_execute(apr_pool_t *mptmp, unsigned char *input,
long int input_len, char **rval, long int *rval_len) long int input_len, char **rval, long int *rval_len)
{ {
*rval_len = normalise_path_inplace(input, input_len, 1); int changed;
*rval_len = normalise_path_inplace(input, input_len, 1, &changed);
*rval = (char *)input; *rval = (char *)input;
return (*rval_len == input_len ? 0 : 1); return changed;
} }
/* ------------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------------ */