brendan-duncan / archive

Dart library to encode and decode various archive and compression formats, such as Zip, Tar, GZip, ZLib, and BZip2.
MIT License
399 stars 139 forks source link

Fix long path name tar encoding and decoding errors #245

Closed a-voyager closed 4 months ago

a-voyager commented 1 year ago

FormatException: EOF reached without finding string terminator will be thrown with using the InputFileStream / OutputFileStream for .tar file's encoding and decoding, if any file's path name is very very long.

Minimum Reproducible Example

import 'package:archive/archive_io.dart';  

void main() async {  
  const kLongFileName = '/long_path_name/long_path_name/long_path_name/long_path_name/to/this_is_an_extremely_long_filename.bin';  

  {  
    final archive = Archive()..addFile(ArchiveFile(kLongFileName, 1, [1]));  
    final bytes = TarEncoder().encode(archive);  
    TarDecoder().decodeBytes(bytes);  
  }  

  {  
    final archive = Archive()..addFile(ArchiveFile(kLongFileName, 1, [1]));  
    final outputFile = 'output.tar';  
    TarEncoder().encode(archive, output: OutputFileStream(outputFile));  
    TarDecoder().decodeBuffer(InputFileStream(outputFile)); // FormatException: EOF reached without finding string terminator  
  }  
}

How to Fix In order to control the scope of influence (such as anywhere reading a null-terminated string), pass the size parameter to the InputStream#readString method only when failed to trying to read the null terminator.

       if (tf.filename == '././@LongLink') {
-        nextName = tf.rawContent!.readString();
+        try {
+          nextName = tf.rawContent!.readString();
+        } catch (error) {
+          nextName = tf.rawContent!.readString(size: tf.fileSize);
+        }
         continue;
       }
brendan-duncan commented 4 months ago

I'm closing this PR (I know it's old and I neglected it). I'm finishing a major version update, and it includes a similar fix for the tar symlink not always being null terminated. https://github.com/brendan-duncan/archive/tree/4.0