Skip to content

Commit 60e9e3b

Browse files
committed
Clone R-O inversion list before modifying it
Unicode-defined properties are kept in inversion lists in read-only memory. Attempting to modify them will result in a segfault. The new Unicode 16.0 has some empty properties that need to be inverted before use in some cases. This situation has not occurred before. The inversion code that gets called presumes it has a modifiable SV and inverts in-place. This segfaults. Normally, no inversion is needed, and the properties are used as-is, and no problem arises. The solution here is to create a clone, and then invert that.
1 parent 6f00038 commit 60e9e3b

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

regcomp.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14764,6 +14764,14 @@ S_parse_uniprop_string(pTHX_
1476414764
/* Here, we are either done with the whole property name, if it was simple;
1476514765
* or are positioned just after the '=' if it is compound. */
1476614766

14767+
/* When we get a system inversion list, it is a global that needs to be
14768+
* preserved for later, and not coincidentally is in read-only memory.
14769+
* So we set this boolean to true once we've made a copy, and then we are
14770+
* free to modify the copy. It has to be set here way above where it is
14771+
* needed, in order to not run afoul of the C++ compiler saying goto's
14772+
* cross its initialization */
14773+
bool cloned = false;
14774+
1476714775
if (equals_pos >= 0) {
1476814776
assert(stricter == Not_Strict); /* We shouldn't have set this yet */
1476914777

@@ -15916,12 +15924,16 @@ S_parse_uniprop_string(pTHX_
1591615924
_invlist_union(prop_definition, pu_invlist,
1591715925
&expanded_prop_definition);
1591815926
prop_definition = expanded_prop_definition;
15927+
cloned = true;
1591915928
Perl_ck_warner_d(aTHX_ packWARN(WARN_EXPERIMENTAL__PRIVATE_USE), "The private_use feature is experimental");
1592015929
}
1592115930
}
1592215931
}
1592315932

1592415933
if (invert_return) {
15934+
if (! cloned) {
15935+
prop_definition = sv_2mortal(invlist_clone(prop_definition, NULL));
15936+
}
1592515937
_invlist_invert(prop_definition);
1592615938
}
1592715939
return prop_definition;

0 commit comments

Comments
 (0)