Skip to content

Latest commit

 

History

History
191 lines (146 loc) · 7.97 KB

File metadata and controls

191 lines (146 loc) · 7.97 KB

05 — Two namespaces: 1,422 extents, 1,422 paths, and not one agreement

Measure: iso9660.py --compare for the extent sets and the path comparison; tools/namespaces.py, written this session, for the derivation rule, the collision analysis and the Level 1 conformance check. Every figure is over the whole tree.


The inverse of yesterday

CLIC 02/97 had no Joliet descriptor, so --compare had nothing to compare and the chapter that would have used it was never written. This disc has three descriptors, and the answer is the other extreme:

python tools/iso9660.py Mico02CD.bin --compare

  primary namespace : 1527 entries (1423 files, 104 dirs)
  Joliet  namespace : 1527 entries (1423 files, 104 dirs)
  primary file bytes: 713496612
  Joliet  file bytes: 713496612   (delta 0)

  extents in primary only : 0
  extents in Joliet only  : 0
  extents in both         : 1422
  of which the two namespaces spell differently: 1422
    ... differing only by letter case          : 779
    ... differing by more than case            : 643

  date bytes identical in both namespaces for every shared extent: True

Same files, same bytes, same dates, same extents. Every single path is spelled differently. /CD_ROM/CREATIVI.HTM against /CD-ROM/creativita.htm; /ABBONAME/MICO_ABB.PDF against /abbonamento/Mico_abbonamento.pdf.

Two namespaces that agree on everything except how to say it.

Paths versus names

The 1,422 is a count of paths, and a path inherits its parent's spelling. At the level of the leaf name the picture is different, and the difference is worth having:

how the primary name derives from the Joliet name records share
identical after uppercasing (exact) 23 1.6163 %
differs by letter case only 1,162 81.6585 %
a character outside the d-characters mapped to _ (subst) 7 0.4919 %
truncated to 8.3 145 10.1897 %
truncated plus a numeric disambiguator 86 6.0436 %
unexplained 0 0 %

1,423 of 1,423 = 100.0000 %, explained by one mechanical rule with nothing left over.

So: 1,400 leaf names of 1,423 differ, and 23 are identical — files whose own name already fitted 8.3 in upper case and whose path differs only because a parent directory's does. /GIOCHI/OTHELLO/README.TXT is the same eleven characters in both namespaces; only giochi and Othello moved.

The rule, stated and tested

ISO 9660 Level 1 (ECMA-119 §7.5, §7.6 and Annex A) allows d-characters A-Z, 0-9 and _; a file identifier of at most 8 characters, an optional . and at most 3 more, then ; and a version; a directory identifier of at most 8 characters with no dot and no version.

What the standard does not say is what a writer should do with a name that breaks those limits. That mapping is the writer's invention, and it is what namespaces.py measures. Nero's rule, derived and then tested against all 1,423 records:

  1. upper-case the name;
  2. map every character outside A-Z 0-9 _ to _;
  3. truncate the stem to 8 characters and the extension to 3;
  4. if that collides with a name already used in the same directory, overwrite trailing characters of the stem with digits.

creativita.htmCREATIVI.HTM. Mico_abbonamento.pdfMICO_ABB.PDF. Archivio_off.gifARCHIVI2.GIF — where ARCHIVIO.GIF was already taken by Archivio.gif, so the eighth character became a counter.

That last case is the whole of step 4 and there are 86 of them.

What Joliet is actually buying

Truncate all 1,423 Joliet names to 8.3 with no disambiguator and count what collides, per directory:

colliding groups 29
names inside those groups 115
names that owe their uniqueness to Joliet or to Nero's counter 86
primary names actually carrying a counter 86

The two 86s are the same 86, which is the check: every name that would have collided got a counter, and no name that would not have collided got one.

The worst groups are all one product, and they are fonts and design sets:

directory truncates to ×
/Creativita/PhotoClassic3/Gallery/Imports/ PRINTDES.SLD 19
/Creativita/PhotoClassic3/Gallery/Data/ WORSTVEL.TTF 16
/Creativita/PhotoClassic3/Gallery/Imports/ WEBDESIG.SLD 12
/Creativita/PhotoClassic3/Gallery/Data/ CZARISTI.TTF 6
/completi/OpenOffice/ OPENOFFI.CAB 4
/Creativita/PhotoClassic3/Gallery/Data/ GOSMICKS.TTF 4
/CD-ROM/Immagini/Interfaccia/ BOX_TEST.GIF 4
/CD-ROM/ INDISPEN.HTM 4

Worstveld Bold Condense Oblique.TTF, Worstveld Bold Condense.TTF, Worstveld Bold Expand Oblique.TTF and thirteen more: sixteen weights of one typeface family, all identical in their first eight characters. A typeface family is exactly the thing 8.3 was worst at, and 2006 is nine years after Windows 95 made that stop mattering — except on the primary descriptor of a CD, where it still did.

openofficeorg1.cab through openofficeorg4.cab collide on OPENOFFI.CAB and become OPENOFF1.CABOPENOFF4.CAB, so the counter and the original number happen to agree. That is luck, not design.

What a DOS sees

python tools/namespaces.py Mico02CD.bin --dos

records violating Level 1 8.3: 0 of 1423
directory depth of records (path separators):
  depth 1        4
  depth 2       41
  depth 3      834
  depth 4      308
  depth 5      199
  depth 6       37

Zero violations. Every one of the 1,423 primary names is legal 8.3 upper-case with a ;1 version suffix, and the deepest record sits five levels below the root where Level 1 permits eight. A machine running MS-DOS with MSCDEX, in 2006, could mount this disc and open every file on it.

It would see a completely different disc. It would see CREATIVI.HTM and CREATIV2.HTM and CREATIV3.HTM where a Windows machine sees creativita.htm, creativita2.htm and creativita3.htm; it would see ARCHIVI2.GIF where the HTML that references the image says Archivio_off.gif. So the files would all open and the front end would not work at all: the shell's markup names its images in Joliet spelling, and on the primary namespace those names do not exist.

That is the practical content of "two namespaces that agree on nothing". The disc is fully readable in both. It is only usable in one.

The two trees, extracted

Both namespaces extracted to separate directories:

python tools/iso9660.py Mico02CD.bin --extract _work/joliet --joliet
python tools/iso9660.py Mico02CD.bin --extract _work/primary

extracted 1423 files, 713496612 bytes, to _work/joliet
extracted 1423 files, 713496612 bytes, to _work/primary

Same count, same total, and — since every file in both trees is read from the same extent — the same bytes. Two directory trees with identical content and no name in common. Yesterday's session proved by extraction that five records became three files; here extraction proves the opposite, that 1,423 records become 1,423 files twice over, and the only thing that changes is what they are called.

The one extent that has two names in the same namespace

--compare reports 1,422 shared extents and the tree reports 1,423 files. The difference is one:

extent 346405
   /UTILITY/REGSEEKE/HISTORY.TXT;1      0 bytes
   /UTILITY/REGSEEKE/LANG.INI;1        80 bytes

history.txt is zero bytes long, and ISO 9660 gives a zero-length file an extent anyway. Nero gave it the next sector it was about to use, which is the one lang.ini occupies. Both namespaces do the same thing, so the pair is symmetrical.

Yesterday's disc had two empty files pointing at LBA 136 and 137, two sectors that belonged to nobody. This one has an empty file pointing at a sector that belongs to somebody else. Same standard, same gap in it, two writers filling it two different ways — and this is the version where the arithmetic does not notice, because 1,422 distinct extents look exactly like 1,422 files unless you count the records too.