Prepare 0.5.5 release
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 094c649..53fe868 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.5.5
+
+- Fix a crash when pausing a subscription to `TarEntry.contents` right before
+ it ends.
+
## 0.5.4
- Fix generating corrupt tar files when adding lots of entries at very high
diff --git a/README.md b/README.md
index 2730a58..8d5a334 100644
--- a/README.md
+++ b/README.md
@@ -51,6 +51,10 @@
__Warning__: Since the reader is backed by a single stream, concurrent calls to
`read` are not allowed! Similarly, if you're reading from an entry's `contents`,
make sure to fully drain the stream before calling `read()` again.
+_Not_ subscribing to `contents` before calling `moveNext()` is acceptable too.
+In this case, the reader will implicitly drain the stream.
+The reader detects concurrency misuses and will throw an error when they occur,
+there's no risk of reading faulty data.
## Writing
@@ -107,7 +111,7 @@
By default, tar files are written in the pax format defined by the
POSIX.1-2001 specification (`--format=posix` in GNU tar).
-When all entries have file names shorter than 100 chars and a size smaller
+When all entries have file names shorter than 100 chars and a size smaller
than 8 GB, this is equivalent to the `ustar` format. This library won't write
PAX headers when there is no reason to do so.
If you prefer writing GNU-style long filenames instead, you can use the
@@ -154,8 +158,57 @@
- Supports extended pax headers for long file or link names
- Supports long file and link names generated by GNU-tar
- Hardened against denial-of-service attacks with invalid tar files
+- Supports being compiled to JavaScript, tested on Node.js
+
+## Security considerations
+
+Internally, this package contains checks to guard against some invalid tar files.
+In particular,
+
+- The reader doesn't allocate memory based on values in a tar file (so there's
+ a guard against DoS attacks with tar files containing huge headers).
+- When encountering malformed tar files, the reader will throw a `TarException`.
+ Any other exception thrown indicates a bug in `package:tar` or how it's used.
+ The reader should never crash.
+- Reading a tar file can be cancelled mid-stream without leaking resources.
+
+However, the tar reader __does not__ throw exceptions for wellformed archives
+with suspicious contents, such as
+
+- File names beginning with `../`, `/` or names pointing out of the archive by
+ other means.
+- Link references to files outside of the archive.
+- Paths not using forward slashes.
+- Gzip + tar bombs.
+- Invalid permission bits in entries.
+- ...
+
+When reading or extracting untrusted tar files, it is your responsibility to
+detect and handle these cases.
+For instance, this naive extraction function is susceptible to invalid tar
+files containing paths outside of the target directory:
+
+```dart
+Future<void> extractTarGz(File tarGz, Directory target) async {
+ final input = tarGz.openRead().transform(gzip.decoder);
+
+ await TarReader.forEach(input, (entry) async {
+ final destination =
+ // DON'T DO THIS! If `entry.name` contained `../`, this may escape the
+ // target directory.
+ path.joinAll([target.path, ...path.posix.split(entry.name)]);
+
+ final f = File(destination);
+ await f.create(recursive: true);
+ await entry.contents.pipe(f.openWrite());
+ });
+}
+```
+
+For an idea on how to guard against this, see the [extraction logic](https://github.com/dart-lang/pub/blob/3082796f8ba9b3f509265ac3a223312fb5033988/lib/src/io.dart#L904-L991)
+used by the pub client.
-----
-Big thanks to [Garett Tok Ern Liang](https://github.com/walnutdust) for writing the initial
+Big thanks to [Garett Tok Ern Liang](https://github.com/walnutdust) for writing the initial
Dart tar reader that this library is based on.
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 717c8c6..8b18047 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -1,4 +1,4 @@
-include: package:extra_pedantic/analysis_options.1.3.0.yaml
+include: package:extra_pedantic/analysis_options.2.0.0.yaml
analyzer:
strong-mode:
@@ -17,3 +17,4 @@
unnecessary_await_in_return: false
no_default_cases: false
prefer_asserts_with_message: false # We only use asserts for library-internal invariants
+ prefer_final_parameters: false # Too much noise
diff --git a/lib/src/utils.dart b/lib/src/utils.dart
index 2a531e8..8003cb9 100644
--- a/lib/src/utils.dart
+++ b/lib/src/utils.dart
@@ -95,7 +95,7 @@
int computeUnsignedHeaderChecksum() {
// Accessing the last element first helps the VM eliminate bounds checks in
// the loops below.
- this[blockSize - 1];
+ this[blockSize - 1]; // ignore: unnecessary_statements
var result = checksumLength * _checksumPlaceholder;
for (var i = 0; i < checksumOffset; i++) {
@@ -109,7 +109,7 @@
}
int computeSignedHeaderChecksum() {
- this[blockSize - 1];
+ this[blockSize - 1]; // ignore: unnecessary_statements
// Note that _checksumPlaceholder.toSigned(8) == _checksumPlaceholder
var result = checksumLength * _checksumPlaceholder;
diff --git a/pubspec.yaml b/pubspec.yaml
index c119ba5..0d73112 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: tar
description: Memory-efficient, streaming implementation of the tar file format
-version: 0.5.4
+version: 0.5.5
repository: https://github.com/simolus3/tar/
environment:
@@ -13,7 +13,7 @@
dev_dependencies:
charcode: ^1.2.0
- extra_pedantic: ^1.4.0
+ extra_pedantic: ^2.0.0
file: ^6.1.2
node_io: ^2.1.0
path: ^1.8.0