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
2 changes: 2 additions & 0 deletions changes-entries/limit-xml-request-body.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*) core: Reject invalid non-numeric values of LimitXMLRequestBody, as
LimitRequestBody does. PR 69975
25 changes: 20 additions & 5 deletions server/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@

#include "mod_so.h" /* for ap_find_loaded_module_symbol */

#include <limits.h> /* for LONG_MAX */

#if defined(RLIMIT_CPU) || defined (RLIMIT_DATA) || defined (RLIMIT_VMEM) || defined(RLIMIT_AS) || defined (RLIMIT_NPROC)
#include "unixd.h"
#endif
Expand Down Expand Up @@ -3914,16 +3916,29 @@ static const char *set_limit_xml_req_body(cmd_parms *cmd, void *conf_,
const char *arg)
{
core_dir_config *conf = conf_;
apr_uint64_t max = AP_MAX_LIMIT_XML_BODY;
apr_off_t limit;
char *errp;

conf->limit_xml_body = atol(arg);
if (conf->limit_xml_body < 0)
if (APR_SUCCESS != apr_strtoff(&limit, arg, &errp, 10)) {
return "LimitXMLRequestBody argument is not parsable.";
}
if (*errp || limit < 0) {
return "LimitXMLRequestBody requires a non-negative integer.";
}

/* zero is AP_MAX_LIMIT_XML_BODY (implicitly) */
if ((apr_size_t)conf->limit_xml_body > AP_MAX_LIMIT_XML_BODY)
/* zero is AP_MAX_LIMIT_XML_BODY (implicitly), and limit_xml_body is
* a long, which is narrower than apr_size_t on some platforms.
*/
if (max > LONG_MAX) {
max = LONG_MAX;
}
if ((apr_uint64_t)limit > max) {
return apr_psprintf(cmd->pool, "LimitXMLRequestBody must not exceed "
"%" APR_SIZE_T_FMT, AP_MAX_LIMIT_XML_BODY);
"%" APR_UINT64_T_FMT, max);
}

conf->limit_xml_body = (long)limit;
return NULL;
}

Expand Down
41 changes: 41 additions & 0 deletions test/modules/core/test_010_limit_xml_request_body.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import os

import pytest

from pyhttpd.conf import HttpdConf


class TestLimitXMLRequestBody:

# have httpd parse the configuration, like "httpd -t" does
def check_config(self, env, value):
conf = HttpdConf(env)
conf.add(f"LimitXMLRequestBody {value}")
conf.add_vhost_test1()
conf.install()
return env.run([os.path.join(env.bin_dir, 'httpd'),
"-t", "-d", env.server_dir,
"-f", os.path.join(env.server_dir, 'conf', 'httpd.conf')])

@pytest.mark.parametrize("value", ["0", "1", "123", "1000000"])
def test_core_010_001(self, env, value):
r = self.check_config(env, value)
assert r.exit_code == 0, f"{r.stderr}"

# only a whole non-negative decimal number is a valid limit
@pytest.mark.parametrize("value", [
"abc123", "123abc", "123foo456", "-1", "1.5", "0x10", "+", "-",
])
def test_core_010_002(self, env, value):
r = self.check_config(env, value)
assert r.exit_code != 0, f"{value} was accepted"
assert "LimitXMLRequestBody requires a non-negative integer" in r.stderr

# more than can be stored or than the directive permits
@pytest.mark.parametrize("value", [
"9223372036854775807", "9223372036854775808", "9" * 40,
])
def test_core_010_003(self, env, value):
r = self.check_config(env, value)
assert r.exit_code != 0, f"{value} was accepted"
assert "LimitXMLRequestBody" in r.stderr
Loading