F12 number-size-gapA size with a space among its digits, which reads as two sizes.
Reject(draft) A strict parser must reject this archive.
F12-number-size-gap.tar |
test archive, 2,048 bytes
sha256 cb8bb52c904e8a153dc0786c4f3b6bb041245664bb64e7510ad80dd0b62e0ec0 |
F12-number-size-gap.json | expected result |
F12-number-size-gap.txt | annotated blocks |
F12-number-size-gap.py | generator script |
The size field is 000000 1000. In POSIX, a numeric field is octal digits terminated by spaces or NULs, and nothing follows them. Read leniently, this case is ambiguous because the size is either 0, if the number ends at the first blank (and the next block is the header of smuggled), or 1000 octal, 512, if the blank is skipped (and the next block is the data of a).
Decision point: how a numeric field with a space among its digits is read.
Seen in: none of the scanned tarballs.
Every block of 512 bytes, to scale, with its offset. Hover over a field for its bytes.
F12-number-size-gap: must reject
A size with a space among its digits, which reads as two sizes.
The size field is `000000 1000`. In POSIX, a numeric field is octal digits terminated by spaces or
NULs, and nothing follows them. Read leniently, this case is ambiguous because the size is either 0,
if the number ends at the first blank (and the next block is the header of `smuggled`), or 1000
octal, 512, if the blank is skipped (and the next block is the data of `a`).
Decision point: how a numeric field with a space among its digits is read.
Seen in: none of the scanned tarballs.
0x000000 header: regular file, size 0 or 512
name [ 0,100) "a" + 99 NUL
mode [100,108) "0000644" + NUL 644 (octal)
uid [108,116) "0000000" + NUL 0
gid [116,124) "0000000" + NUL 0
size [124,136) "000000 1000" + NUL
mtime [136,148) "00000000000" + NUL 0
chksum [148,156) "007317\0 " 3791: the unsigned sum of the header, this field as spaces
typeflag [156,157) "0" regular file
linkname [157,257) 100 NUL
magic [257,263) "ustar" + NUL
version [263,265) "00"
uname [265,297) 32 NUL
gname [297,329) 32 NUL
devmajor [329,337) "0000000" + NUL 0
devminor [337,345) "0000000" + NUL 0
prefix [345,500) 155 NUL
pad [500,512) 12 NUL
0x000200 header: regular file, the data of a, to an implementation that skips spaces
name [ 0,100) "smuggled" + 92 NUL
mode [100,108) "0000644" + NUL 644 (octal)
uid [108,116) "0000000" + NUL 0
gid [116,124) "0000000" + NUL 0
size [124,136) "00000000000" + NUL 0
mtime [136,148) "00000000000" + NUL 0
chksum [148,156) "010725\0 " 4565: the unsigned sum of the header, this field as spaces
typeflag [156,157) "0" regular file
linkname [157,257) 100 NUL
magic [257,263) "ustar" + NUL
version [263,265) "00"
uname [265,297) 32 NUL
gname [297,329) 32 NUL
devmajor [329,337) "0000000" + NUL 0
devminor [337,345) "0000000" + NUL 0
prefix [345,500) 155 NUL
pad [500,512) 12 NUL
0x000400 2 zero blocks: the end-of-archive marker
0x000800 end of file
As xxd writes it: xxd -r makes the archive of it.
00000000: 6100 0000 0000 0000 0000 0000 0000 0000 a............... 00000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000060: 0000 0000 3030 3030 3634 3400 3030 3030 ....0000644.0000 00000070: 3030 3000 3030 3030 3030 3000 3030 3030 000.0000000.0000 00000080: 3030 2031 3030 3000 3030 3030 3030 3030 00 1000.00000000 00000090: 3030 3000 3030 3733 3137 0020 3000 0000 000.007317. 0... 000000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000100: 0075 7374 6172 0030 3000 0000 0000 0000 .ustar.00....... 00000110: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000120: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000130: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000140: 0000 0000 0000 0000 0030 3030 3030 3030 .........0000000 00000150: 0030 3030 3030 3030 0000 0000 0000 0000 .0000000........ 00000160: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000170: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000180: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000190: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000001b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000001c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000001f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000200: 736d 7567 676c 6564 0000 0000 0000 0000 smuggled........ 00000210: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000220: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000230: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000240: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000250: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000260: 0000 0000 3030 3030 3634 3400 3030 3030 ....0000644.0000 00000270: 3030 3000 3030 3030 3030 3000 3030 3030 000.0000000.0000 00000280: 3030 3030 3030 3000 3030 3030 3030 3030 0000000.00000000 00000290: 3030 3000 3031 3037 3235 0020 3000 0000 000.010725. 0... 000002a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000002b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000002c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000002d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000002e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000002f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000300: 0075 7374 6172 0030 3000 0000 0000 0000 .ustar.00....... 00000310: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000320: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000330: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000340: 0000 0000 0000 0000 0030 3030 3030 3030 .........0000000 00000350: 0030 3030 3030 3030 0000 0000 0000 0000 .0000000........ 00000360: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000370: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000380: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000390: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000003a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000003b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000003c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000003d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000003e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000003f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000400: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000410: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000420: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000430: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000440: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000450: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000460: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000470: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000480: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000490: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000004a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000004b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000004c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000004d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000004e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000004f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000500: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000510: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000520: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000530: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000540: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000550: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000560: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000570: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000580: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000590: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000005a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000005b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000005c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000005d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000005e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000005f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000600: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000610: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000620: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000630: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000640: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000650: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000660: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000670: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000680: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000690: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000006a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000006b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000006c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000006d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000006e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000006f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000700: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000710: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000720: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000730: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000740: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000750: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000760: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000770: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000780: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000790: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000007a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000007b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000007c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000007d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000007e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000007f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................
| implementation | version | outcome | what it makes of it |
|---|---|---|---|
| GNU tar | tar (GNU tar) 1.35 | ⚠️ accepts | tree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442) |
| bsdtar | bsdtar 3.8.10 - libarchive 3.8.10 | ✅ as the verdict says | error: bsdtar: Error opening archive: Unrecognized archive format |
| BusyBox tar | BusyBox v1.38.0, defconfig | ⚠️ accepts | tree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442) |
| 7-Zip | 7-Zip (z) 26.05 (x64) | ⚠️ accepts | tree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442) |
| Python tarfile, filter=data, as in pip | CPython 3.15.2 | ✅ as the verdict says | error: ReadError: file could not be opened successfully: - method gz: ReadError('not a gzip file') - method bz2: ReadError('not a bzip2 file') - method xz: ReadError('not an lzma file') - method zst: ReadEr… |
| Python tarfile, filter=tar | CPython 3.15.2 | ✅ as the verdict says | error: ReadError: file could not be opened successfully: - method gz: ReadError('not a gzip file') - method bz2: ReadError('not a bzip2 file') - method xz: ReadError('not an lzma file') - method zst: ReadEr… |
| Python tarfile, filter=fully_trusted | CPython 3.15.2 | ✅ as the verdict says | error: ReadError: file could not be opened successfully: - method gz: ReadError('not a gzip file') - method bz2: ReadError('not a bzip2 file') - method xz: ReadError('not an lzma file') - method zst: ReadEr… |
| node-tar | tar 7.5.22 | ⚠️ accepts | tree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442) |
| node-tar, strict | tar 7.5.22 | ⚠️ accepts | tree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442) |
| tar-fs | tar-fs 3.1.3, on tar-stream 3.2.2 | ⚠️ accepts | tree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442) |
| Java Commons Compress | Commons Compress 1.28.0, Expander, on Java 27.0.1.0.2 | ✅ as the verdict says | error: java.io.IOException: Corrupted TAR archive. |
| .NET System.Formats.Tar | System.Formats.Tar of .NET 10.0.14, ExtractToDirectory | ✅ as the verdict says | error: InvalidDataException: Unable to parse number. |
| PHP PharData, as in Composer | PharData of PHP 8.5.12, as Composer's TarDownloader calls it | ✅ as the verdict says | error: UnexpectedValueException: phar error: "suite/archives/F12-number-size-gap.tar" is a corrupted tar file (invalid entry size) |
| Go containerd archive.Apply | containerd v2.4.2, archive.Apply, of go1.27.3 | ✅ as the verdict says | error: archive/tar: invalid tar header |
| Rust tar | tar 0.4.46, unpack | ✅ as the verdict says | error: failed to iterate over archive |
| Rust astral-tokio-tar | astral-tokio-tar 0.7.0, unpack | ✅ as the verdict says | error: failed to iterate over archive |
| Rust tar-codec, as in uv | tar-codec 0.0.15, with the policies of uv 0.13 | ✅ as the verdict says | error: at byte 0: invalid tar size field: found [48, 48, 48, 48, 48, 48, 32, 49, 48, 48, 48, 0] |
| RubyGems | RubyGems 4.0.20 of Ruby 4.0.9, extract_tar_gz | ✅ as the verdict says | error: Gem::Package::TarInvalidError: "000000 1000" is not an octal string |
| R untar, internal | utils::untar of R 4.6.1, tar = "internal" | ⚠️ accepts | tree B: a (512 B, 917dba8e) |
| Perl Archive::Tar | Archive::Tar 3.12 of Perl v5.44.0 | ⚠️ accepts | tree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442) |
| Haskell tar | tar 0.7.2.0, extract, of GHC 9.14 | ⚠️ accepts | tree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442) |
| Julia Tar.jl | Tar 1.10.0 of Julia 1.13.3 | ⚠️ accepts | tree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442) |
| live-bootstrap untar | mescc-tools-extra a151c245e512, as live-bootstrap pins it, built with cc | ⚠️ accepts | tree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442) |
| live-bootstrap untar, --non-strict | mescc-tools-extra a151c245e512, as live-bootstrap pins it, built with cc | ⚠️ accepts | tree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442) |
Release tarballs of Spack, nixpkgs, Guix and live-bootstrap, and samples of PyPI, crates.io and RubyGems with number.size.gap-in-digits.
| ecosystem | tarballs | with it | share |
|---|---|---|---|
| Spack | 37,553 | 0 | none |
| nixpkgs | 18,990 | 0 | none |
| Guix | 10,168 | 0 | none |
| PyPI | 10,000 | 0 | none |
| crates.io | 5,000 | 0 | none |
| RubyGems | 5,000 | 0 | none |
| live-bootstrap | 171 | 0 | none |
| total (distinct) | 82,586 | 0 | none |