extractMatchingEntry method

File? extractMatchingEntry({
  1. required File archiveFile,
  2. required Directory outputDir,
  3. required ArchiveSelectionContext selection,
})

Extracts the entry matching canonicalName from a .tar.gz archive.

Returns the extracted file, or null if no matching entry was found. The file is written to outputDir.

Validates:

  • Entry paths are safe (no traversal, no absolute paths)
  • Only regular files are selected (symlinks and hard links rejected)
  • At most one matching entry exists

Implementation

File? extractMatchingEntry({
  required File archiveFile,
  required Directory outputDir,
  required ArchiveSelectionContext selection,
}) {
  final bytes = archiveFile.readAsBytesSync();
  final gzBytes = gzip.decode(bytes);
  final archive = TarDecoder().decodeBytes(gzBytes);

  ArchiveFile? matched;
  var matchCount = 0;

  for (final entry in archive.files) {
    if (!entry.isFile) continue;

    final basename = p.basename(entry.name);
    final matches = matchesLibraryName(
      basename,
      canonicalName: selection.canonicalName,
      acceptVersionedNames: selection.acceptVersionedNames,
    );

    if (matches) {
      matched = entry;
      matchCount++;
    }
  }

  if (matchCount > 1) {
    throw StateError(
      'Multiple entries match ${selection.canonicalName} '
      'in ${archiveFile.path}',
    );
  }

  if (matched == null) return null;

  // Validate path safety.
  if (matched.name.startsWith('/') || matched.name.contains('..')) {
    throw StateError('Unsafe archive entry path: ${matched.name}');
  }

  // Write the selected entry.
  outputDir.createSync(recursive: true);
  final outFile = File(p.join(outputDir.path, p.basename(matched.name)));
  outFile.writeAsBytesSync(matched.content);
  return outFile;
}