Skip to content

Commit 185010b

Browse files
committed
locale.c: Don't do asymmetric back out on failure
This fixes #23519 When something goes wrong doing locale-aware string collation, the code attempts to carry on as well as can be expected. Prior to this commit the backout code was asymmetric, trying to undo things that had not been done. This happened when the failure was early on. In the case of this ticket, the platform has a defective locale that was detectable before getting very far along. The solution adopted here is to jump to a different label for those early failures that does less backout than for later failures.
1 parent ef39fd6 commit 185010b

File tree

1 file changed

+10
-12
lines changed

1 file changed

+10
-12
lines changed

locale.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9663,7 +9663,7 @@ Perl_mem_collxfrm_(pTHX_ const char *input_string,
96639663
if (PL_collxfrm_base != 0) { /* bad collation => skip */
96649664
DEBUG_L(PerlIO_printf(Perl_debug_log,
96659665
"mem_collxfrm_: locale's collation is defective\n"));
9666-
goto bad;
9666+
goto bad_no_strxfrm;
96679667
}
96689668

96699669
/* (mult, base) == (0,0) means we need to calculate mult and base
@@ -9789,7 +9789,7 @@ Perl_mem_collxfrm_(pTHX_ const char *input_string,
97899789
DEBUG_L(PerlIO_printf(Perl_debug_log,
97909790
"mem_collxfrm_: Couldn't find any character to replace"
97919791
" embedded NULs in locale %s with", PL_collation_name));
9792-
goto bad;
9792+
goto bad_no_strxfrm;
97939793
}
97949794

97959795
DEBUG_L(PerlIO_printf(Perl_debug_log,
@@ -9930,7 +9930,7 @@ Perl_mem_collxfrm_(pTHX_ const char *input_string,
99309930
"mem_collxfrm_: Couldn't find any character to"
99319931
" replace above-Latin1 chars in locale %s with",
99329932
PL_collation_name));
9933-
goto bad;
9933+
goto bad_no_strxfrm;
99349934
}
99359935

99369936
DEBUG_L(PerlIO_printf(Perl_debug_log,
@@ -10090,7 +10090,7 @@ Perl_mem_collxfrm_(pTHX_ const char *input_string,
1009010090
if (UNLIKELY(! xbuf)) {
1009110091
DEBUG_L(PerlIO_printf(Perl_debug_log,
1009210092
"mem_collxfrm_: Couldn't malloc %zu bytes\n", xAlloc));
10093-
goto bad;
10093+
goto bad_no_strxfrm;
1009410094
}
1009510095

1009610096
/* Store the collation id */
@@ -10119,7 +10119,6 @@ Perl_mem_collxfrm_(pTHX_ const char *input_string,
1011910119
STMT_START { \
1012010120
if (constructed_locale != (locale_t) 0) \
1012110121
freelocale(constructed_locale); \
10122-
CLEANUP_NON_STRXFRM; \
1012310122
} STMT_END
1012410123
# else
1012510124
# define my_strxfrm(dest, src, n) strxfrm(dest, src, n)
@@ -10128,12 +10127,7 @@ Perl_mem_collxfrm_(pTHX_ const char *input_string,
1012810127
orig_CTYPE_locale = toggle_locale_c(LC_CTYPE, PL_collation_name);
1012910128

1013010129
# define CLEANUP_STRXFRM \
10131-
STMT_START { \
10132-
restore_toggled_locale_c(LC_CTYPE, orig_CTYPE_locale); \
10133-
CLEANUP_NON_STRXFRM; \
10134-
} STMT_END
10135-
# else
10136-
# define CLEANUP_STRXFRM CLEANUP_NON_STRXFRM
10130+
restore_toggled_locale_c(LC_CTYPE, orig_CTYPE_locale);
1013710131
# endif
1013810132
# endif
1013910133

@@ -10275,6 +10269,7 @@ Perl_mem_collxfrm_(pTHX_ const char *input_string,
1027510269

1027610270
DEBUG_L(print_collxfrm_input_and_return(s, s + len, xbuf, *xlen, utf8));
1027710271
CLEANUP_STRXFRM;
10272+
CLEANUP_NON_STRXFRM;
1027810273

1027910274
/* Free up unneeded space; retain enough for trailing NUL */
1028010275
Renew(xbuf, COLLXFRM_HDR_LEN + *xlen + 1, char);
@@ -10286,9 +10281,12 @@ Perl_mem_collxfrm_(pTHX_ const char *input_string,
1028610281
DEBUG_L(print_collxfrm_input_and_return(s, s + len, NULL, 0, utf8));
1028710282
CLEANUP_STRXFRM;
1028810283

10284+
bad_no_strxfrm: /* Found a problem before strxfrm() got called */
10285+
DEBUG_L(print_collxfrm_input_and_return(s, s + len, NULL, 0, utf8));
10286+
1028910287
Safefree(xbuf);
1029010288
*xlen = 0;
10291-
10289+
CLEANUP_NON_STRXFRM;
1029210290
return NULL;
1029310291
}
1029410292

0 commit comments

Comments
 (0)