{ "spec": "0.13", "description": "Paths of a format 3 head (spec §29.5) with the Unicode 18.0.0 and best-fit tables of §29.5.1, generated by the reference implementation. paths: one path and the rules of one entry, R2 to R6c and R10; trees: the paths of a head, of 0 bytes each, and the result of decoding it. See testdata/README.md.", "unicode_version": "18.0.0", "tables_digest": "07cf5d54aea1cd13a3ecef14a06976cc49a3cdad755cf9bc10395178b93aeb07", "paths": [ { "name": "a file", "path": "nota.txt", "result": "ok" }, { "name": "a file in two folders", "path": "fotos/2025/playa.jpg", "result": "ok" }, { "name": "non-ASCII letters", "path": "música/canción.txt", "result": "ok" }, { "name": "U+00BF, which bestfit1250 maps to '?'", "path": "¿Qué es esto.jpg", "result": "ok" }, { "name": "U+00A7, which bestfit874 maps to a C0 control", "path": "§ 3 contrato.pdf", "result": "ok" }, { "name": "U+2665, which bestfit874 maps to a C0 control", "path": "Para ti ♥.jpg", "result": "ok" }, { "name": "U+2192, which bestfit1253 maps to '\u003e'", "path": "Madrid → Lisboa", "result": "ok" }, { "name": "U+00A0 at the start of a segment: no table maps it to ASCII", "path": " a", "result": "ok" }, { "name": "U+00A0 at the end of a segment", "path": "a ", "result": "ok" }, { "name": "U+3000 at the start: bestfit1250 and others map it to U+0020", "path": " a", "result": "R6c: segment 1: code page 1250 maps the segment to one that breaks R5: the segment starts with U+0020" }, { "name": "U+3000 at the end", "path": "a ", "result": "R6c: segment 1: code page 1250 maps the segment to one that breaks R5: the segment ends with U+0020" }, { "name": "CON.txt in full-width forms", "path": "CON.txt", "result": "R6c: segment 1: code page 874 maps the segment to one that breaks R6: CON is a reserved device name" }, { "name": "U+2216 SET MINUS", "path": "a∖b", "result": "R6c: segment 1: code page 1250 maps the segment to one with U+005C" }, { "name": "U+2236 RATIO", "path": "a∶b", "result": "R6c: segment 1: code page 1250 maps the segment to one with U+003A" }, { "name": "U+00A5, which cp932 maps to '\\'", "path": "a¥b", "result": "R6c: segment 1: code page 932 maps the segment to one with U+005C" }, { "name": "U+20A9, which cp949 maps to '\\'", "path": "a₩b", "result": "R6c: segment 1: code page 949 maps the segment to one with U+005C" }, { "name": "U+00B4, which cp1253 maps to '/'", "path": "a´b", "result": "R6c: segment 1: code page 1253 maps the segment to one with U+002F" }, { "name": "full-width solidus", "path": "a/b", "result": "R6c: segment 1: code page 874 maps the segment to one with U+002F" }, { "name": "full-width reverse solidus", "path": "a\b", "result": "R6c: segment 1: code page 874 maps the segment to one with U+005C" }, { "name": "full-width colon", "path": "a:b", "result": "R6c: segment 1: code page 874 maps the segment to one with U+003A" }, { "name": "two full-width full stops", "path": "..", "result": "R6c: segment 1: code page 874 maps the segment to one that breaks R3: the segment is two dots" }, { "name": "8.3 alias", "path": "ABCDEF~1", "result": "R6b: segment 1: the segment has the form of an 8.3 alias" }, { "name": "8.3 alias with an extension", "path": "ABCDEF~1.TXT", "result": "R6b: segment 1: the segment has the form of an 8.3 alias" }, { "name": "~1 alone", "path": "~1", "result": "R6b: segment 1: the segment has the form of an 8.3 alias" }, { "name": "8.3 alias with a non-ASCII letter", "path": "Ä~1.txt", "result": "R6b: segment 1: the segment has the form of an 8.3 alias" }, { "name": "nine characters before ~1", "path": "ABCDEFGHI~1", "result": "ok" }, { "name": "~1 inside a name", "path": "a~1b", "result": "ok" }, { "name": "~2023 in a long name", "path": "report~2023.txt", "result": "ok" }, { "name": "unassigned U+0378", "path": "a͸b", "result": "R4: segment 1: unassigned U+0378" }, { "name": "noncharacter U+FFFE", "path": "a￾b", "result": "R4: segment 1: unassigned U+FFFE" }, { "name": "U+206A", "path": "ab", "result": "R4: segment 1: invisible U+206A" }, { "name": "U+206F", "path": "ab", "result": "R4: segment 1: invisible U+206F" }, { "name": "soft hyphen U+00AD", "path": "a­b", "result": "R4: segment 1: invisible U+00AD" }, { "name": "U+034F COMBINING GRAPHEME JOINER", "path": "a͏b", "result": "R4: segment 1: invisible U+034F" }, { "name": "U+200B ZERO WIDTH SPACE", "path": "a​b", "result": "R4: segment 1: invisible U+200B" }, { "name": "U+2060 WORD JOINER", "path": "a⁠b", "result": "R4: segment 1: invisible U+2060" }, { "name": "U+3164 HANGUL FILLER", "path": "aㅤb", "result": "R4: segment 1: invisible U+3164" }, { "name": "U+FEFF", "path": "ab", "result": "R4: segment 1: invisible U+FEFF" }, { "name": "U+202E RIGHT-TO-LEFT OVERRIDE", "path": "a‮b", "result": "R4: segment 1: invisible U+202E" }, { "name": "tag U+E0041", "path": "a󠁁", "result": "R4: segment 1: invisible U+E0041" }, { "name": "variation selector VS17", "path": "😀󠄀", "result": "R4: segment 1: invisible U+E0100" }, { "name": "the flag of Scotland, with tags", "path": "🏴󠁧󠁢󠁳󠁣󠁴󠁿", "result": "R4: segment 1: invisible U+E0067" }, { "name": "U+F03A of the private use area", "path": "informeanexo", "result": "R4: segment 1: private use U+F03A" }, { "name": "TAB", "path": "a\tb", "result": "R4: segment 1: control U+0009" }, { "name": "U+2028 LINE SEPARATOR", "path": "a\u2028b", "result": "R4: segment 1: separator U+2028" }, { "name": "':'", "path": "a:b", "result": "R4: segment 1: character U+003A" }, { "name": "'\\'", "path": "a\\b", "result": "R4: segment 1: character U+005C" }, { "name": "'?'", "path": "a?b", "result": "R4: segment 1: character U+003F" }, { "name": "'\"'", "path": "a\"b", "result": "R4: segment 1: character U+0022" }, { "name": "'*', '\u003c', '\u003e' and '|'", "path": "a*b\u003cc\u003ed|e", "result": "R4: segment 1: character U+002A" }, { "name": "a dot and ZWJ", "path": ".‍", "result": "R3: segment 1: the segment is a dot without ZWNJ, ZWJ, VS15 and VS16" }, { "name": "a segment of ZWJ alone", "path": "‍", "result": "R3: segment 1: the segment is empty without ZWNJ, ZWJ, VS15 and VS16" }, { "name": "two dots", "path": "..", "result": "R3: segment 1: the segment is two dots" }, { "name": "one dot inside", "path": "a/./b", "result": "R3: segment 2: the segment is a dot" }, { "name": "a segment of 256 bytes", "path": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "result": "R3: segment 1: 256 bytes, more than 255" }, { "name": "a segment of 255 bytes", "path": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "result": "ok" }, { "name": "127 times U+0390: 381 UTF-16 units after NFD", "path": "ΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐ", "result": "R3: segment 1: its NFD is 381 UTF-16 code units, more than 255" }, { "name": "85 times U+0390: 255 UTF-16 units after NFD", "path": "ΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐΐ", "result": "ok" }, { "name": "VS16 after U+2764, which admits it", "path": "❤️.txt", "result": "ok" }, { "name": "VS16 after a", "path": "a️", "result": "R4b: segment 1: U+FE0F is not part of an emoji variation sequence" }, { "name": "ZWJ at the start", "path": "‍a", "result": "R4b: segment 1: U+200D at the start" }, { "name": "ZWJ at the end", "path": "a‍", "result": "R4b: segment 1: U+200D at the end" }, { "name": "two ZWJ in a row", "path": "a‍‍b", "result": "R4b: segment 1: U+200D right after U+200D" }, { "name": "ZWNJ and ZWJ in a row", "path": "a‌‍b", "result": "R4b: segment 1: U+200D right after U+200C" }, { "name": "ZWNJ inside a name", "path": "ab‌c", "result": "ok" }, { "name": "the rainbow flag", "path": "🏳️‍🌈", "result": "ok" }, { "name": "a family, joined with ZWJ", "path": "👨‍👩‍👧", "result": "ok" }, { "name": "a leading slash", "path": "/a", "result": "R2: segment 1 is empty" }, { "name": "two slashes", "path": "a//b", "result": "R2: segment 2 is empty" }, { "name": "a trailing slash", "path": "a/", "result": "R2: segment 2 is empty" }, { "name": "33 segments", "path": "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a", "result": "R2: 33 segments, more than 32" }, { "name": "a leading space", "path": " a", "result": "R5: segment 1: the segment starts with U+0020" }, { "name": "a trailing space", "path": "a ", "result": "R5: segment 1: the segment ends with U+0020" }, { "name": "a trailing dot", "path": "a.", "result": "R5: segment 1: the segment ends with '.'" }, { "name": "CON.txt", "path": "CON.txt", "result": "R6: segment 1: CON is a reserved device name" }, { "name": "con", "path": "con", "result": "R6: segment 1: CON is a reserved device name" }, { "name": "Aux with a space before the dot", "path": "Aux .log", "result": "R6: segment 1: AUX is a reserved device name" }, { "name": "COM with a superscript one", "path": "COM¹", "result": "R6: segment 1: COM¹ is a reserved device name" }, { "name": "lpt9.doc", "path": "lpt9.doc", "result": "R6: segment 1: LPT9 is a reserved device name" }, { "name": "CONIN$", "path": "CONIN$", "result": "R6: segment 1: CONIN$ is a reserved device name" }, { "name": ".datekeys-x at the first level", "path": ".datekeys-x", "result": "R10: the first segment starts with \".datekeys-\"" }, { "name": ".DateKeys-X at the first level, compared by its key", "path": ".DateKeys-X/b", "result": "R10: the first segment starts with \".datekeys-\"" }, { "name": ".datekeys-x at another level", "path": "a/.datekeys-x", "result": "ok" } ], "trees": [ { "name": "three files in two folders", "paths": [ "a/b", "a/c", "d" ], "result": "ok" }, { "name": "U+FF5E before U+1F600: UTF-8 byte order", "paths": [ "~", "😀" ], "result": "ok" }, { "name": "U+1F600 before U+FF5E: UTF-16 order, not UTF-8 byte order", "paths": [ "😀", "~" ], "result": "ERR_NON_CANONICAL_CBOR" }, { "name": "b and a, in that order", "paths": [ "b", "a" ], "result": "ERR_NON_CANONICAL_CBOR" }, { "name": "b/.. and a: R8 comes first, in layer 3", "paths": [ "b/..", "a" ], "result": "ERR_NON_CANONICAL_CBOR" }, { "name": "the same path twice", "paths": [ "a", "a" ], "result": "ERR_NON_CANONICAL_CBOR" }, { "name": "a path of 1025 bytes", "paths": [ "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a" ], "result": "ERR_NON_CANONICAL_CBOR" }, { "name": ".. and a: R3, in layer 4", "paths": [ "..", "a" ], "result": "ERR_HEAD_INVALID", "detail": "file 1: R3: segment 1: the segment is two dots" }, { "name": "A.txt and a.txt", "paths": [ "A.txt", "a.txt" ], "result": "ERR_HEAD_INVALID", "detail": "R7: path 2 collides with path 1 in segment 1" }, { "name": "A and a/b", "paths": [ "A", "a/b" ], "result": "ERR_HEAD_INVALID", "detail": "R7: path 2 collides with path 1 in segment 1" }, { "name": "a/b and a/b/c", "paths": [ "a/b", "a/b/c" ], "result": "ERR_HEAD_INVALID", "detail": "R7: path 2 makes a file of path 1 a folder, or the reverse, in segment 2" }, { "name": "Fotos/b and fotos/a", "paths": [ "Fotos/b", "fotos/a" ], "result": "ERR_HEAD_INVALID", "detail": "R7: path 2 collides with path 1 in segment 1" }, { "name": "STRASSE and Straße", "paths": [ "STRASSE", "Straße" ], "result": "ERR_HEAD_INVALID", "detail": "R7: path 2 collides with path 1 in segment 1" }, { "name": "k and the Kelvin sign", "paths": [ "k", "K" ], "result": "ERR_HEAD_INVALID", "detail": "R7: path 2 collides with path 1 in segment 1" }, { "name": "ab with and without ZWNJ", "paths": [ "ab", "a‌b" ], "result": "ERR_HEAD_INVALID", "detail": "R7: path 2 collides with path 1 in segment 1" }, { "name": "the NFD and the NFC of a name", "paths": [ "é", "é" ], "result": "ERR_HEAD_INVALID", "detail": "R7: path 2 collides with path 1 in segment 1" } ] }