Working draft

F12 number-size-gap

A size with a space among its digits, which reads as two sizes.

Reject(draft) A strict parser must reject this archive.

Category
framing
Default policy
rejects it
Files
F12-number-size-gap.tar test archive, 2,048 bytes sha256 cb8bb52c904e8a153dc0786c4f3b6bb041245664bb64e7510ad80dd0b62e0ec0
F12-number-size-gap.jsonexpected result
F12-number-size-gap.txtannotated blocks
F12-number-size-gap.pygenerator script

The case

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.

The archive

Every block of 512 bytes, to scale, with its offset. Hover over a field for its bytes.

F12-number-size-gap: every block of the archive0x000000header: regular file, size 0 or 512name [0,100): "a" + 99 NULnamemode [100,108): "0000644" + NUL, 644 (octal)uid [108,116): "0000000" + NUL, 0gid [116,124): "0000000" + NUL, 0size [124,136): "000000 1000" + NULmtime [136,148): "00000000000" + NUL, 0chksum [148,156): "007317\0 ", 3791: the unsigned sum of the header, this field as spacestypeflag [156,157): "0", regular filelinkname [157,257): 100 NULlinknamemagic [257,263): "ustar" + NULversion [263,265): "00"uname [265,297): 32 NULunamegname [297,329): 32 NULgnamedevmajor [329,337): "0000000" + NUL, 0devminor [337,345): "0000000" + NUL, 0prefix [345,500): 155 NULprefixpad [500,512): 12 NULname "a" + 99 NULsize "000000 1000" + NUL0x000200header: regular file, the data of a, to an implementation that skips spacesname [0,100): "smuggled" + 92 NULnamemode [100,108): "0000644" + NUL, 644 (octal)uid [108,116): "0000000" + NUL, 0gid [116,124): "0000000" + NUL, 0size [124,136): "00000000000" + NUL, 0mtime [136,148): "00000000000" + NUL, 0chksum [148,156): "010725\0 ", 4565: the unsigned sum of the header, this field as spacestypeflag [156,157): "0", regular filelinkname [157,257): 100 NULlinknamemagic [257,263): "ustar" + NULversion [263,265): "00"uname [265,297): 32 NULunamegname [297,329): 32 NULgnamedevmajor [329,337): "0000000" + NUL, 0devminor [337,345): "0000000" + NUL, 0prefix [345,500): 155 NULprefixpad [500,512): 12 NULname "smuggled" + 92 NUL0x0004002 zero blocks: the end-of-archive markerbytes 0 to 512 of 1024: 512 NUL0x0006002 zero blocks, continuedbytes 512 to 1024 of 1024: 512 NUL0x000800end of fileNULprintable ASCIIspacecontrol character, such as a newlinebyte over 0x7fwritten by the case itself
Every block, as text
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
Every byte, as a hex dump

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  ................

What implementations make of it

implementationversionoutcomewhat it makes of it
GNU tartar (GNU tar) 1.35⚠️ acceptstree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442)
bsdtarbsdtar 3.8.10 - libarchive 3.8.10✅ as the verdict sayserror: bsdtar: Error opening archive: Unrecognized archive format
BusyBox tarBusyBox v1.38.0, defconfig⚠️ acceptstree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442)
7-Zip7-Zip (z) 26.05 (x64)⚠️ acceptstree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442)
Python tarfile, filter=data, as in pipCPython 3.15.2✅ as the verdict sayserror: 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=tarCPython 3.15.2✅ as the verdict sayserror: 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_trustedCPython 3.15.2✅ as the verdict sayserror: 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-tartar 7.5.22⚠️ acceptstree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442)
node-tar, stricttar 7.5.22⚠️ acceptstree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442)
tar-fstar-fs 3.1.3, on tar-stream 3.2.2⚠️ acceptstree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442)
Java Commons CompressCommons Compress 1.28.0, Expander, on Java 27.0.1.0.2✅ as the verdict sayserror: java.io.IOException: Corrupted TAR archive.
.NET System.Formats.TarSystem.Formats.Tar of .NET 10.0.14, ExtractToDirectory✅ as the verdict sayserror: InvalidDataException: Unable to parse number.
PHP PharData, as in ComposerPharData of PHP 8.5.12, as Composer's TarDownloader calls it✅ as the verdict sayserror: UnexpectedValueException: phar error: "suite/archives/F12-number-size-gap.tar" is a corrupted tar file (invalid entry size)
Go containerd archive.Applycontainerd v2.4.2, archive.Apply, of go1.27.3✅ as the verdict sayserror: archive/tar: invalid tar header
Rust tartar 0.4.46, unpack✅ as the verdict sayserror: failed to iterate over archive
Rust astral-tokio-tarastral-tokio-tar 0.7.0, unpack✅ as the verdict sayserror: failed to iterate over archive
Rust tar-codec, as in uvtar-codec 0.0.15, with the policies of uv 0.13✅ as the verdict sayserror: at byte 0: invalid tar size field: found [48, 48, 48, 48, 48, 48, 32, 49, 48, 48, 48, 0]
RubyGemsRubyGems 4.0.20 of Ruby 4.0.9, extract_tar_gz✅ as the verdict sayserror: Gem::Package::TarInvalidError: "000000 1000" is not an octal string
R untar, internalutils::untar of R 4.6.1, tar = "internal"⚠️ acceptstree B: a (512 B, 917dba8e)
Perl Archive::TarArchive::Tar 3.12 of Perl v5.44.0⚠️ acceptstree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442)
Haskell tartar 0.7.2.0, extract, of GHC 9.14⚠️ acceptstree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442)
Julia Tar.jlTar 1.10.0 of Julia 1.13.3⚠️ acceptstree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442)
live-bootstrap untarmescc-tools-extra a151c245e512, as live-bootstrap pins it, built with cc⚠️ acceptstree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442)
live-bootstrap untar, --non-strictmescc-tools-extra a151c245e512, as live-bootstrap pins it, built with cc⚠️ acceptstree A: a (0 B, e3b0c442), smuggled (0 B, e3b0c442)

Prevalence in release tarballs

Release tarballs of Spack, nixpkgs, Guix and live-bootstrap, and samples of PyPI, crates.io and RubyGems with number.size.gap-in-digits.

ecosystemtarballswith itshare
Spack37,5530none
nixpkgs18,9900none
Guix10,1680none
PyPI10,0000none
crates.io5,0000none
RubyGems5,0000none
live-bootstrap1710none
total (distinct)82,5860none