From 91e4e1948fea97b2103cfe54ffbe03ee134f09de Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Wed, 11 Feb 2026 09:44:23 +0300 Subject: [PATCH] Add comprehensive XML escaping to skd-compile Wrap all user-provided values in Esc-Xml() for safe XML output: - ValueType references (CatalogRef, DocumentRef, etc.) - Emit-ParamValue (all type branches: StandardPeriod, dateTime, boolean, decimal) - DataParameters (variant, boolean, dateTime values, viewMode, userSettingID) - Filter items (field, comparisonType, viewMode, userSettingID) - Selection fields, Order fields, GroupItems fields - GroupTemplates templateType, HorizontalAlign appearance value - Parameter use element Verified against 12,495 real DCS files: standard XML entity escaping (& < > ") matches 1C platform behavior exactly. Co-Authored-By: Claude Opus 4.6 --- .../skd-compile/scripts/skd-compile.ps1 | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/.claude/skills/skd-compile/scripts/skd-compile.ps1 b/.claude/skills/skd-compile/scripts/skd-compile.ps1 index 3e208fd5..d6597c74 100644 --- a/.claude/skills/skd-compile/scripts/skd-compile.ps1 +++ b/.claude/skills/skd-compile/scripts/skd-compile.ps1 @@ -197,15 +197,15 @@ function Emit-ValueType { # cfg: references (CatalogRef.XXX, DocumentRef.XXX, EnumRef.XXX, etc.) if ($typeStr -match '^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef)\.') { - X "$indentcfg:$typeStr" + X "$indentcfg:$(Esc-Xml $typeStr)" return } # Fallback if ($typeStr.Contains('.')) { - X "$indentcfg:$typeStr" + X "$indentcfg:$(Esc-Xml $typeStr)" } else { - X "$indent$typeStr" + X "$indent$(Esc-Xml $typeStr)" } } @@ -465,7 +465,7 @@ function Emit-DataSources { foreach ($ds in $dataSources) { X "`t" X "`t`t$(Esc-Xml $ds.name)" - X "`t`t$($ds.type)" + X "`t`t$(Esc-Xml $ds.type)" X "`t" } } @@ -591,7 +591,7 @@ function Emit-Field { X "$indent`t`t" X "$indent`t`t`t$(Esc-Xml $key)" if ($key -eq "ГоризонтальноеПоложение") { - X "$indent`t`t`t$val" + X "$indent`t`t`t$(Esc-Xml $val)" } else { X "$indent`t`t`t$(Esc-Xml $val)" } @@ -797,7 +797,7 @@ function Emit-SingleParam { # Use if ($p -isnot [string] -and $p.use) { - X "`t`t$($p.use)" + X "`t`t$(Esc-Xml "$($p.use)")" } X "`t" @@ -849,22 +849,22 @@ function Emit-ParamValue { if ($type -eq "StandardPeriod") { # val is a period variant string like "LastMonth" X "$indent" - X "$indent`t$valStr" + X "$indent`t$(Esc-Xml $valStr)" X "$indent" } elseif ($type -match '^date') { - X "$indent$valStr" + X "$indent$(Esc-Xml $valStr)" } elseif ($type -eq "boolean") { - X "$indent$valStr" + X "$indent$(Esc-Xml $valStr)" } elseif ($type -match '^decimal') { - X "$indent$valStr" + X "$indent$(Esc-Xml $valStr)" } elseif ($type -match '^string') { X "$indent$(Esc-Xml $valStr)" } else { # Guess from value if ($valStr -match '^\d{4}-\d{2}-\d{2}T') { - X "$indent$valStr" + X "$indent$(Esc-Xml $valStr)" } elseif ($valStr -eq "true" -or $valStr -eq "false") { - X "$indent$valStr" + X "$indent$(Esc-Xml $valStr)" } else { X "$indent$(Esc-Xml $valStr)" } @@ -899,7 +899,7 @@ function Emit-GroupTemplates { foreach ($gt in $def.groupTemplates) { X "`t" X "`t`t$(Esc-Xml "$($gt.groupField)")" - X "`t`t$($gt.templateType)" + X "`t`t$(Esc-Xml "$($gt.templateType)")" X "`t`t" X "`t" } @@ -919,12 +919,12 @@ function Emit-Selection { X "$indent`t" } else { X "$indent`t" - X "$indent`t`t$item" + X "$indent`t`t$(Esc-Xml $item)" X "$indent`t" } } else { X "$indent`t" - X "$indent`t`t$($item.field)" + X "$indent`t`t$(Esc-Xml "$($item.field)")" if ($item.title) { X "$indent`t`t" X "$indent`t`t`t" @@ -968,11 +968,11 @@ function Emit-FilterItem { X "$indent`tfalse" } - X "$indent`t$($item.field)" + X "$indent`t$(Esc-Xml "$($item.field)")" $compType = $script:comparisonTypes["$($item.op)"] if (-not $compType) { $compType = "$($item.op)" } - X "$indent`t$compType" + X "$indent`t$(Esc-Xml $compType)" # Right value if ($null -ne $item.value) { @@ -1003,12 +1003,12 @@ function Emit-FilterItem { } if ($item.viewMode) { - X "$indent`t$($item.viewMode)" + X "$indent`t$(Esc-Xml "$($item.viewMode)")" } if ($item.userSettingID) { $uid = if ("$($item.userSettingID)" -eq "auto") { New-Guid-String } else { "$($item.userSettingID)" } - X "$indent`t$uid" + X "$indent`t$(Esc-Xml $uid)" } X "$indent" @@ -1067,7 +1067,7 @@ function Emit-Order { if ($parts.Count -gt 1 -and $parts[1] -match '^(?i)desc$') { $dir = "Desc" } elseif ($parts.Count -gt 1 -and $parts[1] -match '^(?i)asc$') { $dir = "Asc" } X "$indent`t" - X "$indent`t`t$field" + X "$indent`t`t$(Esc-Xml $field)" X "$indent`t`t$dir" X "$indent`t" } @@ -1145,30 +1145,30 @@ function Emit-DataParameters { if ($dp.value -is [PSCustomObject] -and $dp.value.variant) { # StandardPeriod (object form from JSON) X "$indent`t`t" - X "$indent`t`t`t$($dp.value.variant)" + X "$indent`t`t`t$(Esc-Xml "$($dp.value.variant)")" X "$indent`t`t" } elseif ($dp.value -is [hashtable] -and $dp.value.variant) { # StandardPeriod (hashtable from shorthand parser) X "$indent`t`t" - X "$indent`t`t`t$($dp.value.variant)" + X "$indent`t`t`t$(Esc-Xml "$($dp.value.variant)")" X "$indent`t`t" } elseif ($dp.value -is [bool]) { $bv = "$($dp.value)".ToLower() - X "$indent`t`t$bv" + X "$indent`t`t$(Esc-Xml $bv)" } elseif ("$($dp.value)" -match '^\d{4}-\d{2}-\d{2}T') { - X "$indent`t`t$($dp.value)" + X "$indent`t`t$(Esc-Xml "$($dp.value)")" } else { X "$indent`t`t$(Esc-Xml "$($dp.value)")" } } if ($dp.viewMode) { - X "$indent`t`t$($dp.viewMode)" + X "$indent`t`t$(Esc-Xml "$($dp.viewMode)")" } if ($dp.userSettingID) { $uid = if ("$($dp.userSettingID)" -eq "auto") { New-Guid-String } else { "$($dp.userSettingID)" } - X "$indent`t`t$uid" + X "$indent`t`t$(Esc-Xml $uid)" } X "$indent`t" @@ -1187,7 +1187,7 @@ function Emit-GroupItems { foreach ($field in $groupBy) { if ($field -is [string]) { X "$indent`t" - X "$indent`t`t$field" + X "$indent`t`t$(Esc-Xml $field)" X "$indent`t`tItems" X "$indent`t`tNone" X "$indent`t`t0001-01-01T00:00:00" @@ -1196,11 +1196,11 @@ function Emit-GroupItems { } else { # Object form X "$indent`t" - X "$indent`t`t$($field.field)" + X "$indent`t`t$(Esc-Xml "$($field.field)")" $gt = if ($field.groupType) { "$($field.groupType)" } else { "Items" } - X "$indent`t`t$gt" + X "$indent`t`t$(Esc-Xml $gt)" $pat = if ($field.periodAdditionType) { "$($field.periodAdditionType)" } else { "None" } - X "$indent`t`t$pat" + X "$indent`t`t$(Esc-Xml $pat)" X "$indent`t`t0001-01-01T00:00:00" X "$indent`t`t0001-01-01T00:00:00" X "$indent`t"