@bastani/atomic 0.9.0-alpha.1 → 0.9.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/dist/builtin/cursor/CHANGELOG.md +6 -0
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/intercom/CHANGELOG.md +6 -0
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/mcp/CHANGELOG.md +6 -0
- package/dist/builtin/mcp/package.json +3 -3
- package/dist/builtin/subagents/CHANGELOG.md +6 -0
- package/dist/builtin/subagents/package.json +4 -4
- package/dist/builtin/web-access/CHANGELOG.md +6 -0
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +12 -0
- package/dist/builtin/workflows/README.md +189 -122
- package/dist/builtin/workflows/builtin/deep-research-codebase.ts +30 -27
- package/dist/builtin/workflows/builtin/goal-runner.ts +10 -17
- package/dist/builtin/workflows/builtin/goal.ts +39 -44
- package/dist/builtin/workflows/builtin/index.d.ts +1 -0
- package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +16 -17
- package/dist/builtin/workflows/builtin/open-claude-design.d.ts +1 -0
- package/dist/builtin/workflows/builtin/open-claude-design.ts +42 -50
- package/dist/builtin/workflows/builtin/ralph.ts +44 -41
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/src/authoring/typebox-defaults.d.ts +41 -0
- package/dist/builtin/workflows/src/authoring/typebox-defaults.ts +217 -0
- package/dist/builtin/workflows/src/authoring/workflow.ts +184 -0
- package/dist/builtin/workflows/src/authoring.d.ts +14 -66
- package/dist/builtin/workflows/src/engine/graph-inference.ts +100 -0
- package/dist/builtin/workflows/src/engine/options.ts +40 -0
- package/dist/builtin/workflows/src/engine/primitives/chain.ts +29 -0
- package/dist/builtin/workflows/src/engine/primitives/exit.ts +2 -0
- package/dist/builtin/workflows/src/engine/primitives/parallel.ts +47 -0
- package/dist/builtin/workflows/src/engine/primitives/task.ts +108 -0
- package/dist/builtin/workflows/src/engine/primitives/ui.ts +41 -0
- package/dist/builtin/workflows/src/engine/primitives/workflow.ts +159 -0
- package/dist/builtin/workflows/src/engine/replay.ts +8 -0
- package/dist/builtin/workflows/src/engine/run.ts +356 -0
- package/dist/builtin/workflows/src/engine/runtime.ts +160 -0
- package/dist/builtin/workflows/src/extension/workflow-module-loader.ts +9 -3
- package/dist/builtin/workflows/src/extension/workflow-schema.ts +0 -18
- package/dist/builtin/workflows/src/index.ts +0 -2
- package/dist/builtin/workflows/src/runs/background/runner.ts +6 -3
- package/dist/builtin/workflows/src/runs/foreground/executor-child-boundary.ts +3 -3
- package/dist/builtin/workflows/src/runs/foreground/executor-child-helpers.ts +4 -4
- package/dist/builtin/workflows/src/runs/foreground/executor-child-workflow.ts +1 -158
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-outputs.ts +2 -2
- package/dist/builtin/workflows/src/runs/foreground/executor-prompt-nodes.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-run.ts +1 -359
- package/dist/builtin/workflows/src/runs/foreground/executor-scheduler.ts +1 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-call.ts +2 -5
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +12 -4
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-replay.ts +4 -3
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-types.ts +9 -2
- package/dist/builtin/workflows/src/runs/foreground/executor-task-context.ts +2 -132
- package/dist/builtin/workflows/src/runs/foreground/executor-types.ts +2 -2
- package/dist/builtin/workflows/src/runs/shared/graph-inference.ts +2 -100
- package/dist/builtin/workflows/src/sdk-surface.ts +6 -9
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.d.ts +9 -3
- package/dist/builtin/workflows/src/shared/authoring-contract-stage.ts +17 -3
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.d.ts +3 -33
- package/dist/builtin/workflows/src/shared/authoring-contract-ui.ts +9 -81
- package/dist/builtin/workflows/src/shared/types.ts +25 -8
- package/dist/builtin/workflows/src/shared/workflow-authoring-types.d.ts +49 -0
- package/dist/builtin/workflows/src/shared/workflow-authoring-types.ts +84 -0
- package/dist/builtin/workflows/src/workflows/registry.ts +7 -3
- package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-auto-compaction.js +6 -1
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-bash.d.ts.map +1 -1
- package/dist/core/agent-session-bash.js +0 -5
- package/dist/core/agent-session-bash.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +0 -2
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +0 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +0 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
- package/dist/core/agent-session-tool-registry.js +0 -2
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +0 -2
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +0 -2
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +0 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/atomic-guide-command.d.ts.map +1 -1
- package/dist/core/atomic-guide-command.js +1 -1
- package/dist/core/atomic-guide-command.js.map +1 -1
- package/dist/core/extensions/loader-core.d.ts +1 -3
- package/dist/core/extensions/loader-core.d.ts.map +1 -1
- package/dist/core/extensions/loader-core.js +13 -6
- package/dist/core/extensions/loader-core.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts +7 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +34 -2
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +2 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +2 -1
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/model-registry-builtins.d.ts.map +1 -1
- package/dist/core/model-registry-builtins.js +6 -0
- package/dist/core/model-registry-builtins.js.map +1 -1
- package/dist/core/model-registry-schemas.d.ts +65 -13
- package/dist/core/model-registry-schemas.d.ts.map +1 -1
- package/dist/core/model-registry-schemas.js +10 -0
- package/dist/core/model-registry-schemas.js.map +1 -1
- package/dist/core/resource-loader-core.d.ts +1 -0
- package/dist/core/resource-loader-core.d.ts.map +1 -1
- package/dist/core/resource-loader-core.js +2 -0
- package/dist/core/resource-loader-core.js.map +1 -1
- package/dist/core/resource-loader-extensions.d.ts.map +1 -1
- package/dist/core/resource-loader-extensions.js +3 -3
- package/dist/core/resource-loader-extensions.js.map +1 -1
- package/dist/core/resource-loader-internals.d.ts +1 -0
- package/dist/core/resource-loader-internals.d.ts.map +1 -1
- package/dist/core/resource-loader-internals.js.map +1 -1
- package/dist/core/resource-loader-reload.d.ts.map +1 -1
- package/dist/core/resource-loader-reload.js +6 -2
- package/dist/core/resource-loader-reload.js.map +1 -1
- package/dist/core/sdk-exports.d.ts +1 -1
- package/dist/core/sdk-exports.d.ts.map +1 -1
- package/dist/core/sdk-exports.js.map +1 -1
- package/dist/core/sdk-types.d.ts +0 -3
- package/dist/core/sdk-types.d.ts.map +1 -1
- package/dist/core/sdk-types.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +0 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager-history.d.ts.map +1 -1
- package/dist/core/session-manager-history.js +2 -1
- package/dist/core/session-manager-history.js.map +1 -1
- package/dist/core/tools/bash.d.ts +0 -5
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +10 -11
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff-preserve.d.ts +18 -0
- package/dist/core/tools/edit-diff-preserve.d.ts.map +1 -0
- package/dist/core/tools/edit-diff-preserve.js +85 -0
- package/dist/core/tools/edit-diff-preserve.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +3 -2
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +15 -18
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/index.d.ts +0 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +0 -1
- package/dist/core/tools/index.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +2 -2
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/model-search.d.ts +5 -0
- package/dist/modes/interactive/model-search.d.ts.map +1 -1
- package/dist/modes/interactive/model-search.js +9 -0
- package/dist/modes/interactive/model-search.js.map +1 -1
- package/dist/utils/shell.d.ts +1 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +12 -5
- package/dist/utils/shell.js.map +1 -1
- package/docs/custom-provider.md +4 -3
- package/docs/models.md +3 -2
- package/docs/packages.md +2 -2
- package/docs/quickstart.md +1 -1
- package/docs/sdk.md +2 -40
- package/docs/security.md +1 -1
- package/docs/workflows.md +238 -173
- package/package.json +5 -5
- package/dist/builtin/workflows/src/workflows/define-workflow.ts +0 -277
- package/dist/core/tools/bash-policy-compile.d.ts +0 -5
- package/dist/core/tools/bash-policy-compile.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-compile.js +0 -241
- package/dist/core/tools/bash-policy-compile.js.map +0 -1
- package/dist/core/tools/bash-policy-evaluate.d.ts +0 -3
- package/dist/core/tools/bash-policy-evaluate.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-evaluate.js +0 -92
- package/dist/core/tools/bash-policy-evaluate.js.map +0 -1
- package/dist/core/tools/bash-policy-format.d.ts +0 -5
- package/dist/core/tools/bash-policy-format.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-format.js +0 -49
- package/dist/core/tools/bash-policy-format.js.map +0 -1
- package/dist/core/tools/bash-policy-parser.d.ts +0 -4
- package/dist/core/tools/bash-policy-parser.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-parser.js +0 -155
- package/dist/core/tools/bash-policy-parser.js.map +0 -1
- package/dist/core/tools/bash-policy-segment.d.ts +0 -3
- package/dist/core/tools/bash-policy-segment.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-segment.js +0 -275
- package/dist/core/tools/bash-policy-segment.js.map +0 -1
- package/dist/core/tools/bash-policy-shell.d.ts +0 -11
- package/dist/core/tools/bash-policy-shell.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-shell.js +0 -267
- package/dist/core/tools/bash-policy-shell.js.map +0 -1
- package/dist/core/tools/bash-policy-types.d.ts +0 -146
- package/dist/core/tools/bash-policy-types.d.ts.map +0 -1
- package/dist/core/tools/bash-policy-types.js +0 -2
- package/dist/core/tools/bash-policy-types.js.map +0 -1
- package/dist/core/tools/bash-policy.d.ts +0 -6
- package/dist/core/tools/bash-policy.d.ts.map +0 -1
- package/dist/core/tools/bash-policy.js +0 -5
- package/dist/core/tools/bash-policy.js.map +0 -1
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
import { findClosingBacktick, findClosingParen, isCommandSubstitutionAt, isProcessSubstitutionAt, isWhitespace, readShellWord, } from "./bash-policy-shell.js";
|
|
2
|
-
const UNSUPPORTED_CONTROL_HEADS = new Set([
|
|
3
|
-
"!",
|
|
4
|
-
"[[",
|
|
5
|
-
"]]",
|
|
6
|
-
"case",
|
|
7
|
-
"coproc",
|
|
8
|
-
"do",
|
|
9
|
-
"done",
|
|
10
|
-
"elif",
|
|
11
|
-
"else",
|
|
12
|
-
"esac",
|
|
13
|
-
"fi",
|
|
14
|
-
"for",
|
|
15
|
-
"function",
|
|
16
|
-
"if",
|
|
17
|
-
"in",
|
|
18
|
-
"select",
|
|
19
|
-
"then",
|
|
20
|
-
"time",
|
|
21
|
-
"until",
|
|
22
|
-
"while",
|
|
23
|
-
"{",
|
|
24
|
-
"}",
|
|
25
|
-
]);
|
|
26
|
-
function isAsciiDigit(char) {
|
|
27
|
-
return char !== undefined && char >= "0" && char <= "9";
|
|
28
|
-
}
|
|
29
|
-
function leadingRedirectionTokenAt(input, index) {
|
|
30
|
-
let operatorStart = index;
|
|
31
|
-
while (isAsciiDigit(input[operatorStart]))
|
|
32
|
-
operatorStart += 1;
|
|
33
|
-
const hasDescriptorPrefix = operatorStart > index;
|
|
34
|
-
const char = input[operatorStart];
|
|
35
|
-
const next = input[operatorStart + 1];
|
|
36
|
-
const afterNext = input[operatorStart + 2];
|
|
37
|
-
if (char === undefined)
|
|
38
|
-
return undefined;
|
|
39
|
-
if (hasDescriptorPrefix && char !== "<" && char !== ">")
|
|
40
|
-
return undefined;
|
|
41
|
-
if (!hasDescriptorPrefix && (char === "<" || char === ">") && next === "(") {
|
|
42
|
-
return undefined;
|
|
43
|
-
}
|
|
44
|
-
let operator;
|
|
45
|
-
if (char === "&" && next === ">") {
|
|
46
|
-
operator = afterNext === ">" ? "&>>" : "&>";
|
|
47
|
-
}
|
|
48
|
-
else if (char === "<") {
|
|
49
|
-
if (next === "<")
|
|
50
|
-
operator = "<<";
|
|
51
|
-
else if (next === "&")
|
|
52
|
-
operator = "<&";
|
|
53
|
-
else if (next === ">")
|
|
54
|
-
operator = "<>";
|
|
55
|
-
else
|
|
56
|
-
operator = "<";
|
|
57
|
-
}
|
|
58
|
-
else if (char === ">") {
|
|
59
|
-
if (next === ">")
|
|
60
|
-
operator = ">>";
|
|
61
|
-
else if (next === "|")
|
|
62
|
-
operator = ">|";
|
|
63
|
-
else if (next === "&")
|
|
64
|
-
operator = ">&";
|
|
65
|
-
else
|
|
66
|
-
operator = ">";
|
|
67
|
-
}
|
|
68
|
-
return operator === undefined ? undefined : `${input.slice(index, operatorStart)}${operator}`;
|
|
69
|
-
}
|
|
70
|
-
function isEnvAssignmentWord(word) {
|
|
71
|
-
return /^[A-Za-z_][A-Za-z0-9_]*(?:\+)?=/.test(word);
|
|
72
|
-
}
|
|
73
|
-
function attachedRedirectionOperatorAt(input, index) {
|
|
74
|
-
const char = input[index];
|
|
75
|
-
const next = input[index + 1];
|
|
76
|
-
const afterNext = input[index + 2];
|
|
77
|
-
if ((char === "<" || char === ">") && next === "(") {
|
|
78
|
-
return undefined;
|
|
79
|
-
}
|
|
80
|
-
if (char === "&" && next === ">") {
|
|
81
|
-
return afterNext === ">" ? "&>>" : "&>";
|
|
82
|
-
}
|
|
83
|
-
if (char === "<") {
|
|
84
|
-
if (next === "<")
|
|
85
|
-
return "<<";
|
|
86
|
-
if (next === "&")
|
|
87
|
-
return "<&";
|
|
88
|
-
if (next === ">")
|
|
89
|
-
return "<>";
|
|
90
|
-
return "<";
|
|
91
|
-
}
|
|
92
|
-
if (char === ">") {
|
|
93
|
-
if (next === ">")
|
|
94
|
-
return ">>";
|
|
95
|
-
if (next === "|")
|
|
96
|
-
return ">|";
|
|
97
|
-
if (next === "&")
|
|
98
|
-
return ">&";
|
|
99
|
-
return ">";
|
|
100
|
-
}
|
|
101
|
-
return undefined;
|
|
102
|
-
}
|
|
103
|
-
function attachedCommandHeadRedirection(input, start, end) {
|
|
104
|
-
let quote = "none";
|
|
105
|
-
for (let i = start; i < end; i += 1) {
|
|
106
|
-
const char = input[i];
|
|
107
|
-
if (quote === "single") {
|
|
108
|
-
if (char === "'")
|
|
109
|
-
quote = "none";
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
if (char === "\\") {
|
|
113
|
-
i += 1;
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
if (quote === "double") {
|
|
117
|
-
if (char === "\"") {
|
|
118
|
-
quote = "none";
|
|
119
|
-
continue;
|
|
120
|
-
}
|
|
121
|
-
if (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {
|
|
122
|
-
const close = findClosingParen(input, i + 1, isCommandSubstitutionAt(input, i) ? "command substitution `$(`" : "process substitution");
|
|
123
|
-
if (close.ok)
|
|
124
|
-
i = close.closeIndex;
|
|
125
|
-
continue;
|
|
126
|
-
}
|
|
127
|
-
if (char === "`") {
|
|
128
|
-
const close = findClosingBacktick(input, i);
|
|
129
|
-
if (close.ok)
|
|
130
|
-
i = close.closeIndex;
|
|
131
|
-
}
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
if (char === "'") {
|
|
135
|
-
quote = "single";
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
if (char === "\"") {
|
|
139
|
-
quote = "double";
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
if (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {
|
|
143
|
-
const close = findClosingParen(input, i + 1, isCommandSubstitutionAt(input, i) ? "command substitution `$(`" : "process substitution");
|
|
144
|
-
if (close.ok)
|
|
145
|
-
i = close.closeIndex;
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
if (char === "`") {
|
|
149
|
-
const close = findClosingBacktick(input, i);
|
|
150
|
-
if (close.ok)
|
|
151
|
-
i = close.closeIndex;
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
const operator = attachedRedirectionOperatorAt(input, i);
|
|
155
|
-
if (operator !== undefined && i > start) {
|
|
156
|
-
return { token: operator, offset: i };
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
return undefined;
|
|
160
|
-
}
|
|
161
|
-
function validateLiteralCommandHead(head, metadata) {
|
|
162
|
-
if (head.length === 0) {
|
|
163
|
-
return { ok: false, reason: "empty command heads are not supported by bash policy segments mode" };
|
|
164
|
-
}
|
|
165
|
-
if (metadata.sawSingleQuote || metadata.sawDoubleQuote) {
|
|
166
|
-
return { ok: false, reason: "quoted or quote-constructed command heads are not supported by bash policy segments mode" };
|
|
167
|
-
}
|
|
168
|
-
if (metadata.sawEscape) {
|
|
169
|
-
return { ok: false, reason: "escape-constructed command heads are not supported by bash policy segments mode" };
|
|
170
|
-
}
|
|
171
|
-
if (metadata.sawCommandSubstitution || metadata.sawProcessSubstitution || metadata.sawBacktick) {
|
|
172
|
-
return { ok: false, reason: "command, process, and backtick substitutions are not supported in command heads by bash policy segments mode" };
|
|
173
|
-
}
|
|
174
|
-
if (metadata.sawParameterExpansion) {
|
|
175
|
-
return { ok: false, reason: "parameter-expanded command heads are not supported by bash policy segments mode" };
|
|
176
|
-
}
|
|
177
|
-
if (metadata.sawTildePrefix) {
|
|
178
|
-
return { ok: false, reason: "tilde-expanded command heads are not supported by bash policy segments mode" };
|
|
179
|
-
}
|
|
180
|
-
if (metadata.sawGlobPattern) {
|
|
181
|
-
return { ok: false, reason: "glob-expanded command heads are not supported by bash policy segments mode" };
|
|
182
|
-
}
|
|
183
|
-
if (metadata.sawBraceExpansion) {
|
|
184
|
-
return { ok: false, reason: "brace-expanded command heads are not supported by bash policy segments mode" };
|
|
185
|
-
}
|
|
186
|
-
return { ok: true };
|
|
187
|
-
}
|
|
188
|
-
export function buildSegment(rawSegment, absoluteStart, absoluteEnd, source) {
|
|
189
|
-
let cursor = 0;
|
|
190
|
-
while (cursor < rawSegment.length && isWhitespace(rawSegment[cursor]))
|
|
191
|
-
cursor += 1;
|
|
192
|
-
if (cursor >= rawSegment.length)
|
|
193
|
-
return { ok: true };
|
|
194
|
-
while (cursor < rawSegment.length) {
|
|
195
|
-
while (cursor < rawSegment.length && isWhitespace(rawSegment[cursor]))
|
|
196
|
-
cursor += 1;
|
|
197
|
-
if (cursor >= rawSegment.length)
|
|
198
|
-
return { ok: true };
|
|
199
|
-
const leadingRedirection = leadingRedirectionTokenAt(rawSegment, cursor);
|
|
200
|
-
if (leadingRedirection !== undefined) {
|
|
201
|
-
return {
|
|
202
|
-
ok: false,
|
|
203
|
-
error: {
|
|
204
|
-
reason: `leading shell redirection ${JSON.stringify(leadingRedirection)} is not supported by bash policy segments mode`,
|
|
205
|
-
offset: absoluteStart + cursor,
|
|
206
|
-
source,
|
|
207
|
-
},
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
const word = readShellWord(rawSegment, cursor);
|
|
211
|
-
if (!word.ok) {
|
|
212
|
-
return {
|
|
213
|
-
ok: false,
|
|
214
|
-
error: { reason: word.reason, offset: absoluteStart + word.offset, source },
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
const attachedRedirection = attachedCommandHeadRedirection(rawSegment, cursor, word.end);
|
|
218
|
-
if (attachedRedirection !== undefined) {
|
|
219
|
-
return {
|
|
220
|
-
ok: false,
|
|
221
|
-
error: {
|
|
222
|
-
reason: `attached shell redirection ${JSON.stringify(attachedRedirection.token)} in the command head is not supported by bash policy segments mode`,
|
|
223
|
-
offset: absoluteStart + attachedRedirection.offset,
|
|
224
|
-
source,
|
|
225
|
-
},
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
if (isEnvAssignmentWord(word.word)) {
|
|
229
|
-
return {
|
|
230
|
-
ok: false,
|
|
231
|
-
error: {
|
|
232
|
-
reason: "environment assignment words are not supported by bash policy segments mode",
|
|
233
|
-
offset: absoluteStart + cursor,
|
|
234
|
-
source,
|
|
235
|
-
},
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
const target = rawSegment.slice(cursor).trim();
|
|
239
|
-
const head = word.word;
|
|
240
|
-
if (UNSUPPORTED_CONTROL_HEADS.has(head)) {
|
|
241
|
-
return {
|
|
242
|
-
ok: false,
|
|
243
|
-
error: {
|
|
244
|
-
reason: `unsupported shell reserved or compound syntax starting with ${JSON.stringify(head)}`,
|
|
245
|
-
offset: absoluteStart + cursor,
|
|
246
|
-
source,
|
|
247
|
-
},
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
const literalHead = validateLiteralCommandHead(head, word.metadata);
|
|
251
|
-
if (!literalHead.ok) {
|
|
252
|
-
return {
|
|
253
|
-
ok: false,
|
|
254
|
-
error: {
|
|
255
|
-
reason: literalHead.reason,
|
|
256
|
-
offset: absoluteStart + cursor,
|
|
257
|
-
source,
|
|
258
|
-
},
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
return {
|
|
262
|
-
ok: true,
|
|
263
|
-
segment: {
|
|
264
|
-
raw: rawSegment.trim(),
|
|
265
|
-
target,
|
|
266
|
-
head,
|
|
267
|
-
start: absoluteStart + cursor,
|
|
268
|
-
end: absoluteEnd,
|
|
269
|
-
source,
|
|
270
|
-
},
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
return { ok: true };
|
|
274
|
-
}
|
|
275
|
-
//# sourceMappingURL=bash-policy-segment.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bash-policy-segment.js","sourceRoot":"","sources":["../../../src/core/tools/bash-policy-segment.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SegmentBuildResult, ShellQuoteState, ShellWordMetadata } from \"./bash-policy-types.ts\";\nimport {\n\tfindClosingBacktick,\n\tfindClosingParen,\n\tisCommandSubstitutionAt,\n\tisProcessSubstitutionAt,\n\tisWhitespace,\n\treadShellWord,\n} from \"./bash-policy-shell.ts\";\n\nconst UNSUPPORTED_CONTROL_HEADS = new Set([\n\t\"!\",\n\t\"[[\",\n\t\"]]\",\n\t\"case\",\n\t\"coproc\",\n\t\"do\",\n\t\"done\",\n\t\"elif\",\n\t\"else\",\n\t\"esac\",\n\t\"fi\",\n\t\"for\",\n\t\"function\",\n\t\"if\",\n\t\"in\",\n\t\"select\",\n\t\"then\",\n\t\"time\",\n\t\"until\",\n\t\"while\",\n\t\"{\",\n\t\"}\",\n]);\n\ntype LiteralCommandHeadValidation =\n\t| { readonly ok: true }\n\t| { readonly ok: false; readonly reason: string };\n\ninterface AttachedRedirectionToken {\n\treadonly token: string;\n\treadonly offset: number;\n}\n\nfunction isAsciiDigit(char: string | undefined): boolean {\n\treturn char !== undefined && char >= \"0\" && char <= \"9\";\n}\n\nfunction leadingRedirectionTokenAt(input: string, index: number): string | undefined {\n\tlet operatorStart = index;\n\twhile (isAsciiDigit(input[operatorStart])) operatorStart += 1;\n\n\tconst hasDescriptorPrefix = operatorStart > index;\n\tconst char = input[operatorStart];\n\tconst next = input[operatorStart + 1];\n\tconst afterNext = input[operatorStart + 2];\n\n\tif (char === undefined) return undefined;\n\tif (hasDescriptorPrefix && char !== \"<\" && char !== \">\") return undefined;\n\n\tif (!hasDescriptorPrefix && (char === \"<\" || char === \">\") && next === \"(\") {\n\t\treturn undefined;\n\t}\n\n\tlet operator: string | undefined;\n\tif (char === \"&\" && next === \">\") {\n\t\toperator = afterNext === \">\" ? \"&>>\" : \"&>\";\n\t} else if (char === \"<\") {\n\t\tif (next === \"<\") operator = \"<<\";\n\t\telse if (next === \"&\") operator = \"<&\";\n\t\telse if (next === \">\") operator = \"<>\";\n\t\telse operator = \"<\";\n\t} else if (char === \">\") {\n\t\tif (next === \">\") operator = \">>\";\n\t\telse if (next === \"|\") operator = \">|\";\n\t\telse if (next === \"&\") operator = \">&\";\n\t\telse operator = \">\";\n\t}\n\n\treturn operator === undefined ? undefined : `${input.slice(index, operatorStart)}${operator}`;\n}\n\nfunction isEnvAssignmentWord(word: string): boolean {\n\treturn /^[A-Za-z_][A-Za-z0-9_]*(?:\\+)?=/.test(word);\n}\n\nfunction attachedRedirectionOperatorAt(input: string, index: number): string | undefined {\n\tconst char = input[index];\n\tconst next = input[index + 1];\n\tconst afterNext = input[index + 2];\n\n\tif ((char === \"<\" || char === \">\") && next === \"(\") {\n\t\treturn undefined;\n\t}\n\tif (char === \"&\" && next === \">\") {\n\t\treturn afterNext === \">\" ? \"&>>\" : \"&>\";\n\t}\n\tif (char === \"<\") {\n\t\tif (next === \"<\") return \"<<\";\n\t\tif (next === \"&\") return \"<&\";\n\t\tif (next === \">\") return \"<>\";\n\t\treturn \"<\";\n\t}\n\tif (char === \">\") {\n\t\tif (next === \">\") return \">>\";\n\t\tif (next === \"|\") return \">|\";\n\t\tif (next === \"&\") return \">&\";\n\t\treturn \">\";\n\t}\n\treturn undefined;\n}\n\nfunction attachedCommandHeadRedirection(\n\tinput: string,\n\tstart: number,\n\tend: number,\n): AttachedRedirectionToken | undefined {\n\tlet quote: ShellQuoteState = \"none\";\n\n\tfor (let i = start; i < end; i += 1) {\n\t\tconst char = input[i]!;\n\t\tif (quote === \"single\") {\n\t\t\tif (char === \"'\") quote = \"none\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\\\") {\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (quote === \"double\") {\n\t\t\tif (char === \"\\\"\") {\n\t\t\t\tquote = \"none\";\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {\n\t\t\t\tconst close = findClosingParen(input, i + 1, isCommandSubstitutionAt(input, i) ? \"command substitution `$(`\" : \"process substitution\");\n\t\t\t\tif (close.ok) i = close.closeIndex;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"`\") {\n\t\t\t\tconst close = findClosingBacktick(input, i);\n\t\t\t\tif (close.ok) i = close.closeIndex;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"'\") {\n\t\t\tquote = \"single\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\"\") {\n\t\t\tquote = \"double\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {\n\t\t\tconst close = findClosingParen(input, i + 1, isCommandSubstitutionAt(input, i) ? \"command substitution `$(`\" : \"process substitution\");\n\t\t\tif (close.ok) i = close.closeIndex;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"`\") {\n\t\t\tconst close = findClosingBacktick(input, i);\n\t\t\tif (close.ok) i = close.closeIndex;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst operator = attachedRedirectionOperatorAt(input, i);\n\t\tif (operator !== undefined && i > start) {\n\t\t\treturn { token: operator, offset: i };\n\t\t}\n\t}\n\n\treturn undefined;\n}\n\nfunction validateLiteralCommandHead(head: string, metadata: ShellWordMetadata): LiteralCommandHeadValidation {\n\tif (head.length === 0) {\n\t\treturn { ok: false, reason: \"empty command heads are not supported by bash policy segments mode\" };\n\t}\n\tif (metadata.sawSingleQuote || metadata.sawDoubleQuote) {\n\t\treturn { ok: false, reason: \"quoted or quote-constructed command heads are not supported by bash policy segments mode\" };\n\t}\n\tif (metadata.sawEscape) {\n\t\treturn { ok: false, reason: \"escape-constructed command heads are not supported by bash policy segments mode\" };\n\t}\n\tif (metadata.sawCommandSubstitution || metadata.sawProcessSubstitution || metadata.sawBacktick) {\n\t\treturn { ok: false, reason: \"command, process, and backtick substitutions are not supported in command heads by bash policy segments mode\" };\n\t}\n\tif (metadata.sawParameterExpansion) {\n\t\treturn { ok: false, reason: \"parameter-expanded command heads are not supported by bash policy segments mode\" };\n\t}\n\tif (metadata.sawTildePrefix) {\n\t\treturn { ok: false, reason: \"tilde-expanded command heads are not supported by bash policy segments mode\" };\n\t}\n\tif (metadata.sawGlobPattern) {\n\t\treturn { ok: false, reason: \"glob-expanded command heads are not supported by bash policy segments mode\" };\n\t}\n\tif (metadata.sawBraceExpansion) {\n\t\treturn { ok: false, reason: \"brace-expanded command heads are not supported by bash policy segments mode\" };\n\t}\n\treturn { ok: true };\n}\n\nexport function buildSegment(\n\trawSegment: string,\n\tabsoluteStart: number,\n\tabsoluteEnd: number,\n\tsource: \"top-level\" | \"command-substitution\" | \"process-substitution\" | \"backtick\",\n): SegmentBuildResult {\n\tlet cursor = 0;\n\twhile (cursor < rawSegment.length && isWhitespace(rawSegment[cursor]!)) cursor += 1;\n\tif (cursor >= rawSegment.length) return { ok: true };\n\n\twhile (cursor < rawSegment.length) {\n\t\twhile (cursor < rawSegment.length && isWhitespace(rawSegment[cursor]!)) cursor += 1;\n\t\tif (cursor >= rawSegment.length) return { ok: true };\n\n\t\tconst leadingRedirection = leadingRedirectionTokenAt(rawSegment, cursor);\n\t\tif (leadingRedirection !== undefined) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\treason: `leading shell redirection ${JSON.stringify(leadingRedirection)} is not supported by bash policy segments mode`,\n\t\t\t\t\toffset: absoluteStart + cursor,\n\t\t\t\t\tsource,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst word = readShellWord(rawSegment, cursor);\n\t\tif (!word.ok) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: { reason: word.reason, offset: absoluteStart + word.offset, source },\n\t\t\t};\n\t\t}\n\n\t\tconst attachedRedirection = attachedCommandHeadRedirection(rawSegment, cursor, word.end);\n\t\tif (attachedRedirection !== undefined) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\treason: `attached shell redirection ${JSON.stringify(attachedRedirection.token)} in the command head is not supported by bash policy segments mode`,\n\t\t\t\t\toffset: absoluteStart + attachedRedirection.offset,\n\t\t\t\t\tsource,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tif (isEnvAssignmentWord(word.word)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\treason: \"environment assignment words are not supported by bash policy segments mode\",\n\t\t\t\t\toffset: absoluteStart + cursor,\n\t\t\t\t\tsource,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst target = rawSegment.slice(cursor).trim();\n\t\tconst head = word.word;\n\t\tif (UNSUPPORTED_CONTROL_HEADS.has(head)) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\treason: `unsupported shell reserved or compound syntax starting with ${JSON.stringify(head)}`,\n\t\t\t\t\toffset: absoluteStart + cursor,\n\t\t\t\t\tsource,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\t\tconst literalHead = validateLiteralCommandHead(head, word.metadata);\n\t\tif (!literalHead.ok) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\treason: literalHead.reason,\n\t\t\t\t\toffset: absoluteStart + cursor,\n\t\t\t\t\tsource,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tok: true,\n\t\t\tsegment: {\n\t\t\t\traw: rawSegment.trim(),\n\t\t\t\ttarget,\n\t\t\t\thead,\n\t\t\t\tstart: absoluteStart + cursor,\n\t\t\t\tend: absoluteEnd,\n\t\t\t\tsource,\n\t\t\t},\n\t\t};\n\t}\n\n\treturn { ok: true };\n}\n"]}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { ClosingBacktickResult, ClosingParenResult, ShellWordReadResult } from "./bash-policy-types.ts";
|
|
2
|
-
export declare function isWhitespace(char: string): boolean;
|
|
3
|
-
export declare function lineTerminatorLengthAt(input: string, index: number): number;
|
|
4
|
-
export declare function operatorLengthAt(input: string, index: number): number;
|
|
5
|
-
export declare function isHereDocumentAt(input: string, index: number): boolean;
|
|
6
|
-
export declare function isCommandSubstitutionAt(input: string, index: number): boolean;
|
|
7
|
-
export declare function isProcessSubstitutionAt(input: string, index: number): boolean;
|
|
8
|
-
export declare function findClosingBacktick(input: string, openIndex: number): ClosingBacktickResult;
|
|
9
|
-
export declare function findClosingParen(input: string, openIndex: number, construct: string): ClosingParenResult;
|
|
10
|
-
export declare function readShellWord(input: string, start: number): ShellWordReadResult;
|
|
11
|
-
//# sourceMappingURL=bash-policy-shell.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bash-policy-shell.d.ts","sourceRoot":"","sources":["../../../src/core/tools/bash-policy-shell.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,qBAAqB,EACrB,kBAAkB,EAGlB,mBAAmB,EACnB,MAAM,wBAAwB,CAAC;AAEhC,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK3E;AAgBD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAWrE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAE7E;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAG7E;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,qBAAqB,CAa3F;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,kBAAkB,CAwExG;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,mBAAmB,CAkH/E","sourcesContent":["import type {\n\tClosingBacktickResult,\n\tClosingParenResult,\n\tShellQuoteState,\n\tShellWordMetadata,\n\tShellWordReadResult,\n} from \"./bash-policy-types.ts\";\n\nexport function isWhitespace(char: string): boolean {\n\treturn char === \" \" || char === \"\\t\" || char === \"\\n\" || char === \"\\r\";\n}\n\nexport function lineTerminatorLengthAt(input: string, index: number): number {\n\tconst char = input[index];\n\tif (char === \"\\r\") return input[index + 1] === \"\\n\" ? 2 : 1;\n\tif (char === \"\\n\") return 1;\n\treturn 0;\n}\n\nfunction previousNonWhitespace(input: string, index: number): string | undefined {\n\tfor (let i = index - 1; i >= 0; i -= 1) {\n\t\tconst char = input[i]!;\n\t\tif (!isWhitespace(char)) return char;\n\t}\n\treturn undefined;\n}\n\nfunction isRedirectionAmpersand(input: string, index: number): boolean {\n\tconst previous = previousNonWhitespace(input, index);\n\tconst next = input[index + 1];\n\treturn previous === \">\" || previous === \"<\" || next === \">\";\n}\n\nexport function operatorLengthAt(input: string, index: number): number {\n\tconst char = input[index];\n\tconst next = input[index + 1];\n\tif (char === \"|\" && input[index - 1] === \">\") return 0;\n\tif (char === \"|\" && next === \"&\") return 2;\n\tif (char === \"&\" && next === \"&\") return 2;\n\tif (char === \"|\" && next === \"|\") return 2;\n\tif (char === \"|\") return 1;\n\tif (char === \";\") return 1;\n\tif (char === \"&\" && !isRedirectionAmpersand(input, index)) return 1;\n\treturn 0;\n}\n\nexport function isHereDocumentAt(input: string, index: number): boolean {\n\treturn input[index] === \"<\" && input[index + 1] === \"<\";\n}\n\nexport function isCommandSubstitutionAt(input: string, index: number): boolean {\n\treturn input[index] === \"$\" && input[index + 1] === \"(\";\n}\n\nexport function isProcessSubstitutionAt(input: string, index: number): boolean {\n\tconst char = input[index];\n\treturn (char === \"<\" || char === \">\") && input[index + 1] === \"(\";\n}\n\nexport function findClosingBacktick(input: string, openIndex: number): ClosingBacktickResult {\n\tfor (let i = openIndex + 1; i < input.length; i += 1) {\n\t\tconst char = input[i]!;\n\t\tif (char === \"\\\\\") {\n\t\t\tif (i + 1 >= input.length) {\n\t\t\t\treturn { ok: false, reason: \"trailing escape in backtick command substitution\", offset: i };\n\t\t\t}\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"`\") return { ok: true, closeIndex: i };\n\t}\n\treturn { ok: false, reason: \"unclosed backtick command substitution\", offset: openIndex };\n}\n\nexport function findClosingParen(input: string, openIndex: number, construct: string): ClosingParenResult {\n\tlet quote: ShellQuoteState = \"none\";\n\tlet depth = 1;\n\tfor (let i = openIndex + 1; i < input.length; i += 1) {\n\t\tconst char = input[i]!;\n\n\t\tif (quote === \"single\") {\n\t\t\tif (char === \"'\") quote = \"none\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"\\\\\") {\n\t\t\tif (i + 1 >= input.length) {\n\t\t\t\treturn { ok: false, reason: `trailing escape in ${construct}`, offset: i };\n\t\t\t}\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote === \"double\") {\n\t\t\tif (char === \"\\\"\") {\n\t\t\t\tquote = \"none\";\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {\n\t\t\t\tdepth += 1;\n\t\t\t\ti += 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"`\") {\n\t\t\t\tconst close = findClosingBacktick(input, i);\n\t\t\t\tif (!close.ok) return close;\n\t\t\t\ti = close.closeIndex;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"'\") {\n\t\t\tquote = \"single\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\"\") {\n\t\t\tquote = \"double\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {\n\t\t\tdepth += 1;\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"`\") {\n\t\t\tconst close = findClosingBacktick(input, i);\n\t\t\tif (!close.ok) return close;\n\t\t\ti = close.closeIndex;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"(\") {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\treason: `unsupported shell grouping parentheses in ${construct}`,\n\t\t\t\toffset: i,\n\t\t\t};\n\t\t}\n\t\tif (char === \")\") {\n\t\t\tdepth -= 1;\n\t\t\tif (depth === 0) return { ok: true, closeIndex: i };\n\t\t}\n\t}\n\n\tif (quote === \"single\") return { ok: false, reason: `unclosed single quote in ${construct}`, offset: openIndex };\n\tif (quote === \"double\") return { ok: false, reason: `unclosed double quote in ${construct}`, offset: openIndex };\n\treturn { ok: false, reason: `unclosed ${construct}`, offset: openIndex };\n}\n\nexport function readShellWord(input: string, start: number): ShellWordReadResult {\n\tlet quote: ShellQuoteState = \"none\";\n\tlet sawSingleQuote = false;\n\tlet sawDoubleQuote = false;\n\tlet sawEscape = false;\n\tlet sawParameterExpansion = false;\n\tlet sawCommandSubstitution = false;\n\tlet sawProcessSubstitution = false;\n\tlet sawBacktick = false;\n\tlet sawGlobPattern = false;\n\tlet sawBraceExpansion = false;\n\tlet sawTildePrefix = false;\n\n\tconst metadata = (): ShellWordMetadata => ({\n\t\tsawSingleQuote,\n\t\tsawDoubleQuote,\n\t\tsawEscape,\n\t\tsawParameterExpansion,\n\t\tsawCommandSubstitution,\n\t\tsawProcessSubstitution,\n\t\tsawBacktick,\n\t\tsawGlobPattern,\n\t\tsawBraceExpansion,\n\t\tsawTildePrefix,\n\t});\n\n\tfor (let i = start; i < input.length; i += 1) {\n\t\tconst char = input[i]!;\n\t\tif (quote === \"single\") {\n\t\t\tif (char === \"'\") quote = \"none\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\\\") {\n\t\t\tsawEscape = true;\n\t\t\tif (i + 1 >= input.length) return { ok: false, reason: \"trailing escape in shell word\", offset: i };\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (quote === \"double\") {\n\t\t\tif (char === \"\\\"\") {\n\t\t\t\tquote = \"none\";\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {\n\t\t\t\tif (isCommandSubstitutionAt(input, i)) {\n\t\t\t\t\tsawCommandSubstitution = true;\n\t\t\t\t} else {\n\t\t\t\t\tsawProcessSubstitution = true;\n\t\t\t\t}\n\t\t\t\tconst close = findClosingParen(input, i + 1, isCommandSubstitutionAt(input, i) ? \"command substitution `$(`\" : \"process substitution\");\n\t\t\t\tif (!close.ok) return { ok: false, reason: close.reason, offset: close.offset };\n\t\t\t\ti = close.closeIndex;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"`\") {\n\t\t\t\tsawBacktick = true;\n\t\t\t\tconst close = findClosingBacktick(input, i);\n\t\t\t\tif (!close.ok) return { ok: false, reason: close.reason, offset: close.offset };\n\t\t\t\ti = close.closeIndex;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"$\") sawParameterExpansion = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (isWhitespace(char)) {\n\t\t\treturn { ok: true, word: input.slice(start, i), end: i, metadata: metadata() };\n\t\t}\n\t\tif (char === \"'\") {\n\t\t\tsawSingleQuote = true;\n\t\t\tquote = \"single\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\"\") {\n\t\t\tsawDoubleQuote = true;\n\t\t\tquote = \"double\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (i === start && char === \"~\") {\n\t\t\tsawTildePrefix = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {\n\t\t\tif (isCommandSubstitutionAt(input, i)) {\n\t\t\t\tsawCommandSubstitution = true;\n\t\t\t} else {\n\t\t\t\tsawProcessSubstitution = true;\n\t\t\t}\n\t\t\tconst close = findClosingParen(input, i + 1, isCommandSubstitutionAt(input, i) ? \"command substitution `$(`\" : \"process substitution\");\n\t\t\tif (!close.ok) return { ok: false, reason: close.reason, offset: close.offset };\n\t\t\ti = close.closeIndex;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"`\") {\n\t\t\tsawBacktick = true;\n\t\t\tconst close = findClosingBacktick(input, i);\n\t\t\tif (!close.ok) return { ok: false, reason: close.reason, offset: close.offset };\n\t\t\ti = close.closeIndex;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"$\") {\n\t\t\tsawParameterExpansion = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"*\" || char === \"?\" || char === \"[\" || char === \"]\") {\n\t\t\tsawGlobPattern = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"{\" || char === \"}\") {\n\t\t\tsawBraceExpansion = true;\n\t\t}\n\t}\n\tif (quote === \"single\") return { ok: false, reason: \"unclosed single quote in shell word\", offset: start };\n\tif (quote === \"double\") return { ok: false, reason: \"unclosed double quote in shell word\", offset: start };\n\treturn { ok: true, word: input.slice(start), end: input.length, metadata: metadata() };\n}\n\n"]}
|
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
export function isWhitespace(char) {
|
|
2
|
-
return char === " " || char === "\t" || char === "\n" || char === "\r";
|
|
3
|
-
}
|
|
4
|
-
export function lineTerminatorLengthAt(input, index) {
|
|
5
|
-
const char = input[index];
|
|
6
|
-
if (char === "\r")
|
|
7
|
-
return input[index + 1] === "\n" ? 2 : 1;
|
|
8
|
-
if (char === "\n")
|
|
9
|
-
return 1;
|
|
10
|
-
return 0;
|
|
11
|
-
}
|
|
12
|
-
function previousNonWhitespace(input, index) {
|
|
13
|
-
for (let i = index - 1; i >= 0; i -= 1) {
|
|
14
|
-
const char = input[i];
|
|
15
|
-
if (!isWhitespace(char))
|
|
16
|
-
return char;
|
|
17
|
-
}
|
|
18
|
-
return undefined;
|
|
19
|
-
}
|
|
20
|
-
function isRedirectionAmpersand(input, index) {
|
|
21
|
-
const previous = previousNonWhitespace(input, index);
|
|
22
|
-
const next = input[index + 1];
|
|
23
|
-
return previous === ">" || previous === "<" || next === ">";
|
|
24
|
-
}
|
|
25
|
-
export function operatorLengthAt(input, index) {
|
|
26
|
-
const char = input[index];
|
|
27
|
-
const next = input[index + 1];
|
|
28
|
-
if (char === "|" && input[index - 1] === ">")
|
|
29
|
-
return 0;
|
|
30
|
-
if (char === "|" && next === "&")
|
|
31
|
-
return 2;
|
|
32
|
-
if (char === "&" && next === "&")
|
|
33
|
-
return 2;
|
|
34
|
-
if (char === "|" && next === "|")
|
|
35
|
-
return 2;
|
|
36
|
-
if (char === "|")
|
|
37
|
-
return 1;
|
|
38
|
-
if (char === ";")
|
|
39
|
-
return 1;
|
|
40
|
-
if (char === "&" && !isRedirectionAmpersand(input, index))
|
|
41
|
-
return 1;
|
|
42
|
-
return 0;
|
|
43
|
-
}
|
|
44
|
-
export function isHereDocumentAt(input, index) {
|
|
45
|
-
return input[index] === "<" && input[index + 1] === "<";
|
|
46
|
-
}
|
|
47
|
-
export function isCommandSubstitutionAt(input, index) {
|
|
48
|
-
return input[index] === "$" && input[index + 1] === "(";
|
|
49
|
-
}
|
|
50
|
-
export function isProcessSubstitutionAt(input, index) {
|
|
51
|
-
const char = input[index];
|
|
52
|
-
return (char === "<" || char === ">") && input[index + 1] === "(";
|
|
53
|
-
}
|
|
54
|
-
export function findClosingBacktick(input, openIndex) {
|
|
55
|
-
for (let i = openIndex + 1; i < input.length; i += 1) {
|
|
56
|
-
const char = input[i];
|
|
57
|
-
if (char === "\\") {
|
|
58
|
-
if (i + 1 >= input.length) {
|
|
59
|
-
return { ok: false, reason: "trailing escape in backtick command substitution", offset: i };
|
|
60
|
-
}
|
|
61
|
-
i += 1;
|
|
62
|
-
continue;
|
|
63
|
-
}
|
|
64
|
-
if (char === "`")
|
|
65
|
-
return { ok: true, closeIndex: i };
|
|
66
|
-
}
|
|
67
|
-
return { ok: false, reason: "unclosed backtick command substitution", offset: openIndex };
|
|
68
|
-
}
|
|
69
|
-
export function findClosingParen(input, openIndex, construct) {
|
|
70
|
-
let quote = "none";
|
|
71
|
-
let depth = 1;
|
|
72
|
-
for (let i = openIndex + 1; i < input.length; i += 1) {
|
|
73
|
-
const char = input[i];
|
|
74
|
-
if (quote === "single") {
|
|
75
|
-
if (char === "'")
|
|
76
|
-
quote = "none";
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
if (char === "\\") {
|
|
80
|
-
if (i + 1 >= input.length) {
|
|
81
|
-
return { ok: false, reason: `trailing escape in ${construct}`, offset: i };
|
|
82
|
-
}
|
|
83
|
-
i += 1;
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
if (quote === "double") {
|
|
87
|
-
if (char === "\"") {
|
|
88
|
-
quote = "none";
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
if (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {
|
|
92
|
-
depth += 1;
|
|
93
|
-
i += 1;
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
if (char === "`") {
|
|
97
|
-
const close = findClosingBacktick(input, i);
|
|
98
|
-
if (!close.ok)
|
|
99
|
-
return close;
|
|
100
|
-
i = close.closeIndex;
|
|
101
|
-
}
|
|
102
|
-
continue;
|
|
103
|
-
}
|
|
104
|
-
if (char === "'") {
|
|
105
|
-
quote = "single";
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
if (char === "\"") {
|
|
109
|
-
quote = "double";
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
if (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {
|
|
113
|
-
depth += 1;
|
|
114
|
-
i += 1;
|
|
115
|
-
continue;
|
|
116
|
-
}
|
|
117
|
-
if (char === "`") {
|
|
118
|
-
const close = findClosingBacktick(input, i);
|
|
119
|
-
if (!close.ok)
|
|
120
|
-
return close;
|
|
121
|
-
i = close.closeIndex;
|
|
122
|
-
continue;
|
|
123
|
-
}
|
|
124
|
-
if (char === "(") {
|
|
125
|
-
return {
|
|
126
|
-
ok: false,
|
|
127
|
-
reason: `unsupported shell grouping parentheses in ${construct}`,
|
|
128
|
-
offset: i,
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
if (char === ")") {
|
|
132
|
-
depth -= 1;
|
|
133
|
-
if (depth === 0)
|
|
134
|
-
return { ok: true, closeIndex: i };
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
if (quote === "single")
|
|
138
|
-
return { ok: false, reason: `unclosed single quote in ${construct}`, offset: openIndex };
|
|
139
|
-
if (quote === "double")
|
|
140
|
-
return { ok: false, reason: `unclosed double quote in ${construct}`, offset: openIndex };
|
|
141
|
-
return { ok: false, reason: `unclosed ${construct}`, offset: openIndex };
|
|
142
|
-
}
|
|
143
|
-
export function readShellWord(input, start) {
|
|
144
|
-
let quote = "none";
|
|
145
|
-
let sawSingleQuote = false;
|
|
146
|
-
let sawDoubleQuote = false;
|
|
147
|
-
let sawEscape = false;
|
|
148
|
-
let sawParameterExpansion = false;
|
|
149
|
-
let sawCommandSubstitution = false;
|
|
150
|
-
let sawProcessSubstitution = false;
|
|
151
|
-
let sawBacktick = false;
|
|
152
|
-
let sawGlobPattern = false;
|
|
153
|
-
let sawBraceExpansion = false;
|
|
154
|
-
let sawTildePrefix = false;
|
|
155
|
-
const metadata = () => ({
|
|
156
|
-
sawSingleQuote,
|
|
157
|
-
sawDoubleQuote,
|
|
158
|
-
sawEscape,
|
|
159
|
-
sawParameterExpansion,
|
|
160
|
-
sawCommandSubstitution,
|
|
161
|
-
sawProcessSubstitution,
|
|
162
|
-
sawBacktick,
|
|
163
|
-
sawGlobPattern,
|
|
164
|
-
sawBraceExpansion,
|
|
165
|
-
sawTildePrefix,
|
|
166
|
-
});
|
|
167
|
-
for (let i = start; i < input.length; i += 1) {
|
|
168
|
-
const char = input[i];
|
|
169
|
-
if (quote === "single") {
|
|
170
|
-
if (char === "'")
|
|
171
|
-
quote = "none";
|
|
172
|
-
continue;
|
|
173
|
-
}
|
|
174
|
-
if (char === "\\") {
|
|
175
|
-
sawEscape = true;
|
|
176
|
-
if (i + 1 >= input.length)
|
|
177
|
-
return { ok: false, reason: "trailing escape in shell word", offset: i };
|
|
178
|
-
i += 1;
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
if (quote === "double") {
|
|
182
|
-
if (char === "\"") {
|
|
183
|
-
quote = "none";
|
|
184
|
-
continue;
|
|
185
|
-
}
|
|
186
|
-
if (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {
|
|
187
|
-
if (isCommandSubstitutionAt(input, i)) {
|
|
188
|
-
sawCommandSubstitution = true;
|
|
189
|
-
}
|
|
190
|
-
else {
|
|
191
|
-
sawProcessSubstitution = true;
|
|
192
|
-
}
|
|
193
|
-
const close = findClosingParen(input, i + 1, isCommandSubstitutionAt(input, i) ? "command substitution `$(`" : "process substitution");
|
|
194
|
-
if (!close.ok)
|
|
195
|
-
return { ok: false, reason: close.reason, offset: close.offset };
|
|
196
|
-
i = close.closeIndex;
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
if (char === "`") {
|
|
200
|
-
sawBacktick = true;
|
|
201
|
-
const close = findClosingBacktick(input, i);
|
|
202
|
-
if (!close.ok)
|
|
203
|
-
return { ok: false, reason: close.reason, offset: close.offset };
|
|
204
|
-
i = close.closeIndex;
|
|
205
|
-
continue;
|
|
206
|
-
}
|
|
207
|
-
if (char === "$")
|
|
208
|
-
sawParameterExpansion = true;
|
|
209
|
-
continue;
|
|
210
|
-
}
|
|
211
|
-
if (isWhitespace(char)) {
|
|
212
|
-
return { ok: true, word: input.slice(start, i), end: i, metadata: metadata() };
|
|
213
|
-
}
|
|
214
|
-
if (char === "'") {
|
|
215
|
-
sawSingleQuote = true;
|
|
216
|
-
quote = "single";
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
if (char === "\"") {
|
|
220
|
-
sawDoubleQuote = true;
|
|
221
|
-
quote = "double";
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
if (i === start && char === "~") {
|
|
225
|
-
sawTildePrefix = true;
|
|
226
|
-
continue;
|
|
227
|
-
}
|
|
228
|
-
if (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {
|
|
229
|
-
if (isCommandSubstitutionAt(input, i)) {
|
|
230
|
-
sawCommandSubstitution = true;
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
sawProcessSubstitution = true;
|
|
234
|
-
}
|
|
235
|
-
const close = findClosingParen(input, i + 1, isCommandSubstitutionAt(input, i) ? "command substitution `$(`" : "process substitution");
|
|
236
|
-
if (!close.ok)
|
|
237
|
-
return { ok: false, reason: close.reason, offset: close.offset };
|
|
238
|
-
i = close.closeIndex;
|
|
239
|
-
continue;
|
|
240
|
-
}
|
|
241
|
-
if (char === "`") {
|
|
242
|
-
sawBacktick = true;
|
|
243
|
-
const close = findClosingBacktick(input, i);
|
|
244
|
-
if (!close.ok)
|
|
245
|
-
return { ok: false, reason: close.reason, offset: close.offset };
|
|
246
|
-
i = close.closeIndex;
|
|
247
|
-
continue;
|
|
248
|
-
}
|
|
249
|
-
if (char === "$") {
|
|
250
|
-
sawParameterExpansion = true;
|
|
251
|
-
continue;
|
|
252
|
-
}
|
|
253
|
-
if (char === "*" || char === "?" || char === "[" || char === "]") {
|
|
254
|
-
sawGlobPattern = true;
|
|
255
|
-
continue;
|
|
256
|
-
}
|
|
257
|
-
if (char === "{" || char === "}") {
|
|
258
|
-
sawBraceExpansion = true;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
if (quote === "single")
|
|
262
|
-
return { ok: false, reason: "unclosed single quote in shell word", offset: start };
|
|
263
|
-
if (quote === "double")
|
|
264
|
-
return { ok: false, reason: "unclosed double quote in shell word", offset: start };
|
|
265
|
-
return { ok: true, word: input.slice(start), end: input.length, metadata: metadata() };
|
|
266
|
-
}
|
|
267
|
-
//# sourceMappingURL=bash-policy-shell.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bash-policy-shell.js","sourceRoot":"","sources":["../../../src/core/tools/bash-policy-shell.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n\tClosingBacktickResult,\n\tClosingParenResult,\n\tShellQuoteState,\n\tShellWordMetadata,\n\tShellWordReadResult,\n} from \"./bash-policy-types.ts\";\n\nexport function isWhitespace(char: string): boolean {\n\treturn char === \" \" || char === \"\\t\" || char === \"\\n\" || char === \"\\r\";\n}\n\nexport function lineTerminatorLengthAt(input: string, index: number): number {\n\tconst char = input[index];\n\tif (char === \"\\r\") return input[index + 1] === \"\\n\" ? 2 : 1;\n\tif (char === \"\\n\") return 1;\n\treturn 0;\n}\n\nfunction previousNonWhitespace(input: string, index: number): string | undefined {\n\tfor (let i = index - 1; i >= 0; i -= 1) {\n\t\tconst char = input[i]!;\n\t\tif (!isWhitespace(char)) return char;\n\t}\n\treturn undefined;\n}\n\nfunction isRedirectionAmpersand(input: string, index: number): boolean {\n\tconst previous = previousNonWhitespace(input, index);\n\tconst next = input[index + 1];\n\treturn previous === \">\" || previous === \"<\" || next === \">\";\n}\n\nexport function operatorLengthAt(input: string, index: number): number {\n\tconst char = input[index];\n\tconst next = input[index + 1];\n\tif (char === \"|\" && input[index - 1] === \">\") return 0;\n\tif (char === \"|\" && next === \"&\") return 2;\n\tif (char === \"&\" && next === \"&\") return 2;\n\tif (char === \"|\" && next === \"|\") return 2;\n\tif (char === \"|\") return 1;\n\tif (char === \";\") return 1;\n\tif (char === \"&\" && !isRedirectionAmpersand(input, index)) return 1;\n\treturn 0;\n}\n\nexport function isHereDocumentAt(input: string, index: number): boolean {\n\treturn input[index] === \"<\" && input[index + 1] === \"<\";\n}\n\nexport function isCommandSubstitutionAt(input: string, index: number): boolean {\n\treturn input[index] === \"$\" && input[index + 1] === \"(\";\n}\n\nexport function isProcessSubstitutionAt(input: string, index: number): boolean {\n\tconst char = input[index];\n\treturn (char === \"<\" || char === \">\") && input[index + 1] === \"(\";\n}\n\nexport function findClosingBacktick(input: string, openIndex: number): ClosingBacktickResult {\n\tfor (let i = openIndex + 1; i < input.length; i += 1) {\n\t\tconst char = input[i]!;\n\t\tif (char === \"\\\\\") {\n\t\t\tif (i + 1 >= input.length) {\n\t\t\t\treturn { ok: false, reason: \"trailing escape in backtick command substitution\", offset: i };\n\t\t\t}\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"`\") return { ok: true, closeIndex: i };\n\t}\n\treturn { ok: false, reason: \"unclosed backtick command substitution\", offset: openIndex };\n}\n\nexport function findClosingParen(input: string, openIndex: number, construct: string): ClosingParenResult {\n\tlet quote: ShellQuoteState = \"none\";\n\tlet depth = 1;\n\tfor (let i = openIndex + 1; i < input.length; i += 1) {\n\t\tconst char = input[i]!;\n\n\t\tif (quote === \"single\") {\n\t\t\tif (char === \"'\") quote = \"none\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"\\\\\") {\n\t\t\tif (i + 1 >= input.length) {\n\t\t\t\treturn { ok: false, reason: `trailing escape in ${construct}`, offset: i };\n\t\t\t}\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (quote === \"double\") {\n\t\t\tif (char === \"\\\"\") {\n\t\t\t\tquote = \"none\";\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {\n\t\t\t\tdepth += 1;\n\t\t\t\ti += 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"`\") {\n\t\t\t\tconst close = findClosingBacktick(input, i);\n\t\t\t\tif (!close.ok) return close;\n\t\t\t\ti = close.closeIndex;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (char === \"'\") {\n\t\t\tquote = \"single\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\"\") {\n\t\t\tquote = \"double\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {\n\t\t\tdepth += 1;\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"`\") {\n\t\t\tconst close = findClosingBacktick(input, i);\n\t\t\tif (!close.ok) return close;\n\t\t\ti = close.closeIndex;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"(\") {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\treason: `unsupported shell grouping parentheses in ${construct}`,\n\t\t\t\toffset: i,\n\t\t\t};\n\t\t}\n\t\tif (char === \")\") {\n\t\t\tdepth -= 1;\n\t\t\tif (depth === 0) return { ok: true, closeIndex: i };\n\t\t}\n\t}\n\n\tif (quote === \"single\") return { ok: false, reason: `unclosed single quote in ${construct}`, offset: openIndex };\n\tif (quote === \"double\") return { ok: false, reason: `unclosed double quote in ${construct}`, offset: openIndex };\n\treturn { ok: false, reason: `unclosed ${construct}`, offset: openIndex };\n}\n\nexport function readShellWord(input: string, start: number): ShellWordReadResult {\n\tlet quote: ShellQuoteState = \"none\";\n\tlet sawSingleQuote = false;\n\tlet sawDoubleQuote = false;\n\tlet sawEscape = false;\n\tlet sawParameterExpansion = false;\n\tlet sawCommandSubstitution = false;\n\tlet sawProcessSubstitution = false;\n\tlet sawBacktick = false;\n\tlet sawGlobPattern = false;\n\tlet sawBraceExpansion = false;\n\tlet sawTildePrefix = false;\n\n\tconst metadata = (): ShellWordMetadata => ({\n\t\tsawSingleQuote,\n\t\tsawDoubleQuote,\n\t\tsawEscape,\n\t\tsawParameterExpansion,\n\t\tsawCommandSubstitution,\n\t\tsawProcessSubstitution,\n\t\tsawBacktick,\n\t\tsawGlobPattern,\n\t\tsawBraceExpansion,\n\t\tsawTildePrefix,\n\t});\n\n\tfor (let i = start; i < input.length; i += 1) {\n\t\tconst char = input[i]!;\n\t\tif (quote === \"single\") {\n\t\t\tif (char === \"'\") quote = \"none\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\\\") {\n\t\t\tsawEscape = true;\n\t\t\tif (i + 1 >= input.length) return { ok: false, reason: \"trailing escape in shell word\", offset: i };\n\t\t\ti += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (quote === \"double\") {\n\t\t\tif (char === \"\\\"\") {\n\t\t\t\tquote = \"none\";\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {\n\t\t\t\tif (isCommandSubstitutionAt(input, i)) {\n\t\t\t\t\tsawCommandSubstitution = true;\n\t\t\t\t} else {\n\t\t\t\t\tsawProcessSubstitution = true;\n\t\t\t\t}\n\t\t\t\tconst close = findClosingParen(input, i + 1, isCommandSubstitutionAt(input, i) ? \"command substitution `$(`\" : \"process substitution\");\n\t\t\t\tif (!close.ok) return { ok: false, reason: close.reason, offset: close.offset };\n\t\t\t\ti = close.closeIndex;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"`\") {\n\t\t\t\tsawBacktick = true;\n\t\t\t\tconst close = findClosingBacktick(input, i);\n\t\t\t\tif (!close.ok) return { ok: false, reason: close.reason, offset: close.offset };\n\t\t\t\ti = close.closeIndex;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (char === \"$\") sawParameterExpansion = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (isWhitespace(char)) {\n\t\t\treturn { ok: true, word: input.slice(start, i), end: i, metadata: metadata() };\n\t\t}\n\t\tif (char === \"'\") {\n\t\t\tsawSingleQuote = true;\n\t\t\tquote = \"single\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\"\") {\n\t\t\tsawDoubleQuote = true;\n\t\t\tquote = \"double\";\n\t\t\tcontinue;\n\t\t}\n\t\tif (i === start && char === \"~\") {\n\t\t\tsawTildePrefix = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (isCommandSubstitutionAt(input, i) || isProcessSubstitutionAt(input, i)) {\n\t\t\tif (isCommandSubstitutionAt(input, i)) {\n\t\t\t\tsawCommandSubstitution = true;\n\t\t\t} else {\n\t\t\t\tsawProcessSubstitution = true;\n\t\t\t}\n\t\t\tconst close = findClosingParen(input, i + 1, isCommandSubstitutionAt(input, i) ? \"command substitution `$(`\" : \"process substitution\");\n\t\t\tif (!close.ok) return { ok: false, reason: close.reason, offset: close.offset };\n\t\t\ti = close.closeIndex;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"`\") {\n\t\t\tsawBacktick = true;\n\t\t\tconst close = findClosingBacktick(input, i);\n\t\t\tif (!close.ok) return { ok: false, reason: close.reason, offset: close.offset };\n\t\t\ti = close.closeIndex;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"$\") {\n\t\t\tsawParameterExpansion = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"*\" || char === \"?\" || char === \"[\" || char === \"]\") {\n\t\t\tsawGlobPattern = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"{\" || char === \"}\") {\n\t\t\tsawBraceExpansion = true;\n\t\t}\n\t}\n\tif (quote === \"single\") return { ok: false, reason: \"unclosed single quote in shell word\", offset: start };\n\tif (quote === \"double\") return { ok: false, reason: \"unclosed double quote in shell word\", offset: start };\n\treturn { ok: true, word: input.slice(start), end: input.length, metadata: metadata() };\n}\n\n"]}
|