Index: lib/src/base64.dart |
diff --git a/lib/src/base64.dart b/lib/src/base64.dart |
index 00ff11e84bd6cde58b3b23403f3cdaa05b6e47d3..976ee023b0fa62f0300c23e7a4a6c070ee5fe246 100644 |
--- a/lib/src/base64.dart |
+++ b/lib/src/base64.dart |
@@ -284,9 +284,6 @@ class Base64Decoder extends Converter<String, List<int>> { |
return new List<int>(0); |
} |
- bool expectedSafe = false; |
- bool expectedUnsafe = false; |
- |
int normalLength = 0; |
int i = 0; |
// Count '\r', '\n' and illegal characters, check if |
@@ -306,20 +303,6 @@ class Base64Decoder extends Converter<String, List<int>> { |
} else { |
throw new FormatException('Invalid character', input, i); |
} |
- } else if (input[i] == _URL_UNSAFE_CHARACTERS[0] || |
- input[i] == _URL_UNSAFE_CHARACTERS[1]) { |
- |
- if (expectedSafe) { |
- throw new FormatException('Unsafe character in URL-safe string', |
- input, i); |
- } |
- expectedUnsafe = true; |
- } else if (input[i] == _URL_SAFE_CHARACTERS[0] || |
- input[i] == _URL_SAFE_CHARACTERS[1]) { |
- if (expectedUnsafe) { |
- throw new FormatException('Invalid character', input, i); |
- } |
- expectedSafe = true; |
} |
if (c >= 0) normalLength++; |
i++; |
@@ -384,83 +367,33 @@ class _Base64DecoderSink extends ChunkedConversionSink<String> { |
final Base64Decoder _decoder = new Base64Decoder(); |
final ChunkedConversionSink<List<int>> _outSink; |
- String _buffer = ""; |
- bool _isSafe = false; |
- bool _isUnsafe = false; |
- int _expectPaddingCount = 3; |
+ String _unconverted = ""; |
_Base64DecoderSink(this._outSink); |
void add(String chunk) { |
if (chunk.isEmpty) return; |
- |
- int nextBufferLength = (chunk.length + _buffer.length) % 4; |
- |
- if (chunk.length >= _expectPaddingCount && |
- chunk.substring(0, _expectPaddingCount) == |
- _ENCODED_PAD.substring(3 - _expectPaddingCount, 3)) { |
- chunk = _PAD + chunk.substring(_expectPaddingCount); |
- _expectPaddingCount = 3; |
- } else if(chunk.length < _expectPaddingCount && |
- chunk == _ENCODED_PAD.substring( |
- 3 - _expectPaddingCount, |
- 3 - _expectPaddingCount + chunk.length)) { |
- _expectPaddingCount -= chunk.length; |
- chunk = ""; |
- } |
- |
- if (chunk.length > 1 && |
- chunk[chunk.length - 2] == _ENCODED_PAD[0] && |
- chunk[chunk.length - 1] == _ENCODED_PAD[1]) { |
- _expectPaddingCount = 1; |
- chunk = chunk.substring(0, chunk.length - 2); |
- } else if (!chunk.isEmpty && chunk[chunk.length - 1] == _ENCODED_PAD[0]) { |
- _expectPaddingCount = 2; |
- chunk = chunk.substring(0, chunk.length - 1); |
+ if (_unconverted.isNotEmpty) { |
+ chunk = _unconverted + chunk; |
} |
- |
chunk = chunk.replaceAll(_ENCODED_PAD, _PAD); |
- |
- if (chunk.length + _buffer.length >= 4) { |
- int remainder = chunk.length - nextBufferLength; |
- String decodable = _buffer + chunk.substring(0, remainder); |
- _buffer = chunk.substring(remainder); |
- |
- for (int i = 0;i < decodable.length; i++) { |
- if (decodable[i] == _URL_UNSAFE_CHARACTERS[0] || |
- decodable[i] == _URL_UNSAFE_CHARACTERS[1]) { |
- if (_isSafe) { |
- throw new FormatException('Unsafe character in URL-safe string', |
- decodable, i); |
- } |
- _isUnsafe = true; |
- } else if (decodable[i] == _URL_SAFE_CHARACTERS[0] || |
- decodable[i] == _URL_SAFE_CHARACTERS[1]) { |
- if (_isUnsafe) { |
- throw new FormatException('Invalid character', decodable, i); |
- } |
- _isSafe = true; |
- } |
- } |
- |
- _outSink.add(_decoder.convert(decodable)); |
- } else { |
- _buffer += chunk; |
+ int decodableLength = chunk.length; |
+ // If chunk ends in "%" or "%3", it may be a partial encoded pad. |
+ // If chunk is smaller than 4 characters, don't bother checking. |
+ if (chunk.length > 3 && |
+ chunk.contains(_ENCODED_PAD[0], chunk.length - 2)) { |
+ decodableLength = chunk.lastIndexOf(_ENCODED_PAD[0]); |
+ } |
+ decodableLength -= decodableLength % 4; |
+ _unconverted = chunk.substring(decodableLength); |
+ if (decodableLength > 0) { |
+ _outSink.add(_decoder.convert(chunk.substring(0, decodableLength))); |
} |
} |
void close() { |
- if (_expectPaddingCount == 0 && |
- _buffer.length == 3) { |
- _outSink.add(_buffer + _PAD); |
Bill Hesse
2015/08/04 16:33:33
This line was wrong, should have been .add(_decode
|
- } else if (_expectPaddingCount < 3 && |
- _buffer.length + 3 - _expectPaddingCount == 4) { |
- _outSink.add(_buffer + _ENCODED_PAD.substring(0, 3 - _expectPaddingCount)); |
- } else if (_expectPaddingCount != 3 || !_buffer.isEmpty) { |
- throw new FormatException( |
- "Size of Base 64 input must be a multiple of 4", |
- _buffer + _PAD.substring(0, 3 - _expectPaddingCount), |
- _buffer.length + 3 - _expectPaddingCount); |
+ if (_unconverted.isNotEmpty) { |
+ _outSink.add(_decoder.convert(_unconverted)); |
} |
_outSink.close(); |
} |