Check that selection offset/length is valid in Extract Local refactoring.
R=brianwilkerson@google.com
Bug: https://github.com/dart-lang/sdk/issues/34475
Change-Id: Id2b44494a8464000180a8ca93cfcc770b256f59f
Reviewed-on: https://dart-review.googlesource.com/76063
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index 41a4803..e2ade9f 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -227,6 +227,15 @@
* location of this [Expression] in AST allows extracting.
*/
RefactoringStatus _checkSelection() {
+ if (selectionOffset <= 0) {
+ return new RefactoringStatus.fatal(
+ 'The selection offset must be greater than zero.');
+ }
+ if (selectionOffset + selectionLength >= resolveResult.content.length) {
+ return new RefactoringStatus.fatal(
+ 'The selection end offset must be less then the length of the file.');
+ }
+
String selectionStr;
// exclude whitespaces
{
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index df1e893c..fd048d2 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
@@ -52,6 +52,28 @@
expectedMessage: "The name 'res' is already used in the scope.");
}
+ test_checkInitialCondition_false_outOfRange_length() async {
+ await indexTestUnit('''
+main() {
+ print(1 + 2);
+}
+''');
+ _createRefactoring(0, 1 << 20);
+ RefactoringStatus status = await refactoring.checkAllConditions();
+ assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL);
+ }
+
+ test_checkInitialCondition_outOfRange_offset() async {
+ await indexTestUnit('''
+main() {
+ print(1 + 2);
+}
+''');
+ _createRefactoring(-10, 20);
+ RefactoringStatus status = await refactoring.checkAllConditions();
+ assertRefactoringStatus(status, RefactoringProblemSeverity.FATAL);
+ }
+
test_checkInitialConditions_assignmentLeftHandSize() async {
await indexTestUnit('''
main() {
@@ -68,8 +90,7 @@
test_checkInitialConditions_namePartOfDeclaration_function() async {
await indexTestUnit('''
-main() {
-}
+void main() {}
''');
_createRefactoringWithSuffix('main', '()');
// check conditions
@@ -695,6 +716,24 @@
expect(refactoring.names, unorderedEquals(['helloBob', 'bob']));
}
+ test_isAvailable_false_notPartOfFunction() async {
+ await indexTestUnit('''
+var v = 1 + 2;
+''');
+ _createRefactoringForString('1 + 2');
+ expect(refactoring.isAvailable(), isFalse);
+ }
+
+ test_isAvailable_true() async {
+ await indexTestUnit('''
+main() {
+ print(1 + 2);
+}
+''');
+ _createRefactoringForString('1 + 2');
+ expect(refactoring.isAvailable(), isTrue);
+ }
+
test_occurrences_differentVariable() async {
await indexTestUnit('''
main() {