mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-20 00:45:54 +03:00
fix(form,skd,init,meta-edit): развести экранирование атрибута и текста
esc_xml был один на две задачи, и в атрибутном контексте применялся текстовый вариант без ". form-compile с choiceParameters, имя которого содержит кавычку, выдавал <app:item name="Отбор.Наименование "кавычка"">: lxml падает с attributes construct error, то есть файл невалиден как XML. Затронуто 9 мест в form-compile и 3 в skd-compile, одинаково в обоих портах. Раундтрип через базу показал границу: в ТЕКСТЕ элемента платформа экранирует только & < > (кавычка и апостроф возвращаются сырыми байт-в-байт), а в ЗНАЧЕНИИ АТРИБУТА пишет " — внутри "..." литеральная кавычка невалидна. Поэтому две функции с говорящими именами, а не одна с флагом: esc_xml — значение атрибута: & < > " esc_xml_text — текст элемента: & < > Заодно закрыто расхождение портов в init-навыках: PY экранировал текст с ", PS1 — через SecurityElement::Escape (ещё и '), а epf-init/erf-init в PS1 не экранировали вовсе, из-за чего амперсанд в синониме давал невалидный XML. Кейсы: form-compile/attr-value-escaping, skd-compile/additional-properties-escaping, cf-init/synonym-escaping — все три проверены негативным прогоном на обоих портах и верификацией снэпшотов на платформе. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3c50d3caa0
commit
974ca3aac9
@@ -1,4 +1,4 @@
|
||||
# role-compile v1.19 — Compile 1C role from JSON (+detect_format_version: ветка автономной EPF/ERF)
|
||||
# role-compile v1.20 — Compile 1C role from JSON (+esc_xml/esc_xml_text: разное экранирование атрибута и текста)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -171,6 +171,12 @@ function X {
|
||||
}
|
||||
|
||||
function Esc-Xml {
|
||||
param([string]$s)
|
||||
# Эскейп ЗНАЧЕНИЯ АТРИБУТА: & < > и кавычка — внутри "..." литеральная " невалидна.
|
||||
return $s.Replace('&','&').Replace('<','<').Replace('>','>').Replace('"','"')
|
||||
}
|
||||
|
||||
function Esc-XmlText {
|
||||
# Экранирование ТЕКСТА элемента: только & < > . Кавычки в тексте платформа НЕ экранирует —
|
||||
# пишет литерально (проверено: 92142 сырых кавычки на корпус, ни одной "). " платформа
|
||||
# принимает, но при выгрузке нормализует обратно в кавычку → лишний шум в роундтрипе.
|
||||
@@ -701,11 +707,11 @@ X "`t`t`t<Name>$roleName</Name>"
|
||||
X "`t`t`t<Synonym>"
|
||||
X "`t`t`t`t<v8:item>"
|
||||
X "`t`t`t`t`t<v8:lang>ru</v8:lang>"
|
||||
X "`t`t`t`t`t<v8:content>$(Esc-Xml $synonym)</v8:content>"
|
||||
X "`t`t`t`t`t<v8:content>$(Esc-XmlText $synonym)</v8:content>"
|
||||
X "`t`t`t`t</v8:item>"
|
||||
X "`t`t`t</Synonym>"
|
||||
if ($comment) {
|
||||
X "`t`t`t<Comment>$(Esc-Xml $comment)</Comment>"
|
||||
X "`t`t`t<Comment>$(Esc-XmlText $comment)</Comment>"
|
||||
} else {
|
||||
X "`t`t`t<Comment/>"
|
||||
}
|
||||
@@ -742,7 +748,7 @@ foreach ($obj in $parsedObjects) {
|
||||
X "`t`t`t<value>$($right.Value)</value>"
|
||||
if ($right.Condition) {
|
||||
X "`t`t`t<restrictionByCondition>"
|
||||
X "`t`t`t`t<condition>$(Esc-Xml $right.Condition)</condition>"
|
||||
X "`t`t`t`t<condition>$(Esc-XmlText $right.Condition)</condition>"
|
||||
X "`t`t`t</restrictionByCondition>"
|
||||
}
|
||||
X "`t`t</right>"
|
||||
@@ -756,8 +762,8 @@ $templateCount = 0
|
||||
if ($def.templates) {
|
||||
foreach ($tpl in $def.templates) {
|
||||
X "`t<restrictionTemplate>"
|
||||
X "`t`t<name>$(Esc-Xml "$($tpl.name)")</name>"
|
||||
X "`t`t<condition>$(Esc-Xml "$($tpl.condition)")</condition>"
|
||||
X "`t`t<name>$(Esc-XmlText "$($tpl.name)")</name>"
|
||||
X "`t`t<condition>$(Esc-XmlText "$($tpl.condition)")</condition>"
|
||||
X "`t</restrictionTemplate>"
|
||||
$templateCount++
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user