| // Copyright 2014 The Flutter Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // Hide the original utf8 [Codec] so that we can export our own implementation | |
| // which adds additional error handling. | |
| import 'dart:convert' hide utf8; | |
| import 'dart:convert' as cnv show Utf8Decoder, utf8; | |
| import 'package:meta/meta.dart'; | |
| import 'base/common.dart'; | |
| export 'dart:convert' hide Utf8Codec, Utf8Decoder, utf8; | |
| /// The original utf8 encoding for testing overrides only. | |
| /// | |
| /// Attempting to use the flutter tool utf8 decoder will surface an analyzer | |
| /// warning that overrides cannot change the default value of a named | |
| /// parameter. | |
| @visibleForTesting | |
| const Encoding utf8ForTesting = cnv.utf8; | |
| /// A [Codec] which reports malformed bytes when decoding. | |
| /// | |
| /// Occasionally people end up in a situation where we try to decode bytes | |
| /// that aren't UTF-8 and we're not quite sure how this is happening. | |
| /// This tells people to report a bug when they see this. | |
| class Utf8Codec extends Encoding { | |
| const Utf8Codec({this.reportErrors = true}); | |
| final bool reportErrors; | |
| @override | |
| Converter<List<int>, String> get decoder => reportErrors | |
| ? const Utf8Decoder() | |
| : const Utf8Decoder(reportErrors: false); | |
| @override | |
| Converter<String, List<int>> get encoder => cnv.utf8.encoder; | |
| @override | |
| String get name => cnv.utf8.name; | |
| } | |
| const Encoding utf8 = Utf8Codec(); | |
| class Utf8Decoder extends Converter<List<int>, String> { | |
| const Utf8Decoder({this.reportErrors = true}); | |
| static const cnv.Utf8Decoder _systemDecoder = | |
| cnv.Utf8Decoder(allowMalformed: true); | |
| final bool reportErrors; | |
| @override | |
| String convert(List<int> input, [int start = 0, int? end]) { | |
| final String result = _systemDecoder.convert(input, start, end); | |
| // Finding a Unicode replacement character indicates that the input | |
| // was malformed. | |
| if (reportErrors && result.contains('\u{FFFD}')) { | |
| throwToolExit( | |
| 'Bad UTF-8 encoding (U+FFFD; REPLACEMENT CHARACTER) found while decoding string: $result. ' | |
| 'The Flutter team would greatly appreciate if you could file a bug explaining ' | |
| 'exactly what you were doing when this happened:\n' | |
| 'https://github.com/flutter/flutter/issues/new/choose\n' | |
| 'The source bytes were:\n$input\n\n'); | |
| } | |
| return result; | |
| } | |
| @override | |
| ByteConversionSink startChunkedConversion(Sink<String> sink) => | |
| _systemDecoder.startChunkedConversion(sink); | |
| @override | |
| Stream<String> bind(Stream<List<int>> stream) => _systemDecoder.bind(stream); | |
| @override | |
| Converter<List<int>, T> fuse<T>(Converter<String, T> other) => | |
| _systemDecoder.fuse(other); | |
| } |