Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions changes-entries/sed-fixes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*) mod_sed: Reject malformed scripts which were accepted before, handle
bytes with the high bit set as delimiters and in y commands, filter a
request body read a line at a time, and drop the request Content-Length
once InputSed alters the body. [Joe Orton]
21 changes: 16 additions & 5 deletions modules/filters/mod_sed.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,15 +462,15 @@ static apr_status_t sed_request_filter(ap_filter_t *f,
apr_bucket_brigade *bbinp;
sed_expr_config *sed_cfg = &cfg->input;

if (mode != AP_MODE_READBYTES) {
return ap_get_brigade(f->next, bb, mode, block, readbytes);
}

if ((sed_cfg == NULL) || (sed_cfg->sed_cmds == NULL)) {
/* No sed expression */
return ap_get_brigade(f->next, bb, mode, block, readbytes);
}

if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) {
return APR_ENOTIMPL;
}

if (!ctx) {
if (!ap_is_initial_req(f->r)) {
ap_remove_input_filter(f);
Expand Down Expand Up @@ -510,10 +510,17 @@ static apr_status_t sed_request_filter(ap_filter_t *f,

/* read the bytes from next level filter */
apr_brigade_cleanup(bbinp);
status = ap_get_brigade(f->next, bbinp, mode, block, readbytes);
status = ap_get_brigade(f->next, bbinp, AP_MODE_READBYTES, block,
mode == AP_MODE_GETLINE ? AP_IOBUFSIZE
: readbytes);
if (status != APR_SUCCESS) {
return status;
}
/* The body passed on is not the length the request gave. Only
* drop the header after this read: HTTP_IN takes the length from
* it on the first.
*/
apr_table_unset(f->r->headers_in, "Content-Length");
for (b = APR_BRIGADE_FIRST(bbinp); b != APR_BRIGADE_SENTINEL(bbinp);
b = APR_BUCKET_NEXT(b)) {
const char *buf = NULL;
Expand Down Expand Up @@ -543,6 +550,10 @@ static apr_status_t sed_request_filter(ap_filter_t *f,
}
}

if (mode == AP_MODE_GETLINE) {
return apr_brigade_split_line(bb, ctx->bb, block, HUGE_STRING_LEN);
}

if (!APR_BRIGADE_EMPTY(ctx->bb)) {
apr_bucket *b = NULL;

Expand Down
32 changes: 26 additions & 6 deletions modules/filters/regexp.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ static int regerr(sed_commands_t *commands, int err)
comperr(commands, "First number exceeds second in \\{ \\}: %s");
break;

case 47:
comperr(commands, "\\{ \\} not allowed here: %s");
break;

case 49:
comperr(commands, "[ ] imbalance: %s");
break;
Expand All @@ -133,11 +137,11 @@ char *sed_compile(sed_commands_t *commands, sed_comp_args *compargs,
char *ep, char *endbuf, int seof)
{
int c;
int eof = seof;
int eof = (unsigned char)seof;
char *lastep;
int cclcnt;
char bracket[NBRA], *bracketp;
int closed;
int closed; /* bit n set once group n has been closed */
int neg;
int lc;
int i, cflg;
Expand Down Expand Up @@ -178,6 +182,7 @@ char *sed_compile(sed_commands_t *commands, sed_comp_args *compargs,
*ep++ = CDOT;
continue;

case '\0':
case '\n':
SEDCOMPILE_ERROR(36);
commands->cp = sp;
Expand Down Expand Up @@ -226,6 +231,8 @@ char *sed_compile(sed_commands_t *commands, sed_comp_args *compargs,
PLACE('-');
break;
}
if (c == '\0' || c == '\n')
SEDCOMPILE_ERROR(49);
if ((c & 0200) && iflag) {
iflag = 0;
if (&ep[32] >= endbuf)
Expand Down Expand Up @@ -281,12 +288,24 @@ char *sed_compile(sed_commands_t *commands, sed_comp_args *compargs,
SEDCOMPILE_ERROR(42);
*ep++ = CKET;
*ep++ = *--bracketp;
closed++;
closed |= 1 << *bracketp;
continue;

case '{':
if (lastep == (char *) 0)
goto defchar;
/* _advance() only implements a range on these, and
* not twice over. */
switch (*lastep & ~STAR) {
case CCHR:
case CDOT:
case CCL:
case CXCL:
case NCCL:
break;
default:
SEDCOMPILE_ERROR(47);
}
*lastep |= RNGE;
cflg = 0;
nlim:
Expand All @@ -297,9 +316,9 @@ char *sed_compile(sed_commands_t *commands, sed_comp_args *compargs,
i = 10 * i + c - '0';
else
SEDCOMPILE_ERROR(16);
if (i >= 255)
SEDCOMPILE_ERROR(11);
} while (((c = GETC()) != '\\') && (c != ','));
if (i >= 255)
SEDCOMPILE_ERROR(11);
*ep++ = i;
if (c == ',') {
if (cflg++)
Expand All @@ -320,6 +339,7 @@ char *sed_compile(sed_commands_t *commands, sed_comp_args *compargs,
SEDCOMPILE_ERROR(46);
continue;

case '\0':
case '\n':
SEDCOMPILE_ERROR(36);

Expand All @@ -329,7 +349,7 @@ char *sed_compile(sed_commands_t *commands, sed_comp_args *compargs,

default:
if (c >= '1' && c <= '9') {
if ((c -= '1') >= closed)
if (!(closed & (1 << (c -= '1'))))
SEDCOMPILE_ERROR(25);
*ep++ = CBACK;
*ep++ = c;
Expand Down
25 changes: 22 additions & 3 deletions modules/filters/sed0.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,10 @@ static int fcomp(sed_commands_t *commands, apr_file_t *fin)
case '{':
commands->rep->command = BCOM;
commands->rep->negfl = !(commands->rep->negfl);
if (commands->depth >= SED_DEPTH) {
command_errf(commands, SEDERR_TMOMES);
return -1;
}
commands->cmpend[commands->depth++] = &commands->rep->lb1;
commands->rep = alloc_reptr(commands);
commands->rep->ad1 = p;
Expand Down Expand Up @@ -528,6 +532,10 @@ static int fcomp(sed_commands_t *commands, apr_file_t *fin)

case 's':
commands->rep->command = SCOM;
if (*commands->cp == '\0') {
command_errf(commands, SEDERR_CGMES, commands->linebuf);
return -1;
}
commands->sseof = *commands->cp++;
commands->rep->re1 = p;
p = comple(commands, &compargs, (char *) 0, commands->rep->re1,
Expand Down Expand Up @@ -645,6 +653,10 @@ static int fcomp(sed_commands_t *commands, apr_file_t *fin)

case 'y':
commands->rep->command = YCOM;
if (*commands->cp == '\0') {
command_errf(commands, SEDERR_CGMES, commands->linebuf);
return -1;
}
commands->sseof = *commands->cp++;
commands->rep->re1 = p;
p = ycomp(commands, commands->rep->re1);
Expand Down Expand Up @@ -839,8 +851,13 @@ static char *address(sed_commands_t *commands, char *expbuf,
rcp = commands->cp;
lno = 0;

while(*rcp >= '0' && *rcp <= '9')
lno = lno*10 + *rcp++ - '0';
while(*rcp >= '0' && *rcp <= '9') {
if (lno > (APR_INT64_MAX - (*rcp - '0')) / 10) {
*status = APR_EGENERAL;
return NULL;
}
lno = lno*10 + (*rcp++ - '0');
}

if(rcp > commands->cp) {
if (expbuf > &commands->respace[RESIZE-3]) {
Expand Down Expand Up @@ -954,7 +971,7 @@ static char *ycomp(sed_commands_t *commands, char *expbuf)
sp++;
c = '\n';
}
cint = (int) c;
cint = (unsigned char) c;
if((ep[cint] = *tsp++) == '\\' && *tsp == 'n') {
ep[cint] = '\n';
tsp++;
Expand Down Expand Up @@ -996,6 +1013,8 @@ static char *comple(sed_commands_t *commands, sed_comp_args *compargs,
char *p;

p = sed_compile(commands, compargs, ep + 1, x3, x4);
if(p == NULL)
return NULL;
if(p == ep + 1)
return(ep);
*ep = compargs->circf;
Expand Down
Loading
Loading