@windyroad/risk-scorer 0.19.13-preview.1284 → 0.19.13
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/hooks/external-comms-gate.sh +88 -6
- package/package.json +1 -1
|
@@ -159,6 +159,7 @@ EOF
|
|
|
159
159
|
# ---------- Surface detection ----------
|
|
160
160
|
SURFACE=""
|
|
161
161
|
DRAFT=""
|
|
162
|
+
BODY_FILE_ERROR=0
|
|
162
163
|
|
|
163
164
|
case "$TOOL_NAME" in
|
|
164
165
|
Bash)
|
|
@@ -169,6 +170,15 @@ try:
|
|
|
169
170
|
except Exception:
|
|
170
171
|
print('')
|
|
171
172
|
" 2>/dev/null || echo "")
|
|
173
|
+
TOOL_CWD=$(printf '%s' "$INPUT" | python3 -c "
|
|
174
|
+
import sys, json
|
|
175
|
+
try:
|
|
176
|
+
event = json.load(sys.stdin)
|
|
177
|
+
tool = event.get('tool_input', {})
|
|
178
|
+
print(tool.get('cwd') or tool.get('workdir') or event.get('cwd') or '')
|
|
179
|
+
except Exception:
|
|
180
|
+
print('')
|
|
181
|
+
" 2>/dev/null || echo "")
|
|
172
182
|
|
|
173
183
|
# Surface match — most-specific first.
|
|
174
184
|
if echo "$COMMAND" | grep -qE '(^|;|&&|\|\|)\s*gh issue create(\s|$)'; then
|
|
@@ -230,13 +240,78 @@ except Exception:
|
|
|
230
240
|
# Then --body / --field for the gh + npm + security-advisories surfaces.
|
|
231
241
|
# Then -m / --message for git commit (single-line literal forms).
|
|
232
242
|
#
|
|
233
|
-
# When absent (npm publish,
|
|
234
|
-
#
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
import sys, re
|
|
243
|
+
# When absent (npm publish, editor flow already filtered), DRAFT=""
|
|
244
|
+
# is acceptable. A named body file must be readable before review.
|
|
245
|
+
if ! DRAFT=$(printf '%s' "$COMMAND" | python3 -c "
|
|
246
|
+
import sys, re, os, shlex
|
|
238
247
|
cmd = sys.stdin.read()
|
|
239
248
|
surface = sys.argv[1]
|
|
249
|
+
tool_cwd = sys.argv[2]
|
|
250
|
+
if surface.startswith('gh-'):
|
|
251
|
+
try:
|
|
252
|
+
lexer = shlex.shlex(cmd, posix=True, punctuation_chars=';&|')
|
|
253
|
+
lexer.whitespace_split = True
|
|
254
|
+
lexer.commenters = ''
|
|
255
|
+
args = list(lexer)
|
|
256
|
+
except ValueError:
|
|
257
|
+
if '--body-file' in cmd or ' -F' in cmd or ' -b' in cmd:
|
|
258
|
+
raise SystemExit(2)
|
|
259
|
+
args = []
|
|
260
|
+
try:
|
|
261
|
+
base = os.path.abspath(tool_cwd) if os.path.isabs(tool_cwd) else ''
|
|
262
|
+
if len(args) >= 4 and args[0] == 'cd' and args[2] == '&&':
|
|
263
|
+
if os.path.isabs(args[1]):
|
|
264
|
+
base = os.path.abspath(args[1])
|
|
265
|
+
elif base:
|
|
266
|
+
base = os.path.abspath(os.path.join(base, args[1]))
|
|
267
|
+
args = args[3:]
|
|
268
|
+
# Skip known option values so a quoted title/body beginning with -F
|
|
269
|
+
# cannot be mistaken for a second body source.
|
|
270
|
+
valued = {'--title', '-t', '--template', '-T', '--repo', '-R',
|
|
271
|
+
'--assignee', '-a', '--label', '-l', '--reviewer', '-r',
|
|
272
|
+
'--milestone', '-m', '--project', '-p', '--base', '-B', '--head', '-H'}
|
|
273
|
+
sources = []
|
|
274
|
+
i = 3
|
|
275
|
+
while i < len(args):
|
|
276
|
+
arg = args[i]
|
|
277
|
+
if arg and all(ch in ';&|' for ch in arg):
|
|
278
|
+
raise ValueError('ambiguous command')
|
|
279
|
+
if arg in ('--body-file', '-F', '--body', '-b'):
|
|
280
|
+
sources.append(('file' if arg in ('--body-file', '-F') else 'body',
|
|
281
|
+
args[i + 1] if i + 1 < len(args) else '', arg))
|
|
282
|
+
i += 2
|
|
283
|
+
elif arg.startswith('--body-file=') or arg.startswith('--body='):
|
|
284
|
+
sources.append(('file' if arg.startswith('--body-file=') else 'body',
|
|
285
|
+
arg.split('=', 1)[1], arg.split('=', 1)[0]))
|
|
286
|
+
i += 1
|
|
287
|
+
elif arg.startswith('-F') or arg.startswith('-b'):
|
|
288
|
+
sources.append(('file' if arg.startswith('-F') else 'body',
|
|
289
|
+
arg[3:] if arg[2:3] == '=' else arg[2:], arg[:2]))
|
|
290
|
+
i += 1
|
|
291
|
+
elif arg in valued:
|
|
292
|
+
i += 2
|
|
293
|
+
else:
|
|
294
|
+
i += 1
|
|
295
|
+
files = [value for kind, value, _ in sources if kind == 'file']
|
|
296
|
+
short_bodies = [value for kind, value, flag in sources if kind == 'body' and flag == '-b']
|
|
297
|
+
if files or short_bodies:
|
|
298
|
+
if args[:2] not in (['gh', 'issue'], ['gh', 'pr']):
|
|
299
|
+
raise ValueError('ambiguous command')
|
|
300
|
+
if files:
|
|
301
|
+
if len(files) != 1 or len(sources) != 1 or not files[0] or files[0] == '-':
|
|
302
|
+
raise ValueError('ambiguous body file')
|
|
303
|
+
if not os.path.isabs(files[0]) and not base:
|
|
304
|
+
raise ValueError('unknown command checkout')
|
|
305
|
+
path = files[0] if os.path.isabs(files[0]) else os.path.join(base, files[0])
|
|
306
|
+
with open(path, encoding='utf-8') as body_file:
|
|
307
|
+
print(body_file.read(), end='')
|
|
308
|
+
else:
|
|
309
|
+
if len(sources) != 1 or not short_bodies[0]:
|
|
310
|
+
raise ValueError('ambiguous body')
|
|
311
|
+
print(short_bodies[0], end='')
|
|
312
|
+
raise SystemExit
|
|
313
|
+
except (OSError, UnicodeError, ValueError):
|
|
314
|
+
raise SystemExit(2)
|
|
240
315
|
# P364: bash double-quote unescape. The double-quoted body capture groups
|
|
241
316
|
# carry RAW shell-escaped command text — an orchestrator must backslash-escape
|
|
242
317
|
# backticks (and \$, \", \\) inside \"...\" to survive bash parsing, e.g.
|
|
@@ -310,7 +385,9 @@ for pat, flags, unescape in patterns:
|
|
|
310
385
|
body = unescape_dq(body)
|
|
311
386
|
print(body)
|
|
312
387
|
break
|
|
313
|
-
" "$SURFACE" 2>/dev/null
|
|
388
|
+
" "$SURFACE" "$TOOL_CWD" 2>/dev/null); then
|
|
389
|
+
BODY_FILE_ERROR=1
|
|
390
|
+
fi
|
|
314
391
|
;;
|
|
315
392
|
|
|
316
393
|
Write|Edit)
|
|
@@ -362,6 +439,11 @@ print(json.dumps({
|
|
|
362
439
|
" "$reason"
|
|
363
440
|
}
|
|
364
441
|
|
|
442
|
+
if [ "$BODY_FILE_ERROR" -eq 1 ]; then
|
|
443
|
+
deny_with_reason "BLOCKED (external-comms gate): body-file could not be read unambiguously from the command checkout. Use one readable UTF-8 --body-file path and review its exact contents before retrying."
|
|
444
|
+
exit 0
|
|
445
|
+
fi
|
|
446
|
+
|
|
365
447
|
permit_with_advisory() {
|
|
366
448
|
local msg="$1"
|
|
367
449
|
python3 -c "
|
package/package.json
CHANGED