Conversation
Inside regex="all", field="${var}" saved PCRE2 match_data then
freed the expanded subject, so later $1 substitution was empty.
Transfer field_expanded ownership to save_field_data instead of
strdup+free. Add FST coverage for issue 3141 and mismatch paths.
Fixes signalwire#3141
Co-authored-by: Cursor <cursoragent@cursor.com>
Author
|
@andywolk, do you know who can review this PR? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Fixes #3141
parse_exteninmod_dialplan_xml.c)<condition regex="all">, a<regex field="${var}">that matches still leaves$1empty in the condition actions. The same expression works as a classic single<condition>, or whenfieldis a bare caller-profile name.Reproduction:
Root cause
switch_regex_perform()stores PCRE2 match offsets into the subject string. In theregex="all"loop,${var}is expanded into heapfield_expanded, then on a capturing match the code didsave_field_data = strdup(field_data)andswitch_safe_free(field_expanded)whilesave_match_datastill pointed at the original buffer. Laterswitch_perform_substitution()calledpcre2_substring_get_bynumber()on that dangling subject.The
strduponly servedstrlen(field_data)for buffer sizing; it did not rebind PCRE2's subject pointer.Solution
If the subject is the expanded heap buffer, transfer ownership to
save_field_data(field_expanded = NULL) so the later free offield_expandeddoes not run. Profile fields (no$) stillstrdupas before; those subjects live in the caller profile.Rejected:
PCRE2_COPY_MATCHED_SUBJECTinswitch_regex_perform— extra copy on every match site, larger blast radius.Impact and risk
regex="all|any|xor"actions that used$1withfield="${var}"now get the capture instead of an empty string. Match/fail of the condition itself is unchanged.Testing
mod_dialplan_xmlandtests/unit/switch_dialplan_xmlAction log(transfer to ), 1/2 failing)transfer to 7001234567)tests/unit/switch_dialplan_xml.cregex_all_var_field_keeps_captureclassic_var_field_keeps_captureregex_all_second_regex_fail_skips_actionregex_all_did_already_set_skips_actionclassic_var_field_mismatch_skips_action./tests/unit/switch_dialplan_xml— PASSED (5/5)Checklist
[module] summaryconvention