mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-10 10:06:15 -08:00
fix(packaging): reject advanced Snap YAML semantics
This commit is contained in:
1 parent
406a20851b
commit
809182ca06
2 files changed
+116
No files matched your search
@@ -464,6 +464,76 @@ function yamlSequenceIncludes(lines, entry, expected) {
|
||||
);
|
||||
}
|
||||
|
||||
function yamlSyntaxOutsideQuotedScalars(line) {
|
||||
let result = '';
|
||||
let quote = null;
|
||||
for (let index = 0; index < line.length; index += 1) {
|
||||
const character = line[index];
|
||||
if (quote === "'") {
|
||||
if (character === "'" && line[index + 1] === "'") {
|
||||
result += ' ';
|
||||
index += 1;
|
||||
} else {
|
||||
result += ' ';
|
||||
if (character === "'") {
|
||||
quote = null;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (quote === '"') {
|
||||
result += ' ';
|
||||
if (character === '\\') {
|
||||
result += ' ';
|
||||
index += 1;
|
||||
} else if (character === '"') {
|
||||
quote = null;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (character === '#') {
|
||||
break;
|
||||
}
|
||||
if (character === "'" || character === '"') {
|
||||
quote = character;
|
||||
result += ' ';
|
||||
continue;
|
||||
}
|
||||
result += character;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function containsUnsupportedYamlSemantics(lines) {
|
||||
let blockScalarParentIndent = null;
|
||||
for (const line of lines) {
|
||||
if (!line.trim()) {
|
||||
continue;
|
||||
}
|
||||
const lineIndent = line.length - line.trimStart().length;
|
||||
if (
|
||||
blockScalarParentIndent !== null &&
|
||||
lineIndent > blockScalarParentIndent
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
blockScalarParentIndent = null;
|
||||
const syntax = yamlSyntaxOutsideQuotedScalars(line);
|
||||
if (
|
||||
/(?:^|[\s:[\]{},])(?:[&*][A-Za-z0-9_-]+|![^\s,[\]{}]+)(?=$|[\s,\]}])/.test(
|
||||
syntax
|
||||
) ||
|
||||
/(?:^|\s)<<\s*:/.test(syntax)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (/:\s*[>|][+-]?\d?\s*$/.test(syntax)) {
|
||||
blockScalarParentIndent = lineIndent;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function validateExtractedSnapMetadata(extractionRoot) {
|
||||
const snapYamlPath = path.join(extractionRoot, 'meta', 'snap.yaml');
|
||||
let stat;
|
||||
@@ -492,6 +562,11 @@ export function validateExtractedSnapMetadata(extractionRoot) {
|
||||
];
|
||||
}
|
||||
const lines = contents.split(/\r?\n/);
|
||||
if (containsUnsupportedYamlSemantics(lines)) {
|
||||
return [
|
||||
'Extracted Snap metadata must not use YAML anchors, aliases, merge keys, or custom tags.',
|
||||
];
|
||||
}
|
||||
const errors = [];
|
||||
const plugs = singleYamlMappingEntry(
|
||||
lines,
|
||||
|
||||
@@ -575,6 +575,8 @@ test('requires a private top-level shared-memory plug used by the Snap app', ()
|
||||
|
||||
const validSnapYaml = [
|
||||
'name: iptvnator',
|
||||
'summary: "*literal &anchor !tag <<: is quoted"',
|
||||
'# *commented-alias &commented-anchor !commented-tag',
|
||||
'apps:',
|
||||
' iptvnator:',
|
||||
' command: iptvnator',
|
||||
@@ -660,6 +662,45 @@ test('requires a private top-level shared-memory plug used by the Snap app', ()
|
||||
),
|
||||
/plug keys.*unique/i,
|
||||
],
|
||||
[
|
||||
(contents) =>
|
||||
[
|
||||
'shared-interface: &sharedInterface shared-memory',
|
||||
contents.replace(
|
||||
'\nplugs:\n',
|
||||
'\nplugs:\n alias-plug:\n interface: *sharedInterface\n'
|
||||
),
|
||||
].join('\n'),
|
||||
/anchors, aliases, merge keys, or custom tags/i,
|
||||
],
|
||||
[
|
||||
(contents) =>
|
||||
[
|
||||
'shared-interface: &sharedInterface shared-memory',
|
||||
`${contents}slots:\n alias-slot:\n interface: *sharedInterface\n`,
|
||||
].join('\n'),
|
||||
/anchors, aliases, merge keys, or custom tags/i,
|
||||
],
|
||||
[
|
||||
(contents) =>
|
||||
contents.replace(
|
||||
'\nplugs:\n',
|
||||
'\nplugs:\n tagged:\n interface: !shared-memory shared-memory\n'
|
||||
),
|
||||
/anchors, aliases, merge keys, or custom tags/i,
|
||||
],
|
||||
[
|
||||
(contents) =>
|
||||
[
|
||||
'shared-plug: &sharedPlug',
|
||||
' interface: network',
|
||||
contents.replace(
|
||||
'\nplugs:\n',
|
||||
'\nplugs:\n merged:\n <<: *sharedPlug\n'
|
||||
),
|
||||
].join('\n'),
|
||||
/anchors, aliases, merge keys, or custom tags/i,
|
||||
],
|
||||
[
|
||||
(contents) =>
|
||||
contents.replace(
|
||||
|
||||
Reference in new issue
Block a user