#include <unistd.h>
#endif
+#define INVALID_CHAR -2
+
extern module AP_MODULE_DECLARE_DATA http_module;
static long get_chunk_size(char *);
http_ctx_t *ctx = f->ctx;
apr_status_t rv;
apr_off_t totalread;
+ apr_status_t http_error = HTTP_REQUEST_ENTITY_TOO_LARGE;
/* just get out of the way of things we don't want. */
if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) {
}
if (rv == APR_SUCCESS) {
ctx->remaining = get_chunk_size(ctx->chunk_ln);
+ if (ctx->remaining == INVALID_CHAR) {
+ rv = APR_EGENERAL;
+ http_error = HTTP_SERVICE_UNAVAILABLE;
+ }
}
}
apr_brigade_cleanup(bb);
if (rv != APR_SUCCESS || ctx->remaining < 0) {
ctx->remaining = 0; /* Reset it in case we have to
* come back here later */
- return bail_out_on_error(ctx, f, HTTP_REQUEST_ENTITY_TOO_LARGE);
+ return bail_out_on_error(ctx, f, http_error);
}
if (!ctx->remaining) {
case BODY_CHUNK_PART:
{
apr_bucket_brigade *bb;
- apr_status_t http_error = HTTP_REQUEST_ENTITY_TOO_LARGE;
bb = ctx->bb;
apr_brigade_cleanup(bb);
return rv;
}
if (rv == APR_SUCCESS) {
- /*
- * Wait a sec, that's a blank line or it starts
- * with an invalid character! Oh no.
- */
- if (!apr_isxdigit(*(ctx->chunk_ln))) {
+ ctx->remaining = get_chunk_size(ctx->chunk_ln);
+ if (ctx->remaining == INVALID_CHAR) {
rv = APR_EGENERAL;
http_error = HTTP_SERVICE_UNAVAILABLE;
}
- else {
- ctx->remaining = get_chunk_size(ctx->chunk_ln);
- }
}
}
apr_brigade_cleanup(bb);
ap_xlate_proto_from_ascii(b, strlen(b));
+ if (!apr_isxdigit(*b)) {
+ /*
+ * Detect invalid character at beginning. This also works for empty
+ * chunk size lines.
+ */
+ return INVALID_CHAR;
+ }
/* Skip leading zeros */
while (*b == '0') {
++b;