blob: d6691f5cc206dab37988fae6e04e56ac557de44d [file] [log] [blame]
// Copyright (c) 2023, 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.
/// This library gives some backstops to make sure that arbitrary string
/// exceptions generated by something that might be sent to the crash reporting
/// framework do not contain PII. The regular expressions here are
/// intentionally broad to make sure they get everything, possibly at the
/// expense of readability for the error message. Use care when reducing
/// their scope.
library;
/// Contain an ordered list of regular expressions to be applied in sequence
/// with [applyTo] to a string, with any matches being substituted with
/// [substitution]. While a single regular expression could be
/// used in place of this class, this is intending to make the regular
/// expressions being applied more comprehensible to non-expert regular
/// expression authors and to make it very simple to add or remove individual
/// cases.
class _RegExpList {
/// This list should be usually be ordered from more specific to more general
/// cases in the event the regular expressions overlap.
final List<RegExp> _regExps;
final String substitution;
_RegExpList(List<String> uncompiledRegexps, this.substitution)
: _regExps = uncompiledRegexps.map((s) => RegExp(s)).toList();
String applyTo(String input) => _regExps.fold(
input, (previousInput, r) => previousInput.replaceAll(r, substitution));
}
/// An ordered list of regular expressions to be substituted out and replaced
/// with a generic `<path>` string. To be applied in sequence.
/// The regular expressions here intentionally eat all characters after a
/// path is identified, with the hope of catching all potential complex
/// pathnames and assuming that most error messages will have any paths last.
/// For example: `throw Exception('error in: $fileName)`
final _piiPathRegexps = _RegExpList([
// C:\Some\Things\Including Spaces\Too
r'\w:\\.*',
// \\Windows\Shares\Look\Like This
r'\\\\\S+\\.*',
// ..\StartsWithDots\Windows Path
r'[.]+\\+\S*\\.*',
// A\Relative\Windows Path
r'\b\S+\\.*',
// ../StartsWithDots/Unix path
r'[.]+/\S*/.*',
// /AUnix/path
r'/(\S|[.])+/.*',
// a/unix\ relative path/possibly-containing-strange-characters
r'\b(\S|[.])+/.*',
], '<path>');
/// An ordered list of regular expressions to be substituted out and replaced
/// with a generic `<filename>` string. To be applied after
/// all paths from [_piiPathRegexps] are applied. This is somewhat less
/// all-encompassing than the path finder, above, just to try and grab things
/// that could be file names but without being quite so greedy or depending
/// on the presence of path separators.
final _piiFileRegexps = _RegExpList([
// foo.dart
// something.exe
// code.js
r'\b\S+[.]\w{1,4}\b',
], '<filename>');
/// Attempt to remove things that look like they could be PII from the
/// given [message].
/// Returns the filtered string.
/// Not suitable for pre-scrubbed strings that intentionally include things
/// that look like filenames.
String filterPiiFromErrorMessage(String message) => [
_piiPathRegexps,
_piiFileRegexps,
].fold(message, (previousMessage, r) => r.applyTo(previousMessage));