core: use char slicing instead of byte slicing (#17686)

* core: use char slicing instead of byte slicing (close #17675)

Fix a panic which can occur when pasting non-ASCII characters into a
textbox. Use char slicing instead of byte slicing when limiting the
length of the text being pasted in. This fixes issue #17675.

* tests: Add test for issue 17675

* tests: fix incorrect output in test "avm2/issue_17675"

The output expected the text to be pasted at the end, even though it
will be pasted at the beginning, which is the correct behaviour here.

* core: use char length instead of byte length

Use char length instead of byte length for text pasting and setting the
current text selection.

* core: use WString for limiting text length and pasting text

Switch to WString from String for limiting text length and pasting text.
Done to ensure this code won't need to be fixed in the future. This does
not work properly with certain characters (e.g., 4-byte UTF-8 chars),
but that's due to how WString handles those characters.

* lint: fix clippy errors

---------

Co-authored-by: oad <48562304+oaddyk@users.noreply.github.com>
Co-authored-by: Adrian Wielgosik <adrian.wielgosik@gmail.com>
This commit is contained in:
oad 2024-08-30 23:49:50 +02:00 committed by GitHub
parent 76ee654812
commit 9505da8438
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 30 additions and 8 deletions

View File

@ -1493,19 +1493,16 @@ impl<'gc> EditText<'gc> {
break 'paste;
}
let mut text = self.0.read().restrict.filter_allowed(&text);
let text = self.0.read().restrict.filter_allowed(&text);
let text = WString::from_utf8(&text);
let mut text = text.as_wstr();
if text.len() > self.available_chars() && self.available_chars() > 0 {
text = text[0..self.available_chars()].to_owned();
text = &text[0..self.available_chars()];
}
if text.len() <= self.available_chars() {
self.replace_text(
selection.start(),
selection.end(),
&WString::from_utf8(&text),
context,
);
self.replace_text(selection.start(), selection.end(), text, context);
let new_pos = selection.start() + text.len();
if is_selectable {
self.set_selection(

View File

@ -0,0 +1,19 @@
// compiled with mxmlc
package {
import flash.display.MovieClip;
import flash.text.TextField;
public class Test extends MovieClip {
public function Test(){
var tf = new TextField();
tf.text = "text";
tf.maxChars = 5;
tf.type = "input";
addChild(tf);
tf.addEventListener("change", function(){
trace(tf.text);
});
stage.focus = tf;
}
}
}

View File

@ -0,0 +1,4 @@
[
{ "type": "SetClipboardText", "text": "兔兔兔" },
{ "type": "TextControl", "code": "Paste" }
]

View File

@ -0,0 +1 @@
兔text

Binary file not shown.

View File

@ -0,0 +1 @@
num_frames = 1