Skip to content

Conversation

@Renzo-Olivares
Copy link
Contributor

This PR addresses a concern brought up in #107127 where the creation of a TextEditingDelta through the fromJson method will fail silently when given bad text bounds (delta range, selection, or composing region). A similar issue was addressed for non-delta text input in #104711 and this change adds the same text bound checks to delta text input.

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • All existing and new tests are passing.

@flutter-dashboard flutter-dashboard bot added a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. labels Jul 11, 2022
/// replacement string.
// Replaces a range of text in the original string with the text given in the
// replacement string.
String _replace(String originalText, String replacementText, int start, int end) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

// Verify that the given range is within the text.
bool _textRangeIsValid(TextRange range, String text) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

preferably the function name needs a debug prefix.


// Verify that the given range is within the text.
bool _textRangeIsValid(TextRange range, String text) {
if (range.start == -1 && range.end == -1) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: !range.isInvalid instead. This should be consistent with the isValid definition I think?

return true;
}
assert(range.start >= 0 && range.start <= text.length,
'Range start ${range.start} is out of text of length ${text.length}');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe print the entire range here to give more context? The end could be OOB too.

Copy link
Contributor

@LongCatIsLooong LongCatIsLooong Jul 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: looking at the callers of this function, it's a bit difficult to tell what kind of TextRange is OOB, the only thing that can help developers trace that down is the line number in the stacktrace.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated this a bit, to make it more obvious what range was failing (delta/selection/composing).

// Verify the error message in parts because Web formats the message
// differently from others.
expect(record[0].exception.toString(), matches(RegExp(r'\brange.start >= 0 && range.start <= text.length\b')));
expect(record[0].exception.toString(), matches(RegExp(r'\bRange start 3 is out of text of length 1\b')));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, what's the difference?

Copy link
Contributor Author

@Renzo-Olivares Renzo-Olivares Jul 12, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slight formatting difference.

Command line:

    Actual: '\'package:flutter/src/services/text_editing_delta.dart\': Failed assertion: line 140 pos 14: \'_debugTextRangeIsValid(newSelection, oldText)\': The selection range: TextSelection.collapsed(offset: 3, affinity: TextAffinity.downstream, isDirectional: false) is not within the bounds of text: 1 of length: 1'

Web:

    Actual: 'Assertion failed: file:///Users/roliv/flutter/packages/flutter/lib/src/services/text_editing_delta.dart:140:14\n'
              '_debugTextRangeIsValid(newSelection, oldText)\n'
              '"The selection range: TextSelection.collapsed(offset: 3, affinity: TextAffinity.downstream, isDirectional: false) is not within the bounds of text: 1 of length: 1"'

prevents me from just using endsWith()

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Comment on lines 40 to 44
if ((range.start >= 0 && range.start <= text.length) && (range.end >= 0 && range.end <= text.length)) {
return true;
}

return false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: You could also directly return the expression in the if.

);

if (isNonTextUpdate) {
assert(_debugTextRangeIsValid(newSelection, oldText), 'TextEditingDelta.fromJSON failed, the selection range: $newSelection is not within the bounds of text: $oldText of length: ${oldText.length}');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I think you could just start the error message at "the selection range..." if you want because the first part is redundant. The stacktrace will point to TextEditingDelta.fromJSON and "failed" is also obvious.

@Renzo-Olivares Renzo-Olivares merged commit 329afbe into flutter:master Jul 12, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jul 13, 2022
engine-flutter-autoroll added a commit to engine-flutter-autoroll/plugins that referenced this pull request Jul 13, 2022
camsim99 pushed a commit to camsim99/flutter that referenced this pull request Aug 10, 2022
…alid (flutter#107426)

* Make deltas fail loudly

* analyzer fixes

* empty

* updates

* Analyzer fixes

* Make it more obvious what kind of TextRange is failing and where

* update tests

* Add tests for concrete TextEditinDelta apply method

* trailing spaces

* address nits

* fix analyzer

Co-authored-by: Renzo Olivares <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants