Răsfoiți Sursa

test(sandbox): cover POSIX no-shebang fallback

Hypatia May 2 luni în urmă
părinte
comite
c4e9893a87
1 a modificat fișierele cu 37 adăugiri și 12 ștergeri
  1. 37 12
      packages/bash/bash-sandbox/tests/partial-landlock.spec.ts

+ 37 - 12
packages/bash/bash-sandbox/tests/partial-landlock.spec.ts

@@ -132,27 +132,52 @@ describe('partial Landlock runner-failure classification', () => {
     })
   })
 
-  it('keeps a real malformed executable ENOEXEC as an ordinary spawn failure', async () => {
+  it('keeps a real malformed executable ordinary across no-shebang spawn behavior', async () => {
     const dir = await mkdtemp(join(tmpdir(), 'dsh-malformed-sandbox-runner-'))
     tempDirs.push(dir)
     const runner = join(dir, 'malformed-runner')
     await writeFile(runner, 'not a native executable or shebang script\n', { mode: 0o755 })
     const bash = await setupConfiguredRunner(runner)
+    const request = { command: 'true' }
 
-    const foreground = await bash.run(bash.resolve({ command: 'true' })).catch((value: unknown) => value)
-    expect(foreground).toMatchObject({ code: 'ENOEXEC', syscall: 'spawn' })
-    expect((foreground as { path?: unknown }).path).toBeUndefined()
+    // Node/libuv may expose execve's ENOEXEC directly (Darwin) or retry a
+    // no-shebang executable through /bin/sh (Linux). Neither path supplies the
+    // provenanced ENOENT/EACCES evidence required for runner attribution.
+    const foreground = await bash.run(bash.resolve(request)).catch((value: unknown) => value)
     expect(foreground).not.toBeInstanceOf(SandboxUnavailableError)
 
-    let background: unknown
-    try {
-      bash.start(bash.resolve({ command: 'true' }))
-    } catch (error) {
-      background = error
+    if (foreground instanceof Error) {
+      expect(foreground).toMatchObject({ code: 'ENOEXEC', syscall: 'spawn' })
+      expect((foreground as { path?: unknown }).path).toBeUndefined()
+
+      let background: unknown
+      try {
+        bash.start(bash.resolve(request))
+      } catch (error) {
+        background = error
+      }
+      expect(background).toMatchObject({ code: 'ENOEXEC', syscall: 'spawn' })
+      expect((background as { path?: unknown }).path).toBeUndefined()
+      expect(background).not.toBeInstanceOf(SandboxUnavailableError)
+    } else {
+      expect(foreground).toMatchObject({
+        exitCode: 127,
+        signal: null,
+        sandbox: { mode: 'read-only', denied: false, enforcement: 'full' },
+      })
+      expect((foreground as { stderr: { text: string } }).stderr.text).toMatch(/not.*not found/)
+
+      const background = bash.start(bash.resolve(request))
+      await background.done
+      expect(background.status).toBe('completed')
+      expect(background.exitCode).toBe(127)
+      expect(background.signal).toBeNull()
+      expect(background.sandbox).toEqual({ mode: 'read-only', denied: false, enforcement: 'full' })
+      const output = background.readOutput().delta
+      expect(output).toMatch(/\[stderr\]\n[\s\S]*not.*not found/)
+      expect(output).not.toContain('spawn failed:')
     }
-    expect(background).toMatchObject({ code: 'ENOEXEC', syscall: 'spawn' })
-    expect((background as { path?: unknown }).path).toBeUndefined()
-    expect(background).not.toBeInstanceOf(SandboxUnavailableError)
+
     const accounting = (bash as unknown as { processFacts: Map<unknown, unknown> }).processFacts
     expect(accounting.size).toBe(0)
   })