mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
fix: Swapcase must handle multibyte expansions (#7559)
`swapcase` used `to_ascii_lowercase` and uppercase to swap cases. This is fine for ASCII, but code points may expand into multiple bytes which leads to incorrect case swaps for some languages. The fix is to use `to_lowercase` and `to_uppercase` instead. Unfortunately, this leads to a realloc in `swapcase` when bytes are expanded. Part of #7526.
This commit is contained in:
1 parent
b682ec3bbe
commit
6493f9a31d
2 files changed
+5
-3
No files matched your search
@@ -1045,11 +1045,11 @@ impl PyStr {
|
||||
let mut swapped_str = Wtf8Buf::with_capacity(self.data.len());
|
||||
for c_orig in self.as_wtf8().code_points() {
|
||||
let c = c_orig.to_char_lossy();
|
||||
// to_uppercase returns an iterator, to_ascii_uppercase returns the char
|
||||
// to_uppercase returns an iterator because case changes may be multiple bytes
|
||||
if c.is_lowercase() {
|
||||
swapped_str.push_char(c.to_ascii_uppercase());
|
||||
swapped_str.extend(c.to_uppercase());
|
||||
} else if c.is_uppercase() {
|
||||
swapped_str.push_char(c.to_ascii_lowercase());
|
||||
swapped_str.extend(c.to_lowercase());
|
||||
} else {
|
||||
swapped_str.push(c_orig);
|
||||
}
|
||||
|
||||
@@ -235,6 +235,8 @@ assert "유니코드".isidentifier()
|
||||
assert not "😂".isidentifier()
|
||||
assert not "123".isidentifier()
|
||||
|
||||
assert "Σίσυφος".swapcase() == "σΊΣΥΦΟΣ"
|
||||
|
||||
# String Formatting
|
||||
assert "{} {}".format(1, 2) == "1 2"
|
||||
assert "{0} {1}".format(2, 3) == "2 3"
|
||||
|
||||
Reference in new issue
Block a user