diff --git a/src/proxy/http/remap/RemapConfig.cc b/src/proxy/http/remap/RemapConfig.cc index bb7bc915f5e..bac5253a675 100644 --- a/src/proxy/http/remap/RemapConfig.cc +++ b/src/proxy/http/remap/RemapConfig.cc @@ -1047,6 +1047,11 @@ process_regex_mapping_config(const char *from_host_lower, url_mapping *new_mappi Warning("Substitution id [%c] has no corresponding capture pattern in regex [%s]", to_host[i + 1], from_host_lower); goto lFail; } + if (reg_map->n_substitutions >= UrlRewrite::MAX_REGEX_SUBS) { + Warning("too many substitution markers in regex remap target [%.*s], saw %d markers, max %d", to_host_len, to_host.data(), + reg_map->n_substitutions + 1, UrlRewrite::MAX_REGEX_SUBS); + goto lFail; + } reg_map->substitution_markers[reg_map->n_substitutions] = i; reg_map->substitution_ids[reg_map->n_substitutions] = substitution_id; ++reg_map->n_substitutions; diff --git a/src/proxy/http/remap/unit-tests/test_RemapRules.cc b/src/proxy/http/remap/unit-tests/test_RemapRules.cc index 012e8b55bd7..f51e39d0dd6 100644 --- a/src/proxy/http/remap/unit-tests/test_RemapRules.cc +++ b/src/proxy/http/remap/unit-tests/test_RemapRules.cc @@ -37,6 +37,7 @@ #include "tscore/BaseLogFile.h" #include "tsutil/PostScript.h" +#include #include #include @@ -122,6 +123,49 @@ SCENARIO("Parsing ACL named filters", "[proxy][remap]") } } +std::string +make_regex_remap_with_substitutions(int n_substitutions) +{ + std::string substitutions; + + substitutions.reserve(n_substitutions * 2); + for (int i = 0; i < n_substitutions; ++i) { + substitutions += "$0"; + } + + return "regex_map http://([^.]+)\\.example\\.com/ http://" + substitutions + ".origin.example.com/\n"; +} + +SCENARIO("Parsing regex remap substitutions", "[proxy][remap]") +{ + GIVEN("A regex remap target with the maximum number of substitution markers") + { + std::unique_ptr urlrw = std::make_unique(); + + auto cpath = write_test_remap(make_regex_remap_with_substitutions(UrlRewrite::MAX_REGEX_SUBS), "max-regex-substitutions"); + ts::PostScript file_cleanup([&]() -> void { std::filesystem::remove(cpath.c_str()); }); + + THEN("the remap parse succeeds") + { + REQUIRE(urlrw->BuildTable(cpath.c_str()) == TS_SUCCESS); + } + } + + GIVEN("A regex remap target with too many substitution markers") + { + std::unique_ptr urlrw = std::make_unique(); + + auto cpath = + write_test_remap(make_regex_remap_with_substitutions(UrlRewrite::MAX_REGEX_SUBS + 1), "too-many-regex-substitutions"); + ts::PostScript file_cleanup([&]() -> void { std::filesystem::remove(cpath.c_str()); }); + + THEN("the remap parse fails") + { + REQUIRE(urlrw->BuildTable(cpath.c_str()) != TS_SUCCESS); + } + } +} + struct EasyURL { URL url; HdrHeap *heap;