Skip to content

<regex>: regex_search() throws regex_error(error_complexity) with an unwisely written pattern #6452

Description

Related to #6347.

This was reported by the compiler back-end team, reduced from an important test case. This was previously accepted (MSVC Build Tools 14.50 and earlier) with regex_search() returning false (the line has been deliberately changed to contain total_WOOF_pushes so total_heap_pushes won't be found). Now with MSVC Build Tools 14.51 and later, it is rejected with a complexity exception.

D:\GitHub\STL\out\x64>type regex_repro.cpp
#include <print>
#include <regex>
#include <string>
using namespace std;

int main() {
    const regex rx(R"(.*total_heap_pushes\s*:\s*(\d+) .*)");

    const string line = "Router Stats: total_nets_routed: 113175 "
                        "total_connections_routed: 437370 "
                        "total_WOOF_pushes: 313639277 "
                        "total_heap_pops: 35866777 "
                        "total_internal_heap_pushes: 0 "
                        "total_internal_heap_pops: 0 "
                        "total_external_heap_pushes: 313639277 "
                        "total_external_heap_pops: 35866777 "
                        "total_external_SOURCE_pushes: 379297 "
                        "total_external_SOURCE_pops: 379297 "
                        "total_internal_SOURCE_pushes: 0 "
                        "total_internal_SOURCE_pops: 0 "
                        "rt_node_SOURCE_pushes: 379297 "
                        "rt_node_SOURCE_high_fanout_pushes: 3797 "
                        "rt_node_SOURCE_entire_tree_pushes: 375500 "
                        "total_external_SINK_pushes: 3488243 "
                        "total_external_SINK_pops: 3260194 "
                        "total_internal_SINK_pushes: 0 "
                        "total_internal_SINK_pops: 0 "
                        "rt_node_SINK_pushes: 0 "
                        "rt_node_SINK_high_fanout_pushes: 0 "
                        "rt_node_SINK_entire_tree_pushes: 0 "
                        "total_external_IPIN_pushes: 5501600 "
                        "total_external_IPIN_pops: 3585046 "
                        "total_internal_IPIN_pushes: 0 "
                        "total_internal_IPIN_pops: 0 "
                        "rt_node_IPIN_pushes: 0 "
                        "rt_node_IPIN_high_fanout_pushes: 0 "
                        "rt_node_IPIN_entire_tree_pushes: 0 "
                        "total_external_OPIN_pushes: 14718566 "
                        "total_external_OPIN_pops: 8542877 "
                        "total_internal_OPIN_pushes: 0 "
                        "total_internal_OPIN_pops: 0 "
                        "rt_node_OPIN_pushes: 342094 "
                        "rt_node_OPIN_high_fanout_pushes: 8165 "
                        "rt_node_OPIN_entire_tree_pushes: 333929 "
                        "total_external_CHANX_pushes: 143852606 "
                        "total_external_CHANX_pops: 10396956 "
                        "total_internal_CHANX_pushes: 0 "
                        "total_internal_CHANX_pops: 0 "
                        "rt_node_CHANX_pushes: 2213020 "
                        "rt_node_CHANX_high_fanout_pushes: 482509 "
                        "rt_node_CHANX_entire_tree_pushes: 1730511 "
                        "total_external_CHANY_pushes: 145698965 "
                        "total_external_CHANY_pops: 9702407 "
                        "total_internal_CHANY_pushes: 0 "
                        "total_internal_CHANY_pops: 0 "
                        "rt_node_CHANY_pushes: 2442282 "
                        "rt_node_CHANY_high_fanout_pushes: 589528 "
                        "rt_node_CHANY_entire_tree_pushes: 1852754 "
                        "total_number_of_adding_all_rt: 8814821 "
                        "total_number_of_adding_high_fanout_rt: 62167 "
                        "total_number_of_adding_all_rt_from_calling_high_fanout_rt: 41981 ";

    try {
        const bool found = regex_search(line, rx);
        println("regex_search() returned {}.", found);
    } catch (const regex_error& re) {
        println("{}", re.what());
    }
}
D:\GitHub\STL\out\x64>cl /EHsc /nologo /W4 /std:c++latest /MTd /Od regex_repro.cpp
regex_repro.cpp

D:\GitHub\STL\out\x64>regex_repro
regex_error(error_complexity): The complexity of an attempted match against a regular expression exceeded a pre-set level.

In this case, telling the user to fix their regex is not especially feasible. (The initial ".*" used with a regex_search() is bad and should feel bad.) I would like to retune the limits to accept this case, while still guarding against severely pathological regex DoS scenarios.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingregexmeow is a substring of homeowner

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions