blob: eb9e4d5035a14d1181efc6de52b2520d7d216cf6 [file]
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/diagnostic/diagnostic.dart' as diag;
import 'package:analyzer/src/error/listener.dart';
/// A verifier that checks for unsafe Unicode text.
/// See: https://nvd.nist.gov/vuln/detail/CVE-2021-22567
class UnicodeTextVerifier {
final DiagnosticReporter _diagnosticReporter;
UnicodeTextVerifier(this._diagnosticReporter);
void verify(CompilationUnit unit, String source) {
for (var offset = 0; offset < source.length; ++offset) {
var codeUnit = source.codeUnitAt(offset);
// U+202A, U+202B, U+202C, U+202D, U+202E, U+2066, U+2067, U+2068, U+2069.
if (0x202a <= codeUnit &&
codeUnit <= 0x2069 &&
(codeUnit <= 0x202e || 0x2066 <= codeUnit)) {
var node = unit.nodeCovering(offset: offset);
// If it's not in a string literal, we assume we're in a comment.
// This can potentially over-report on syntactically incorrect sources
// (where Unicode is outside a string or comment).
var diagnosticCode =
node is SimpleStringLiteral || node is InterpolationString
? diag.textDirectionCodePointInLiteral
: diag.textDirectionCodePointInComment;
var code = codeUnit.toRadixString(16).toUpperCase();
_diagnosticReporter.report(
diagnosticCode
.withArguments(codePoint: code)
.atOffset(offset: offset, length: 1),
);
}
}
}
}