Format 3, step 3: read capsule format 3 of spec v0.10
Syncs testdata with datekeys-go at the tag spec-v0.10 (cc35d2c) and
moves the reader to the DateKeys Protocol Specification v0.10. The
three capsule formats are read.
- framing: FORMAT_3, and isPadded for formats 2 and 3. control: schema
version 3, with the keys 6 and 7 of version 2. SPEC_VERSION is 0.10.
- open: OpenOptions.sink receives the files of a format 3 capsule
(sink.ts: Sink with begin, create, commit and abort, as capsule.Sink,
and MemorySink). Without one, open rejects with a TypeError right
after step 2, before any request, as ErrSinkRequired. Opened gains
head, verdicts, areaLen and unusableHeadExtensions.
- open3.ts: step 17 of format 3 in its substeps 17.2 to 17.8, as
openBody of the reference: a failure of age or a plaintext whose
length is not P prevails, the first failing substep decides, and the
codes other than ERR_INTEGRITY are reported only after reading
PAYLOAD_AGE to its end. Reads grow with the bytes received, never
with the lengths BODY declares. A failure of the sink is ERR_INTEGRITY
with its text, and the sink is aborted once after begin.
- The page: opener.ts opens the fixtures of format 3 into a
MemorySink; the open panel says that it does not deliver their files
yet, and the glosses of the steps name format 3. check-build.mjs
refuses to ship the heads, salts, comments and paths of the format 3
fixtures.
Tests: the 21 fixtures, format 3 laid out byte by byte from its record
and opened into a sink with its files and verdicts; the 209 cases of
the corpus from memory and from a Blob, with the code, the step and,
new, the exact text of capsule.Open, frozen by
scripts/mutation-go-texts.go in testing/mutation-texts.json, which
replays the corpus as internal/testkit does (its extension validator
texts included); the 5110 differential cases over 14 bases; paths,
path_fold, head_schema and security vectors; the control of schema
version 3 in cbor.json; and step 17 on crafted plaintexts sealed again
to I_PAYLOAD, whose texts capsule.Open gives on the same plaintexts.
ibe-vectors.json gains the nine format 3 fixtures from
scripts/ibe-go-vectors.go; the twelve before are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
{
"spec" : "0.10" ,
"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" ,
Key of words v2: salted with capsule_id, lowered with Unicode 18.0.0
As the spec v0.11 draft decides after its review (38.1), and as the Go
reference does from 2213b8c:
- dkc/wordkey.ts replaces inspector/wordkey.ts. The salt carries the
capsule_id too, so the same words give another key in each capsule;
the words are lowered with the new LOWERCASE table of pathrule.ts,
loaded on demand; checkWords refuses controls, invisible and
unassigned code points and counts only different words of three
letters or more, with the errors of Go. New vector of 38.1.
- encryptFiles takes the words and derives their key once it has drawn
capsule_id; the creator passes them, and the opener salts them with
the capsule_id of the capsule.
- /create asks for the words twice and shows how they are kept; the form
checks them with the tables of the platform, and the writer again with
those of Unicode 18.0.0.
- The tables, regenerated with the lower case, and testdata synced from
2213b8c; the frozen texts of Go for the invalid options, updated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 days ago
"tables_digest" : "07cf5d54aea1cd13a3ecef14a06976cc49a3cdad755cf9bc10395178b93aeb07" ,
Format 3, step 3: read capsule format 3 of spec v0.10
Syncs testdata with datekeys-go at the tag spec-v0.10 (cc35d2c) and
moves the reader to the DateKeys Protocol Specification v0.10. The
three capsule formats are read.
- framing: FORMAT_3, and isPadded for formats 2 and 3. control: schema
version 3, with the keys 6 and 7 of version 2. SPEC_VERSION is 0.10.
- open: OpenOptions.sink receives the files of a format 3 capsule
(sink.ts: Sink with begin, create, commit and abort, as capsule.Sink,
and MemorySink). Without one, open rejects with a TypeError right
after step 2, before any request, as ErrSinkRequired. Opened gains
head, verdicts, areaLen and unusableHeadExtensions.
- open3.ts: step 17 of format 3 in its substeps 17.2 to 17.8, as
openBody of the reference: a failure of age or a plaintext whose
length is not P prevails, the first failing substep decides, and the
codes other than ERR_INTEGRITY are reported only after reading
PAYLOAD_AGE to its end. Reads grow with the bytes received, never
with the lengths BODY declares. A failure of the sink is ERR_INTEGRITY
with its text, and the sink is aborted once after begin.
- The page: opener.ts opens the fixtures of format 3 into a
MemorySink; the open panel says that it does not deliver their files
yet, and the glosses of the steps name format 3. check-build.mjs
refuses to ship the heads, salts, comments and paths of the format 3
fixtures.
Tests: the 21 fixtures, format 3 laid out byte by byte from its record
and opened into a sink with its files and verdicts; the 209 cases of
the corpus from memory and from a Blob, with the code, the step and,
new, the exact text of capsule.Open, frozen by
scripts/mutation-go-texts.go in testing/mutation-texts.json, which
replays the corpus as internal/testkit does (its extension validator
texts included); the 5110 differential cases over 14 bases; paths,
path_fold, head_schema and security vectors; the control of schema
version 3 in cbor.json; and step 17 on crafted plaintexts sealed again
to I_PAYLOAD, whose texts capsule.Open gives on the same plaintexts.
ibe-vectors.json gains the nine format 3 fixtures from
scripts/ibe-go-vectors.go; the twelve before are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 week ago
"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" : "C O N .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" : "ab" ,
"result" : "R4: segment 1: unassigned U+0378"
} ,
{
"name" : "noncharacter U+FFFE" ,
"path" : "ab" ,
"result" : "R4: segment 1: unassigned U+FFFE"
} ,
{
"name" : "U+206A" ,
"path" : "a b" ,
"result" : "R4: segment 1: invisible U+206A"
} ,
{
"name" : "U+206F" ,
"path" : "a b" ,
"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" : "a b" ,
"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" : "informeanexo" ,
"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"
}
]
}