%PDF-1.5 %¿÷¢þ 4069 0 obj > endobj 60000 0 obj > stream .-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.- !!! If you see garbage below, make sure your text editor is set to use !!! !!! UTF-8 encoding. For example, in Vim, switch with :e ++enc=utf-8 !!! .-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.- _ _ __ ISSUE 1 £1.99 JUNE 2021 _ | | __ _| |__ / /_ In this issue: _| |_ | |/ _` | '_ \| '_ \ New Frontiers in PDF Accessibility |_ _| | | (_| | |_) | (_) | Publishing in PDF: preliminary experimental |_| |_|\__,_|_.__/ \___/ results Fantasy Footbyte Colophon Tracking █▀▀▀▀▀█ ▀▀▀█▄█▄ █ █▀▀▀▀▀█ █ ███ █ ▀▄█ ▀█▄▄ █ ███ █ █ ▀▀▀ █ ▄▀█▀██ █ ▀▀▀ █ ▀▀▀▀▀▀▀ █▄▀ █ █ █ ▀▀▀▀▀▀▀ ▀█▄██▄▀ ▄▀▄ ▀▀█▄▀ ▀▄▄▄▄▄▀ █▄▄▄▀▀▀ ▄▀ ▀ ██▀▀█▄██▄▄█ █▄ ▀▀▄▀██▀█ ▄▀▀▄█ ▀▀▄ ▄▀ █▀▄▄▀▀▀█▄██ ▄▄██▄ ▀▄▀██▀█ ▀ ▀ ▀▀ █▄ █▀ ▀█▀▀▀█ ██ █▀▀▀▀▀█ █ ▄▀█▀▄█ ▀ █ ▀ █ ███ █ ███▀▄█ ▀▀▀█▀▀ ▄█ █ ▀▀▀ █ ▄ ▀█▄█ ▀ ▄▄█▀███ ▀▀▀▀▀▀▀ ▀▀ ▀▀▀ ▀▀▀ ▀ ▀ 1LAB6ABnKev8dXGpHPCctyJfnUunJs13ah Find the disk image as a PDF attachment. .-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.-=-._.- New Frontiers in PDF Accessibility ================================== This file is both a valid PDF/A-3b document and a valid MP3 file containing a dramatic reading of the content. It is also readable as plain text in any text editor. It has been tested in applications such as Adobe Reader, Windows Media Player, and Vim. Why? Because sometimes you want to read Lab 6 with full colour and glorious layout, and sometimes you want to read Lab 6 in a text mode terminal, and sometimes you want to listen to it while swimming - and you don't want to maintain multiple copies in separate files that might go missing. How? Through the magic of binary polyglots! While many PDF readers take a flexible approach to finding the 5 PDF header bytes %PDF-, the spec requires that they occur at offset zero. Adobe Reader is happy to search the first 1024 bytes for the magic string, but validation tools are rightly stricter. Meanwhile, the MP3¹ file format has no overall header, instead consisting of a sequence of frames for which players must search. I suspect that this behaviour is helpful in the context of live streams that may deliver partial frames and leading garbage such as HTTP headers; the player just needs to find the frame sync bits and pick up from there. This tolerance means we can hide the MP3 file away within a PDF stream object. Placing non-PDF data here doesn't clash with PDF content because the PDF file format contains pointers to explicit offsets that allow readers to seek straight to the relevant objects. We still need to place this non-PDF data close to the start of the file as some media players bail out if they search for too long without locating any MP3 frames. Fortunately, there are very few mandatory PDF preamble bytes, so we don't need to keep media players waiting too long. Since PDF uses hard-coded pointers to objects, adding additional objects near the start is not going to work without rebuilding all those pointers so they point to the new, higher, offsets. Fortunately, qpdf is adept at inserting extra text after the header, and with only a slight modification can be convinced to add arbitrary binary data. What remains is to add the plain text representation of the document. PDFs treat any line starting with a % as a comment, so we could just write the text as a series of comment lines, but this is an unnecessary constraint when we can just wrap it in another stream object, to make the text visually cleaner. The flaw in this plan is that if we add too much plain text, we risk the media players losing interest. Fortunately, plain text is very light weight, so there is substantial headroom available in the file. It's true that the plain text content will be immediately followed by a wall of binary gibberish that won't look good in a text editor - but it's trivial to just not read any further. It is important to adhere to the PDF spec precisely, as Adobe have a history of blacklisting² polyglot techniques that bend the spec too far. And hey presto! A universally accessible PDF/MP3/TXT document, all in one file. 🖫 Find on the coverdisk 🖫 Find qpdfmod.patch on the coverdisk Footnotes --------- ¹ Why MP3? Since we live so far into the future, all relevant patents have now expired, making it an unencumbered format with near-universal support. ² Don't miss the link to the TIFF/EXT2 polyglot at the MIT Mystery Hunt 2015 site. Publishing in PDF: preliminary experimental results =================================================== How much of the web ecosystem supports PDF properly? Thankfully, a lot of it. Browsers are particularly good: all of them are happy to load a PDF as the root document on a domain³. Google Chrome and Firefox both support searching for phrases that span multiple lines, whereas offline rendering libraries like poppler (which underpins viewers such as Evince, Okular and Inkscape) do not⁴. The Wayback Machine supports PDFs flawlessy but does not. PDFs are out of scope of the W3C validator, but there are alternative validators available. Google's PageSpeed Insights tool bails out, describing the page as "NOT_HTML", which is both disappointing and accurate. Adobe Reader iOS's Liquid Mode didn't work on Lab 6 Issue 0 at the start of the year, but does now. It paints many rendering anomalies, but overall puts in a good effort and largely delivers the continuous-scroll reflowing that Tagged PDF promises. Because I love comedy, I tried a couple of SEO optimisation tools which are so scummy I won't even bother linking to them. You can imagine how helpful their advice was. Feedback -------- To the general concept of a PDF-based website, reactions have ranged from "love it" and "a compelling proposition", to "baffled", "don't", and "I hate reading that on mobile". The Lab 6 Corporate Voice is undeterred, and believes the experience will resonate more profoundly as the value of static publishing is rediscovered. One bug has been discovered in Lab 6 Issue 0: a typo. Lab6 is not merely promotional material for Adobe, but is also a static, immutable doc-chain with each issue referring back to the published hashes of previous issues - so we can't just edit the bug away. What we can do though, is patch it. 🖫 Find patch0.lab on the coverdisk Here's how it works: PDFs support incremental updates, meaning you can append new objects (and replacement versions of old objects) to the end, then write a new cross-reference table that identifies the new object and points to the previous cross-reference table - all without having to rewrite any of the original document. If you grab your trusty copy of Lab 6 Issue 0, you can apply the patch as follows: $ cat patch0.lab >> 0.pdf The new SHA256 hash is: 23960e5ad7c58b67f83ad6729e0c9be5af3822de726393da584c8ec7e12684b7 The patch was developed mostly manually, with some light automation; compiled PDF objects can be very unfriendly to read. Here's an example of how the text "Find the disk as a PDF attachment!" is encoded by LibreOffice: 5.7 142.089 Td /F3 10 Tf[-27-6-2(\ t)9(\n)-62-2-232(\b)- 6-2]TJ Td, Tf, and TJ are commands (set display position, select font, and write text, respectively), preceded by their arguments. TJ's bracketed argument contains the text, encoded as the glyph number in the selected font. So represents the first and second glyph in the font /F3. Only hex numbers inside angle brackets are glyph numbers; the numbers outside the angle brackets are horizontal offsets used to kern letters. Bizarrely, when a glyph number has an ASCII representation, Libreoffice chooses to emit an ASCII literal in parentheses, such as (\n). This is not a newline; it's just glyph number 0x0A. Glyph numbers are not Unicode code points. Nor are they the number of the glyph in an embedded font file, because PDFs typically don't embed font files. Instead, the PDF creator software subsets fonts so that only the required glyphs are included, and in this case it numbers the glyphs in the order they are used, which is why you see a progression from 01, 02, 03, 04, 05, 06, 07, 08, and only back to 05 when we hit the first re-used glyph in the sentence, which in this case is a space. (It's worth noting that this example comes from the first use of this font in the document, so this really is the first time the glyph is encountered). Having understood the syntax, we are still no closer to decoding the text. For this we must separately look up the font object /F3 and find its /ToUnicode mapping, which finally gives us a way to translate glyph number into a Unicode code point. PDFs in general are not required to contain a /ToUnicode mapping, which means it's possible to include text that can be displayed, but not exported without the use of OCR. But that's why we use PDF/A, where such mappings are mandatory. To cut a long story short, the offending paragraph in Issue 0 was located with the aid of some brute force Python: 🖫 Find on the coverdisk From this point it was simply a matter of extracting the original paragraph, manually patching it with some extra characters, fixing up the length, then adding a new trailer with manually-recalculated offsets. So, slightly harder than hitting the edit button on a Wordpress blog entry, but you'll surely agree thoroughly worth it. Further development ------------------- Now that PDF has proper audio support, what about video? Unfortunately, the most popular video container formats like Matroska, ASF and Ogg tend to have sane requirements like headers that must be located at the beginning of the file. MP4 (ISO base media format) technically allows its ftyp box to appear merely "as early as possible" in the file, but in practice media players like mpv and VLC are too picky to accept this. Not to worry - video doesn't bring a lot to the accessibility table. Commentary ---------- Feedback and comment forms are nice features on a website, but this isn't really an option in PDF/A. In regular cursed PDF⁵, you can create editable text fields and a submit button which POSTs to a URL, but we're not using regular cursed PDF here, so we're out of luck, right? Wrong! Browsers still, as of 2021, display a URL bar to users, and the URL bar is none other than a user-editable text field with a submit action! So, to submit comments on this document, just enter your comment in the address bar after the URL, and it shall be grepped out of the web server logs. Here's an example of a comment on Issue 1 using Firefox: And another on iOS: To be clear: The comment can only be a structureless character stream, so feel free to describe your own human-readable metadata in-band. The maximum length is a few thousand characters. Your browser should take care of encoding. In the event that you are not using a browser to read this document, you can still use a browser to submit a comment - or indeed any device capable of issuing an HTTP request. Just be sure to append your comment to the URL of the document, including the number, so that it is clear which issue you are commenting on. Comments will then go into an eldritch limbo ("moderation queue"), existing only in the server logs, until a future Lab 6 editor remembers to run a command like the following: sed -n -r 's/.*"GET \/[0-9]+(.+) HTTP\/.*/\1/gp' access.log | uniq | python3 -c "import sys, urllib.parse as ul; print(*[ul.unquote_plus(l) for l in sys.stdin], end='\n')" | less The small web ------------- Of course, PDFs tend to have a life independent of the web, and so Lab 6 is now also available over Gemini: gemini:// (Indeed, this issue was published *first* over Gemini). The Gemini protocol favours text documents written in its own lightweight markup format, but does not prevent hosting other file types. Reading Gemini sites using Petr Vernigorov's Elaho on iOS is a delightful experience - and by virtue of being based on Firefox, it even handles opening PDF files natively! Comment-submission-via-URL works over Gemini too, naturally. PDF in the News --------------- The PDF/A-4 standard was approved in November 2020, and like most new technology, it appears to be a regression, due to allowing the presence of JavaScript in the file, although it is hard to verify this as the standard is kept behind the ISO paywall. In order to keep your PDF/A lawn pristine, best to keep PDF/A-4 kids off it until this can be clarified. Footnotes --------- ³ As long as they are set to open PDF files themselves, rather than download them. ⁴ Bug number 56, created 13 years ago. ⁵ Consult Lab 6 Issue 0 for more details on the curse Fantasy Footbytes ================= Anyway, moving on from PDFs... Just as is doing sterling work filling out the namespace of 24-bit colours, Lab 6 is proud to do its bit for the English language by naming all the 8-bit bytes. There are 256 of these beauties, and while some of them have been named in character encodings, the more popular ones such as ASCII, UTF-8, and Windows Code Page 1252, leave several values undefined. Mac Roman does manage to assign a character, symbol, or control code name to every value, including the Apple logo twice. But these aren't names. Not really. Let's change that. Grab your magnifying glass and check out the table on the next page, or read the file in text mode to find the data in a more convenient format. The scene is now set to destroy environmentally ruinous proof of work cryptocurrencies by neutralising them into a mechanism for running a fantasy football tournament: * Pick a nice round Bitcoin block like S = 393216ᵈᵉᶜ = 60000ₕₑₓ. * Choose two teams T₁ and T₂ to compete against each other. * Find the result of the match between team T₁ and team T₂ in block: S + (256 × T₁) + T₂ * For example, in season 60000ₕₑₓ, when Chownley play Openmillwall, the result can be found in block: 60000ₕₑₓ + (FFₕₑₓ × 8Fₕₑₓ) + 05ₕₑₓ = 68F05ₕₑₓ * And what is the result? Whichever team has the highest nonce value wins. 65,536 blocks are needed to determine results for all local (home) matches, and another 65,536 blocks for remote (away) matches. Fixtures where a team plays themselves are always fogged off. Null City Starthampton Writing Alvechurch-Turing Shellcode 04 Openmillwall Ackrington Stanley St Synchronous Mirren Cray Supervalley Paperless Mills GSV Einhorn Is Finkle Zstandard Liège Porting Middlesout Ryhope Corollary Warfare FC Beşiktaş Cult of Jimnastik Kubüntü Grays Almanathletic Roswell First Corinthians 8:2 Device County Blinken 04 Lichten FC SAN Cache Invalidation & Nîmes NAK Dons IaaX Transmere End Bradfnord City Medium North End Fenermicrobahçe SSD Napoli Sunderfile Ignite & Hive Albion Intercal Milan Atalanparty Lunar Rovers Winampdoria Port Knock Oct*thorpe United Hartleblackliver Mining Pool Cagliarewriting Bologna/Lux SC Libreburg Cá.DIZ Apt-Getafe Typecaster Rovers Turbo Chelc++ Zener St. Petersburg AFC St. Austelnet Hibernation Prescot Ribbon Cables Sheffield 0day Heather St. JS BO2kRussia Dortmund LaTeX Orient St Johnston Sans Lothlorien Thistle Hutchison 5G IPv6switch Town Serialbus Full HAM8 Sigkillmarnock AJAX Arpenden Town Linker City Scihub Academicals Balanced Forest Heart of Central Tendency AFK Bourneshell JVham HotSpot Done DD BSDtar Donetsk Polyvillareal Nice OlympiarchOS Static Kiev Kruskal Palace AST DOM Villa Bootsplash Arygle Airdrie Octonions Hallambda Greenthread Morton N Queens Problem Rangers Forth Athletic Tucowdenbeath CA OS/Asuna Eternal Wednesday Stirling Engine Albion Unsigned Long Eaton Midi Tower Hamlets V4L Wolfsburg Pentestrith Keith Packard Conwy's Game of Football LazyI/O Noetherwell Eigencity HELO Athletic Gala Fairydean Naming Things Is Hard Miningrigg Rose Athletic Losslessmouth DAG Algorithm and Redshift East Fifo SparcTeX MOSFET Stran.rar Dun k-line Irlambda Cardijk City Stack City Covertree City Acidburn Rovers Napcester City Wolframalphton Wanderers Andds County Torqwrench United Rexxham Raspbury Future Crew Alexandra Vimbledon MFC Linking City Emacslesfield Town Debian & Redmond Shepton Malware Blackburn Roverflow Inverse Hamiltonian Thistle Man(1)field Town Mempoole Town MK Nod Xargsyle Md5sumderland Birminghamming City Galoisfield Town Von Neucastle United Examouth Enverton Ballinabellard Homotopy Cliftonville RAID Rovers Less|tr City Terminal Citty Cursor Wanderers Arstechnical Altsport RFC Newton Raphson Aycliffe Run Korn Town Guitarheroe Dunwich Hamlet HP Chownley Nandwich Town Bill Gates' Head Solderhell Moors Tokenring Athletic Wizard's Cleeve Whytehat Malware & Xtree Wardrivington Town Fractal Collieries Kirby Marlinspike Stallmanchester FS Eibarbazquux Sunderland RSA TADScaster Albion Rovers Return Oriented Football Object Orient Angsty Gnomads Chiptune Modbury Town Disjoint United Rampishamware Dunstable Multivibrator FLACwell Heath NetAFC Hayes Trafford Shaping Stenhouse|more HANA Athletic Olapton Hashton & Backup United Tunbridge Seekwells Coleshill Climbing Town Glasgow Haskell Aloysians Linterhouse Valgrind of Clyde CRC7 MOTD UART Ain't a Recursive Teamname Queens Park Named Range Celtick-tock Refresh PR Flamengo Breakin City Wysiwigan Ipswitchboard Wanderers Maidentail United Coaxfosters Merthyristor Town Market Driven Town Carcdrlisle United Complex Madrid TCP Porto MAC Address Tel Aviv FC Bayer Filter Munich Olympique Lyon Estates Inte8le Javantus Keygenoa Botafo.go Sunny Cove Rangers Apache Fluminense Salispbury Foobarcelona Blyth Spartstations Tilbury Containers CLIde Inverurie Low Code Works Red Team Blue Team Beaconscell Town DC Milan Vasco Certified Net Associates GNUport County Nandwich Town Host Bromwich Adapter Cryptal Palace Blockpool NFT Architectural Lens Montpeltier Goole Fonts Splunkirk Marlowverflow Bashley Hashford Town FK Riemann Zeta Genthub 3D Chessterfield Xrangers Ports Tree Vale Sphere Everton Ballardrat Seymour Cray Wanderers Enterprise Civil Service Bus Darwen XNU IMPLY Gate Priory Abingdom Town Halespwn Town KirkMcKusickloch Rob Pike Portsknuth Great YARNmouth Town Lamport County Backus-Stourport Torvaldershot Town Dense Boldface Dijon Postel Bjarne Strasbourg Bordeauxgecoin Paris Saint Voidmain() Touhouse Aminets Eeproma Saasuolo Crontone CSV 1860 Munich Pagnell ≠ Newport Pagnell Colophon ======== This document was drafted in OneNote, productionised using LibreOffice Writer, post-processed in Audacity and hand-tuned using a derivation of qpdf, before being glued together with bash, sed, and python. The coverdisk is a 1.44MB FAT-12 formatted floppy disk image. The document's primary URL is – although mirrors are welcome. The document may contain outrageous falsehoods and embarrassing mistakes, unretractable due to it being immutable. Corrections may be published in future issues. All content is licensed under: Contributions may be sent to the email address on the last page, or the Bitcoin address on the first page. This document's hexadecimal SHA256 hash begins 0x01, identifying the issue number. 250e3f7d581acff115537ba38e89ad31 is a handy random 128-bit integer that will appear in every issue of Lab 6 and can be used to search for copies. Back Issues ----------- 00 - All hail PDF, FORENSIC.ZIP SHA256 00c411fee9419cd861d9850dc56d53b7e6a211e90df9a1ca953e021b0cf31a56 Official sponsor of 6 Tracking ======== OEIS entries 344,647 English Wikipedia entries 6,311,391 RC5-72 keys tested 365,427,233,059,946,627,072 (% complete) (7.738%) Bitcoin blocks 686413 (hash) 00000000000000000005bbef80d32208e28d73e4adf775898554d3487b72a3bf XKCDs 2472 IPv6 adoption 35.06% Abe Vigoda Status Page Status Still up Largest Prime 2^82,589,933 − 1 BTTF Movies 3 World population according to the CIA 7,772,850,805 Latest stable Linux kernel 5.12.9 Color Names 2,545,185 Latest number on tildeverse's #counting 6,070 Count of University of Queensland pitch drops 9 Project Gutenberg eBooks 65,490 UNIX time rebaselined to the big bang 434313793622924534 OCRemix Releases 4,034 Did you enjoy these numbers? Send your feedback to and it may be published in the next issue. You may have just lost Schrödinger's game. The End ======= That's the end of the text mode version of this issue. What follows is an audio rendition of the same information, and then the rest of the PDF. Enjoy! ID3 @ " 8)TCON Death Metalÿû”d Xing 7 êØ "%(+-0358;=@BDGJMORUWZ]_adfilnqtwy|„†ˆ‹Ž“•˜š ¢¤§©¬¯°³¶·º½ÀÁÄÇÉÌÎÐÓÖØÚÝàâäçéìîðóöøûþ LAME3.100œ 5 $œ ® êØ X—; ÿû¤d ð € ð ,4 € ( ?À 4Š Ýù~-Ð ÿÿÿîÿÖÿυ€ Ïð}ÿÿÿÿü ÿzÂÿø86åÿüˆ Ûj` ‰ª CÿHg±tvœêí7/ÿÿÿÿT4ñ³ûØ`•w¿‡|ò”‹‘ÿÿÐ 0 @ yÿÏæ_üÿÿÿÿÿþ² öTßóNgÿÿýˆ¿¯²»VØíq„Á úš½¿ÔmŸË[–6Ù¹˜Ž »˜´fŠ^„Ì­ðÁPãPE.^IUòü,6îäA€%ÿX`E—ý5ØìTÅþµÿóØF`¹;\‡©`'þOo}Ã}翔š–E"ÒÊ WԍX§ÿÿÿÿçpÃÿ{÷-U‡wÿÿÿÿÿ«J,ÓüÜ)Ê(ÿÿÿ“ë~ÿ£cmg¿HŸàµ¨ ˆ“eF Ö û7҅ŒT”8(8Æ1†ÊªëUR²µ®õ(áìds?Õ.ÌU+«íÿû4dÝ Ï ð  ø@˜ p '— ŐÞdùC¥,†¿¨x m“É‚5 ù$Š!¹X .mKR•¾ÿU)ú²‘Ñ­§êÄUTAÎÒÐdy™%!(ií/0>Ndµp ƒ”„B'»C½™+›°ò,ïõXfےi§°“]lÿû”dø€o)PF@ $%*