summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Cook <tony@develop-help.com>2020-10-29 15:59:16 +1100
committerTony Cook <tony@develop-help.com>2020-10-29 15:59:16 +1100
commitfb072d007726c7ba114978a00f8f4f687ad7a55a (patch)
tree7900539979da1d88eca55303850d6f646de27d61
parentdfee93524089fd4fa372ce7e0dd15e2809b5c540 (diff)
downloadperl-fb072d007726c7ba114978a00f8f4f687ad7a55a.tar.gz
remove assertion that collation magic has data
This broke on some smokers where the locale collation data was broken in some way (and rejected by the collation setup code.) It also broke if collation magic was generated for an SV and then the SV was modified, freeing the collation data before the SV was destroyed.
-rw-r--r--mg.c9
-rw-r--r--t/run/locale.t25
2 files changed, 31 insertions, 3 deletions
diff --git a/mg.c b/mg.c
index d14b2eb88c..32d7732bc6 100644
--- a/mg.c
+++ b/mg.c
@@ -2669,9 +2669,12 @@ Perl_magic_freecollxfrm(pTHX_ SV *sv, MAGIC *mg)
/* Collate magic uses mg_len as a string length rather than a buffer
* length, so we need to free even with mg_len == 0: hence we can't
* rely on standard magic free handling */
- assert(mg->mg_type == PERL_MAGIC_collxfrm && mg->mg_len >= 0);
- Safefree(mg->mg_ptr);
- mg->mg_ptr = NULL;
+ if (mg->mg_len >= 0) {
+ assert(mg->mg_type == PERL_MAGIC_collxfrm);
+ Safefree(mg->mg_ptr);
+ mg->mg_ptr = NULL;
+ }
+
return 0;
}
#endif /* USE_LOCALE_COLLATE */
diff --git a/t/run/locale.t b/t/run/locale.t
index 78cfc2ff72..e072b63b0f 100644
--- a/t/run/locale.t
+++ b/t/run/locale.t
@@ -510,4 +510,29 @@ EOF
}
+SKIP:
+{
+ use locale;
+ # look for an english locale (so a < B, hopefully)
+ my ($en) = grep /^en_/, @locales;
+ POSIX::setlocale(LC_COLLATE, $en);
+ unless ("a" lt "B") {
+ skip "didn't find a suitable locale", 1;
+ }
+ fresh_perl_is(<<'EOF', "ok\n", { args => [ $en ] }, "check for failed assertion");
+use locale ':collate';
+use POSIX qw(setlocale LC_COLLATE);
+if (setlocale(LC_COLLATE, shift)) {
+ my $x = "a";
+ my $y = "B";
+ print $x lt $y ? "ok\n" : "not ok\n";
+ $x = "c"; # should empty the collxfrm magic but not remove it
+ # which the free code asserts on
+}
+else {
+ print "ok\n";
+}
+EOF
+}
+
done_testing();