@@ -187,22 +187,6 @@ mapping: !<tag:example.test,2026:object>
187187 $result.mapping.name | Should - Be ' safe'
188188 }
189189
190- It ' decodes percent escapes in expanded representation tags' {
191- $escaped = Get-TestYamlRepresentationRoot - Yaml (
192- " %TAG !e! tag:example.com,2000:app/`n --- !e!tag%21 value"
193- )
194- $multibyte = Get-TestYamlRepresentationRoot - Yaml (
195- " %TAG !e! tag:example.com,2000:app/`n --- !e!caf%C3%A9 value"
196- )
197-
198- $escaped.Tag | Should - Be ' tag:example.com,2000:app/tag!'
199- $escaped.HasUnknownTag | Should - BeTrue
200- $multibyte.Tag | Should - Be (
201- ' tag:example.com,2000:app/caf{0}' -f [char ] 0x00E9
202- )
203- $multibyte.HasUnknownTag | Should - BeTrue
204- }
205-
206190 It ' retains unknown local and global tags before neutral value projection' {
207191 $local = Get-TestYamlRepresentationRoot - Yaml ' !local value'
208192 $global = Get-TestYamlRepresentationRoot - Yaml (
@@ -394,6 +378,49 @@ date: !!timestamp 2001-12-14
394378 { $largeInteger | ConvertFrom-Yaml - MaxNumericLength 4096 } | Should - Throw
395379 }
396380
381+ It ' decodes percent escapes in expanded tags using UTF-8' {
382+ $yaml = @'
383+ %TAG !e! tag:example.com,2000:app/
384+ ---
385+ first: !e!tag%21 value
386+ second: !e!currency%E2%82%AC amount
387+ '@
388+ $representation = Read-YamlStreamCore - Yaml $yaml - Depth 32 - MaxNodes 64 - MaxAliases 16 `
389+ - MaxScalarLength 4096 - MaxTagLength 1024 - MaxTotalTagLength 4096 `
390+ - MaxNumericLength 64
391+
392+ $representation.Value.Count | Should - Be 1
393+ $entries = $representation.Value [0 ].Entries
394+ $entries.Count | Should - Be 2
395+ $entries [0 ].Value.Tag | Should - Be ' tag:example.com,2000:app/tag!'
396+ $entries [1 ].Value.Tag | Should - Be (' tag:example.com,2000:app/currency' + [char ] 0x20AC )
397+ }
398+
399+ It ' rejects malformed or non-UTF8 tag percent escapes' {
400+ $truncated = @'
401+ %TAG !e! tag:example.com,2000:app/
402+ ---
403+ !e!tag%2 value
404+ '@
405+ $invalidHex = @'
406+ %TAG !e! tag:example.com,2000:app/
407+ ---
408+ !e!tag%ZZ value
409+ '@
410+ $invalidUtf8 = @'
411+ %TAG !e! tag:example.com,2000:app/
412+ ---
413+ !e!tag%E2%28%A1 value
414+ '@
415+
416+ ($truncated | Test-Yaml ) | Should - BeFalse
417+ ($invalidHex | Test-Yaml ) | Should - BeFalse
418+ ($invalidUtf8 | Test-Yaml ) | Should - BeFalse
419+ { $truncated | ConvertFrom-Yaml } | Should - Throw
420+ { $invalidHex | ConvertFrom-Yaml } | Should - Throw
421+ { $invalidUtf8 | ConvertFrom-Yaml } | Should - Throw
422+ }
423+
397424 It ' bounds expanded-tag storage and rejects huge numerics promptly' {
398425 $prefix = ' x' * 20000
399426 $taggedItems = 1 .. 500 | ForEach-Object { ' - !e!value item' }
0 commit comments