@sema-agent/server 7.134.0 → 7.136.0
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/MIGRATION.md +197 -1
- package/USAGE.md +147 -42
- package/deploy/sema-up/README.md +1 -1
- package/deploy/sema-up/chart/templates/NOTES.txt +1 -1
- package/deploy/sema-up/chart/values.yaml +1 -1
- package/dist/adoption/plan.d.ts +1 -1
- package/dist/approval-ask-audit-store.d.ts +24 -24
- package/dist/approval-ask-machine.d.ts +2 -2
- package/dist/approval-card.d.ts +122 -154
- package/dist/approval-card.js +50 -51
- package/dist/approval-content-kind.d.ts +23 -5
- package/dist/approval-content-kind.js +8 -1
- package/dist/approval-deny-reasons.d.ts +1 -1
- package/dist/approval-gate-currency.d.ts +22 -3
- package/dist/approval-gate-currency.js +44 -18
- package/dist/approval-hmac.d.ts +7 -7
- package/dist/approval-policy-settlement.d.ts +2 -2
- package/dist/approval-reconciler.d.ts +3 -3
- package/dist/approval.d.ts +8 -8
- package/dist/approval.js +4 -2
- package/dist/auth-bridge.d.ts +35 -6
- package/dist/auth-bridge.js +20 -3
- package/dist/auto-mode-face.d.ts +4 -4
- package/dist/background-session-reap.d.ts +2 -2
- package/dist/bake-runner/main.d.ts +2 -2
- package/dist/bake-runner/runner.d.ts +4 -4
- package/dist/bench/s1/live-deps.d.ts +1 -1
- package/dist/bench/s1/run-firm.d.ts +1 -1
- package/dist/boot/budget-tracing.d.ts +1 -2
- package/dist/boot/budget-tracing.js +2 -2
- package/dist/boot/coordinators.d.ts +2 -2
- package/dist/boot/coordinators.js +2 -2
- package/dist/boot/deferred-sandbox-path-env.d.ts +0 -6
- package/dist/boot/deferred-sandbox-path-env.js +0 -5
- package/dist/boot/engine-lease.d.ts +5 -5
- package/dist/boot/execution-env.d.ts +16 -15
- package/dist/boot/execution-env.js +19 -21
- package/dist/boot/fatal-exit.d.ts +2 -2
- package/dist/boot/late-binds.d.ts +1 -1
- package/dist/boot/leader.d.ts +1 -1
- package/dist/boot/memory-boundary.d.ts +2 -2
- package/dist/boot/memory-consolidation.d.ts +15 -15
- package/dist/boot/org-memory.js +1 -1
- package/dist/boot/parked-revive-gate.d.ts +3 -3
- package/dist/boot/parked-revive-gate.js +3 -2
- package/dist/boot/reapers.d.ts +4 -4
- package/dist/boot/resolve-spec.d.ts +1 -1
- package/dist/boot/resolve-spec.js +36 -29
- package/dist/boot/runner-deps.d.ts +11 -11
- package/dist/boot/runner-deps.js +7 -4
- package/dist/boot/session-faces.d.ts +3 -3
- package/dist/boot/session-faces.js +11 -30
- package/dist/boot/shutdown.d.ts +5 -5
- package/dist/boot/side-query-lane.d.ts +2 -2
- package/dist/boot/stage-04-stores.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.d.ts +1 -1
- package/dist/boot/stage-05-execution-env.js +4 -4
- package/dist/boot/stage-06-runners.d.ts +1 -1
- package/dist/boot/stage-06-runners.js +0 -2
- package/dist/boot/stage-07-capability-layer.d.ts +1 -1
- package/dist/boot/stage-08-reapers.d.ts +1 -1
- package/dist/boot/stage-09-leader.d.ts +1 -1
- package/dist/boot/stage-10-http-server.d.ts +1 -1
- package/dist/boot/stores.js +4 -4
- package/dist/boot/web-admin.d.ts +17 -17
- package/dist/boot/web-admin.js +15 -27
- package/dist/boot/workflow-orchestration.js +2 -9
- package/dist/brain.d.ts +11 -11
- package/dist/brain.js +12 -3
- package/dist/budget.d.ts +7 -7
- package/dist/budget.js +4 -0
- package/dist/capabilities/approvals-push.d.ts +4 -4
- package/dist/capabilities/builtin-tools.d.ts +5 -5
- package/dist/capabilities/center-plugins.d.ts +5 -5
- package/dist/capabilities/center-plugins.js +1 -1
- package/dist/capabilities/center-prompts.d.ts +1 -1
- package/dist/capabilities/center-wiring.d.ts +1 -1
- package/dist/capabilities/composite-members.d.ts +1 -1
- package/dist/capabilities/execution-lane.d.ts +5 -5
- package/dist/capabilities/execution-lane.js +2 -2
- package/dist/capabilities/hands-lane.d.ts +5 -5
- package/dist/capabilities/mcp-probe.d.ts +11 -7
- package/dist/capabilities/sandbox-file-send.d.ts +1 -18
- package/dist/capabilities/sandbox-file-send.js +0 -7
- package/dist/capabilities/scenarios.d.ts +28 -10
- package/dist/capabilities/scenarios.js +15 -5
- package/dist/capabilities/send-user-file-tool.d.ts +1 -1
- package/dist/capabilities/skills.d.ts +31 -12
- package/dist/capabilities/skills.js +23 -17
- package/dist/capabilities/tool-defer.d.ts +1 -1
- package/dist/capability-facts.d.ts +29 -32
- package/dist/capability-facts.js +17 -21
- package/dist/center-config-tier.d.ts +1 -1
- package/dist/center-credential.d.ts +22 -8
- package/dist/center-credential.js +18 -3
- package/dist/checkpoint-identity.d.ts +5 -0
- package/dist/checkpoint-identity.js +14 -0
- package/dist/config-catalog.d.ts +12 -12
- package/dist/config-catalog.js +12 -10
- package/dist/config-d-migration.js +1 -1
- package/dist/config-invariants.d.ts +5 -5
- package/dist/config-invariants.js +11 -2
- package/dist/config-lkg.d.ts +1 -39
- package/dist/config-lkg.js +1 -83
- package/dist/config-provider.d.ts +13 -13
- package/dist/config-provider.js +2 -1
- package/dist/config-types.d.ts +95 -87
- package/dist/config.d.ts +26 -24
- package/dist/config.js +38 -18
- package/dist/cross-session-settings.d.ts +1 -1
- package/dist/delegated-session-owner.d.ts +16 -13
- package/dist/delegated-session-owner.js +9 -10
- package/dist/deployment-governance.d.ts +16 -16
- package/dist/deployment-shape.d.ts +127 -0
- package/dist/deployment-shape.js +72 -0
- package/dist/device-store.d.ts +1 -1
- package/dist/device-ws-hub.d.ts +1 -1
- package/dist/egress-redirect.d.ts +1 -1
- package/dist/elicitation.d.ts +8 -7
- package/dist/elicitation.js +9 -8
- package/dist/entry-mode-clamp-notice.d.ts +2 -2
- package/dist/env-facts.d.ts +10 -9
- package/dist/env-facts.js +1 -1
- package/dist/env-name-allowlist-knobs.d.ts +5 -5
- package/dist/exec-bounds.d.ts +2 -2
- package/dist/execution-lane-caps.d.ts +31 -43
- package/dist/execution-lane-caps.js +0 -13
- package/dist/file-history-capture.d.ts +9 -9
- package/dist/file-history-disclosure.d.ts +25 -11
- package/dist/file-history-disclosure.js +25 -14
- package/dist/fleet/drain-entry.d.ts +2 -2
- package/dist/fleet/fleet-bus.d.ts +22 -14
- package/dist/fleet/fleet-bus.js +5 -5
- package/dist/fleet/fleet-reconciler.d.ts +9 -9
- package/dist/fleet/subagent-tail-bus.d.ts +4 -4
- package/dist/fleet-client.d.ts +45 -14
- package/dist/fleet-client.js +24 -4
- package/dist/fleet-lease.d.ts +23 -19
- package/dist/fleet-lease.js +31 -23
- package/dist/governance-http-status.d.ts +2 -2
- package/dist/hooks/hook-llm.d.ts +7 -7
- package/dist/hooks/hook-llm.js +14 -8
- package/dist/hooks/hook-runner.d.ts +58 -31
- package/dist/hooks/hook-runner.js +37 -19
- package/dist/host-decision.d.ts +5 -5
- package/dist/host-lsp-manager.d.ts +5 -5
- package/dist/hosted-posture.d.ts +23 -13
- package/dist/hosted-posture.js +4 -9
- package/dist/http/admission.d.ts +2 -2
- package/dist/http/admission.js +20 -5
- package/dist/http/approval-sweeps.d.ts +1 -1
- package/dist/http/approval-sweeps.js +2 -1
- package/dist/http/checkpoint-ctx.d.ts +62 -17
- package/dist/http/checkpoint-ctx.js +78 -35
- package/dist/http/dispatch.d.ts +3 -3
- package/dist/http/dispatch.js +9 -9
- package/dist/http/durable-run-leg.js +4 -3
- package/dist/http/idempotency.d.ts +2 -2
- package/dist/http/mcp-dial-deadline.d.ts +7 -5
- package/dist/http/memory-compliance-failure-reply.d.ts +4 -4
- package/dist/http/owner-access.d.ts +4 -6
- package/dist/http/owner-access.js +1 -1
- package/dist/http/principal-gate.d.ts +7 -7
- package/dist/http/principal-gate.js +3 -2
- package/dist/http/readiness.d.ts +1 -1
- package/dist/http/request-guards.d.ts +4 -4
- package/dist/http/request-guards.js +2 -1
- package/dist/http/resume-ctx-read.d.ts +9 -23
- package/dist/http/resume-ctx-read.js +2 -3
- package/dist/http/resume-legs.d.ts +3 -3
- package/dist/http/resume-legs.js +11 -8
- package/dist/http/route-ctx.d.ts +29 -29
- package/dist/http/route-table.d.ts +9 -9
- package/dist/http/routes/agents-roster.d.ts +1 -1
- package/dist/http/routes/approvals-assistant.d.ts +5 -7
- package/dist/http/routes/approvals-assistant.js +101 -26
- package/dist/http/routes/background.d.ts +3 -3
- package/dist/http/routes/background.js +2 -2
- package/dist/http/routes/capabilities.d.ts +1 -1
- package/dist/http/routes/capabilities.js +16 -8
- package/dist/http/routes/config-catalog.d.ts +1 -1
- package/dist/http/routes/devices.d.ts +1 -1
- package/dist/http/routes/diagnostics.d.ts +3 -3
- package/dist/http/routes/fleet.d.ts +1 -1
- package/dist/http/routes/fleet.js +2 -1
- package/dist/http/routes/mcp-reconnect.d.ts +4 -4
- package/dist/http/routes/mcp-reconnect.js +3 -3
- package/dist/http/routes/memory-consolidation.d.ts +1 -1
- package/dist/http/routes/notify-wake.d.ts +1 -1
- package/dist/http/routes/notify-wake.js +2 -2
- package/dist/http/routes/rules.d.ts +1 -1
- package/dist/http/routes/runs.js +23 -11
- package/dist/http/routes/session-sync.d.ts +1 -1
- package/dist/http/routes/session-sync.js +97 -46
- package/dist/http/routes/sessions-list.js +1 -1
- package/dist/http/routes/sessions.js +43 -53
- package/dist/http/routes/tasks.d.ts +1 -1
- package/dist/http/routes/trace-usage.d.ts +1 -1
- package/dist/http/routes/workflows.d.ts +3 -0
- package/dist/http/routes/workflows.js +31 -28
- package/dist/http/send.d.ts +5 -5
- package/dist/http/server.d.ts +34 -34
- package/dist/http/session-inherit-env.d.ts +3 -3
- package/dist/http/sse-lifecycle.d.ts +1 -1
- package/dist/http/sse-log.d.ts +2 -2
- package/dist/http/submit-ctx.js +1 -1
- package/dist/http/sync-submit-body.d.ts +1 -1
- package/dist/http/verify-rounds.d.ts +1 -1
- package/dist/http/wire-types.d.ts +33 -24
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/instruction-source-notice.d.ts +2 -2
- package/dist/key-resolver.d.ts +3 -3
- package/dist/lane-home-probe.d.ts +1 -1
- package/dist/leader/diffout.d.ts +1 -1
- package/dist/leader/diffup.d.ts +2 -2
- package/dist/leader/endpoint.d.ts +1 -1
- package/dist/leader/fanout.d.ts +1 -1
- package/dist/leader/leader.d.ts +4 -4
- package/dist/leader/merge.d.ts +3 -3
- package/dist/leader/repair-wire.d.ts +1 -1
- package/dist/leader/wire.d.ts +6 -6
- package/dist/list-entry-display.d.ts +1 -1
- package/dist/lsp-evict.d.ts +1 -1
- package/dist/mcp-assertion-header.d.ts +1 -1
- package/dist/memory-layer-legacy-lock.d.ts +1 -1
- package/dist/memory-operator-faces.d.ts +1 -1
- package/dist/memory-posture.js +4 -2
- package/dist/memory-project-layer.d.ts +1 -1
- package/dist/memory-scope.d.ts +19 -19
- package/dist/memory-store-refusal.d.ts +4 -4
- package/dist/model-entry-headers.d.ts +2 -2
- package/dist/model-entry-refusal.d.ts +17 -17
- package/dist/model-provider.d.ts +10 -10
- package/dist/model-reach-scope.d.ts +1 -1
- package/dist/model-route-endpoint.d.ts +6 -6
- package/dist/model-route-gap.d.ts +49 -4
- package/dist/model-route-gap.js +34 -1
- package/dist/model-route-url.d.ts +5 -5
- package/dist/model-select.d.ts +15 -6
- package/dist/model-select.js +5 -0
- package/dist/model-unreachable-notice.d.ts +3 -3
- package/dist/namespaced-rule-name.d.ts +15 -5
- package/dist/namespaced-rule-name.js +3 -2
- package/dist/object-store-buckets.d.ts +13 -0
- package/dist/object-store-buckets.js +3 -0
- package/dist/observability/corrupt-read-seat.d.ts +9 -9
- package/dist/observability/cost-taxonomy.d.ts +1 -1
- package/dist/observability/err-text.d.ts +1 -1
- package/dist/observability/fail-open.d.ts +17 -13
- package/dist/observability/fail-open.js +17 -13
- package/dist/observability/metrics.d.ts +3 -3
- package/dist/observability/metrics.js +1 -1
- package/dist/observability/principal-context.d.ts +4 -1
- package/dist/observability/principal-context.js +6 -1
- package/dist/observability/run-terminal.d.ts +36 -36
- package/dist/observability/secret-env-scrub.d.ts +3 -3
- package/dist/observability/tool-trace.d.ts +1 -1
- package/dist/operator-ask.d.ts +4 -4
- package/dist/orchestration/workflow-agent-session-index.d.ts +3 -3
- package/dist/orchestration/workflow-completion-inbox.d.ts +20 -5
- package/dist/orchestration/workflow-completion-inbox.js +29 -7
- package/dist/orchestration/workflow-notify-journal.d.ts +43 -19
- package/dist/orchestration/workflow-notify-journal.js +17 -0
- package/dist/outbound-dispatcher.d.ts +4 -4
- package/dist/parent-watch.d.ts +4 -4
- package/dist/parked-decide.d.ts +20 -18
- package/dist/parked-decide.js +31 -11
- package/dist/parked-revive-surface.d.ts +7 -7
- package/dist/parked-revive-surface.js +2 -3
- package/dist/peer-directory.d.ts +5 -4
- package/dist/peer-directory.js +6 -6
- package/dist/permission-rule-list.d.ts +10 -1
- package/dist/permission-rule-list.js +7 -5
- package/dist/permission-rule-vocab.d.ts +2 -2
- package/dist/plugins/adoption-log-sql.d.ts +1 -1
- package/dist/plugins/approval-ask-store-file.d.ts +8 -1
- package/dist/plugins/approval-ask-store-file.js +6 -3
- package/dist/plugins/approval-ask-store-memory.d.ts +11 -7
- package/dist/plugins/approval-ask-store-memory.js +11 -7
- package/dist/plugins/approval-ask-store-sql.d.ts +42 -15
- package/dist/plugins/approval-ask-store-sql.js +21 -5
- package/dist/plugins/approval-exemption-store.d.ts +3 -3
- package/dist/plugins/approval-nonce-store.d.ts +3 -3
- package/dist/plugins/background-agent-store-sql.d.ts +1 -1
- package/dist/plugins/background-shell-support.d.ts +2 -2
- package/dist/plugins/blob-backend.d.ts +1 -1
- package/dist/plugins/blob-backend.js +2 -1
- package/dist/plugins/caching-session-store.d.ts +23 -32
- package/dist/plugins/caching-session-store.js +5 -17
- package/dist/plugins/checkpoint-index-columns.d.ts +130 -0
- package/dist/plugins/checkpoint-index-columns.js +90 -0
- package/dist/plugins/checkpoint-store-sql.d.ts +71 -69
- package/dist/plugins/checkpoint-store-sql.js +109 -127
- package/dist/plugins/device-store-sql.d.ts +7 -6
- package/dist/plugins/e2b-orphan-reclaim.d.ts +1 -1
- package/dist/plugins/ensure-schema-lock-policy.d.ts +1 -1
- package/dist/plugins/file-history-store-sql.d.ts +15 -7
- package/dist/plugins/file-history-store-sql.js +55 -36
- package/dist/plugins/file-run-store.d.ts +8 -8
- package/dist/plugins/fork-routing-session-store.d.ts +2 -2
- package/dist/plugins/fork-routing-session-store.js +1 -1
- package/dist/plugins/host-platform.d.ts +10 -10
- package/dist/plugins/image-bake-store-sql.d.ts +1 -1
- package/dist/plugins/image-index-sql.d.ts +1 -1
- package/dist/plugins/leader-run-store-sql.d.ts +1 -1
- package/dist/plugins/local-checkpoint-store.d.ts +10 -10
- package/dist/plugins/local-checkpoint-store.js +7 -7
- package/dist/plugins/local-session-store.d.ts +34 -38
- package/dist/plugins/local-session-store.js +20 -39
- package/dist/plugins/local-session-window.d.ts +1 -1
- package/dist/plugins/mailbox-store-sql.d.ts +2 -2
- package/dist/plugins/memory-engine-pg.d.ts +1 -1
- package/dist/plugins/memory-run-store.d.ts +4 -4
- package/dist/plugins/memory-sync-store-pg.d.ts +3 -3
- package/dist/plugins/one-time-migrations.d.ts +73 -54
- package/dist/plugins/one-time-migrations.js +131 -134
- package/dist/plugins/outcome-ledger-sql.d.ts +1 -1
- package/dist/plugins/park-commit-watch.d.ts +3 -3
- package/dist/plugins/permission-rule-store-file.d.ts +5 -5
- package/dist/plugins/permission-rule-store-file.js +12 -19
- package/dist/plugins/permission-rule-store-sql.d.ts +38 -4
- package/dist/plugins/permission-rule-store-sql.js +67 -24
- package/dist/plugins/pg-cost-quota.d.ts +1 -1
- package/dist/plugins/pg-pool.d.ts +2 -2
- package/dist/plugins/pg-pool.js +5 -2
- package/dist/plugins/pg-rate-limiter.d.ts +1 -1
- package/dist/plugins/pg-session-storage.d.ts +8 -20
- package/dist/plugins/pg-session-storage.js +14 -27
- package/dist/plugins/remote-env-adb.d.ts +10 -10
- package/dist/plugins/remote-env-device.d.ts +10 -9
- package/dist/plugins/remote-env-device.js +6 -2
- package/dist/plugins/remote-env-e2b.d.ts +3 -3
- package/dist/plugins/remote-env-host.d.ts +16 -16
- package/dist/plugins/remote-env-k8s.d.ts +26 -13
- package/dist/plugins/remote-env-k8s.js +24 -7
- package/dist/plugins/remote-env-local-docker.d.ts +2 -2
- package/dist/plugins/remote-env-ssh.d.ts +4 -4
- package/dist/plugins/remote-scratchpad.d.ts +2 -3
- package/dist/plugins/remote-scratchpad.js +0 -4
- package/dist/plugins/remote-shell.d.ts +6 -6
- package/dist/plugins/retention-lane-store-sql.d.ts +4 -4
- package/dist/plugins/retention-store-sql.d.ts +4 -4
- package/dist/plugins/roster-store-sql.d.ts +1 -1
- package/dist/plugins/run-store-sql.d.ts +8 -8
- package/dist/plugins/s3-answer.d.ts +15 -0
- package/dist/plugins/s3-answer.js +5 -0
- package/dist/plugins/schema-consistency.d.ts +2 -2
- package/dist/plugins/schema-ensure-legs.d.ts +3 -3
- package/dist/plugins/schema-indexes.d.ts +1 -1
- package/dist/plugins/schema-live-columns.d.ts +1 -1
- package/dist/plugins/session-event-payload.d.ts +4 -4
- package/dist/plugins/session-fork.d.ts +34 -0
- package/dist/plugins/session-fork.js +29 -0
- package/dist/plugins/session-ownership.js +1 -1
- package/dist/plugins/session-placement.d.ts +1 -1
- package/dist/plugins/session-policy-store-sql.d.ts +12 -12
- package/dist/plugins/session-store.d.ts +2 -2
- package/dist/plugins/session-store.js +2 -2
- package/dist/plugins/shared-memory-store-sql.d.ts +2 -2
- package/dist/plugins/snapshot-bucket-presence.d.ts +39 -4
- package/dist/plugins/snapshot-bucket-presence.js +35 -7
- package/dist/plugins/sql-driver.d.ts +8 -8
- package/dist/plugins/sql-errors.d.ts +40 -1
- package/dist/plugins/sql-errors.js +49 -1
- package/dist/plugins/sql-json-column.d.ts +21 -21
- package/dist/plugins/sql-row-helpers.d.ts +2 -2
- package/dist/plugins/store-backend.d.ts +17 -16
- package/dist/plugins/store-backend.js +3 -3
- package/dist/plugins/store-contracts.d.ts +21 -21
- package/dist/plugins/store-fault.d.ts +4 -0
- package/dist/plugins/store-fault.js +8 -0
- package/dist/plugins/task-attachment-store.d.ts +2 -2
- package/dist/plugins/task-list-store-sql.d.ts +1 -1
- package/dist/plugins/tidb-pool.d.ts +2 -2
- package/dist/plugins/tidb-pool.js +10 -3
- package/dist/plugins/tidb-session-store.d.ts +16 -26
- package/dist/plugins/tidb-session-store.js +15 -27
- package/dist/plugins/tool-result-store-sql.d.ts +1 -1
- package/dist/plugins/usage-window-store-sql.d.ts +3 -3
- package/dist/plugins/user-input-ledger-file.d.ts +1 -1
- package/dist/plugins/user-input-ledger-sql.d.ts +3 -3
- package/dist/plugins/web-search.d.ts +19 -5
- package/dist/plugins/web-search.js +20 -5
- package/dist/{orchestration/workflow-journal-entry.d.ts → plugins/workflow-journal-payload.d.ts} +23 -32
- package/dist/plugins/workflow-journal-payload.js +32 -0
- package/dist/plugins/workflow-journal-store-sql.d.ts +28 -14
- package/dist/plugins/workflow-journal-store-sql.js +34 -15
- package/dist/plugins/workflow-run-store-sql.d.ts +4 -4
- package/dist/posture-source.d.ts +11 -11
- package/dist/principal-jwt.d.ts +6 -6
- package/dist/project-identity.d.ts +3 -3
- package/dist/project-memory.d.ts +4 -4
- package/dist/read-face-posture.d.ts +7 -7
- package/dist/request-declaration-refusal.d.ts +94 -0
- package/dist/request-declaration-refusal.js +78 -0
- package/dist/request-image-urls.d.ts +6 -0
- package/dist/request-image-urls.js +27 -0
- package/dist/request-key-closure.d.ts +6 -1
- package/dist/request-key-closure.js +5 -2
- package/dist/request-value-closure.d.ts +15 -8
- package/dist/request-value-closure.js +2 -0
- package/dist/router/route-orchestration.d.ts +11 -16
- package/dist/router/route-orchestration.js +2 -12
- package/dist/rule-entry-list.d.ts +8 -7
- package/dist/rule-entry-list.js +2 -9
- package/dist/rules-consent.d.ts +6 -6
- package/dist/rules-consent.js +2 -0
- package/dist/run-cancel-context.d.ts +5 -5
- package/dist/run-local.d.ts +10 -10
- package/dist/runs.d.ts +13 -11
- package/dist/runs.js +15 -1
- package/dist/runtime-caps-resolver.d.ts +6 -6
- package/dist/runtime-caps-resolver.js +1 -1
- package/dist/runtime-governance.d.ts +9 -9
- package/dist/sandbox-pkg-source.d.ts +17 -12
- package/dist/sandbox-pkg-source.js +14 -9
- package/dist/sealed-key.d.ts +22 -3
- package/dist/sealed-key.js +47 -4
- package/dist/security.d.ts +23 -26
- package/dist/security.js +12 -9
- package/dist/server-secret-env.d.ts +10 -10
- package/dist/session-children-retire.d.ts +1 -1
- package/dist/session-error-wire.d.ts +7 -7
- package/dist/session-incarnation.d.ts +65 -37
- package/dist/session-incarnation.js +30 -12
- package/dist/session-policy-wire.d.ts +27 -5
- package/dist/session-policy-wire.js +15 -1
- package/dist/session-records-skipped-notice.d.ts +1 -1
- package/dist/session-row.d.ts +3 -17
- package/dist/session-row.js +4 -0
- package/dist/session-sync-kernel.d.ts +4 -4
- package/dist/session-sync.d.ts +61 -6
- package/dist/session-sync.js +55 -10
- package/dist/session-titler.d.ts +7 -6
- package/dist/session-titler.js +8 -13
- package/dist/session-watch.d.ts +3 -3
- package/dist/session-watch.js +4 -4
- package/dist/sighup-idle.d.ts +2 -2
- package/dist/spec-fields.d.ts +4 -4
- package/dist/sql-engine-posture.d.ts +3 -3
- package/dist/store-posture.d.ts +2 -2
- package/dist/stored-request-tool-axes-m19.d.ts +1 -1
- package/dist/task-a2a.d.ts +52 -79
- package/dist/task-a2a.js +224 -62
- package/dist/task-cwd.d.ts +7 -88
- package/dist/task-cwd.js +2 -15
- package/dist/task-mcp.d.ts +13 -17
- package/dist/task-mcp.js +29 -49
- package/dist/task-settings.d.ts +30 -18
- package/dist/task-settings.js +33 -3
- package/dist/task-workflow.d.ts +0 -24
- package/dist/task-workflow.js +2 -1
- package/dist/terminal.d.ts +5 -5
- package/dist/tighten-only-seats.d.ts +7 -6
- package/dist/tighten-only-seats.js +1 -1
- package/dist/tool-approval.d.ts +166 -207
- package/dist/tool-approval.js +61 -61
- package/dist/tool-rule-names.d.ts +2 -2
- package/dist/trace/core-keyset-guard.d.ts +13 -8
- package/dist/trace/engine-notice-wire.d.ts +5 -5
- package/dist/trace/engine-notice-wire.js +1 -0
- package/dist/trace/exit-seat.d.ts +31 -4
- package/dist/trace/exit-seat.js +69 -67
- package/dist/trace/ledger-events.d.ts +3 -3
- package/dist/trace/ledger-sink.d.ts +1 -1
- package/dist/trace/model-segment.d.ts +3 -3
- package/dist/trace/project.d.ts +47 -45
- package/dist/trace/project.js +33 -1
- package/dist/trace/redact.d.ts +61 -31
- package/dist/trace/redact.js +394 -153
- package/dist/trace/self-minted-wire.d.ts +302 -14
- package/dist/trace/self-minted-wire.js +87 -0
- package/dist/trace/sema-provenance.d.ts +1 -1
- package/dist/trace/task-notification-facets.d.ts +4 -4
- package/dist/trace/wire-projection-faces.d.ts +3 -3
- package/dist/trace/wire-projection-faces.js +1 -1
- package/dist/unattended-permission-mode.d.ts +5 -5
- package/dist/url-credential-refusal.d.ts +52 -0
- package/dist/url-credential-refusal.js +14 -0
- package/dist/url-refusal.d.ts +16 -3
- package/dist/url-refusal.js +15 -2
- package/dist/usage-analytics.d.ts +2 -2
- package/dist/user-input-ledger.d.ts +23 -23
- package/dist/web-admin-client/apply-effective.d.ts +5 -5
- package/dist/web-admin-client/apply-effective.js +2 -1
- package/dist/web-admin-client/apply-ledger.d.ts +2 -2
- package/dist/web-admin-client/center-request.d.ts +2 -2
- package/dist/web-admin-client/facade.d.ts +5 -5
- package/dist/web-admin-client/facade.js +1 -1
- package/dist/web-admin-client/hot-keys-registry.d.ts +2 -2
- package/dist/web-admin-client/http-client.d.ts +4 -4
- package/dist/web-admin-client/mcp-revocation.d.ts +1 -1
- package/dist/web-admin-client/pull-state.d.ts +1 -1
- package/dist/web-admin-client/read-face.d.ts +2 -2
- package/dist/web-admin-client/read-warnings.d.ts +5 -5
- package/dist/web-admin-client/restart-signal.d.ts +6 -6
- package/dist/web-admin-client/skills-mcp.d.ts +28 -3
- package/dist/web-admin-client/skills-mcp.js +29 -1
- package/dist/web-admin-client/types.d.ts +16 -9
- package/dist/workspace-space.d.ts +32 -3
- package/dist/workspace-space.js +26 -0
- package/dist/write-protection.d.ts +2 -2
- package/package.json +5 -3
- package/scripts/drain-check-local.mjs +4 -2
- package/scripts/drain-check.mysql.sql +6 -2
- package/scripts/drain-check.pg.sql +6 -2
- package/skills/loop.md +1 -1
- package/skills/schedule.md +1 -1
- package/wire-changes/server@7.104.0.json +134 -0
- package/wire-changes/server@7.105.0.json +53 -0
- package/wire-changes/server@7.106.0.json +475 -0
- package/wire-changes/server@7.107.0.json +64 -0
- package/wire-changes/server@7.108.0.json +153 -0
- package/wire-changes/server@7.109.0.json +46 -0
- package/wire-changes/server@7.110.0.json +90 -0
- package/wire-changes/server@7.111.0.json +86 -0
- package/wire-changes/server@7.112.0.json +60 -0
- package/wire-changes/server@7.113.0.json +26 -0
- package/wire-changes/server@7.114.0.json +26 -0
- package/wire-changes/server@7.115.0.json +97 -0
- package/wire-changes/server@7.116.0.json +218 -0
- package/wire-changes/server@7.116.1.json +26 -0
- package/wire-changes/server@7.117.0.json +65 -0
- package/wire-changes/server@7.118.0.json +129 -0
- package/wire-changes/server@7.119.0.json +65 -0
- package/wire-changes/server@7.120.0.json +89 -0
- package/wire-changes/server@7.121.0.json +219 -0
- package/wire-changes/server@7.122.0.json +54 -0
- package/wire-changes/server@7.123.0.json +26 -0
- package/wire-changes/server@7.124.0.json +336 -0
- package/wire-changes/server@7.124.1.json +26 -0
- package/wire-changes/server@7.125.0.json +111 -0
- package/wire-changes/server@7.126.0.json +285 -0
- package/wire-changes/server@7.127.0.json +77 -0
- package/wire-changes/server@7.127.1.json +26 -0
- package/wire-changes/server@7.127.2.json +53 -0
- package/wire-changes/server@7.128.0.json +26 -0
- package/wire-changes/server@7.129.0.json +106 -0
- package/wire-changes/server@7.129.1.json +26 -0
- package/wire-changes/server@7.130.0.json +26 -0
- package/wire-changes/server@7.131.0.json +118 -0
- package/wire-changes/server@7.132.0.json +226 -0
- package/wire-changes/server@7.133.0.json +1155 -0
- package/wire-changes/server@7.134.0.json +107 -0
- package/wire-changes/server@7.135.0.json +174 -0
- package/wire-changes/server@7.136.0.json +448 -0
- package/dist/http/run-declared-families.d.ts +0 -16
- package/dist/http/run-declared-families.js +0 -12
- package/dist/orchestration/workflow-journal-entry.js +0 -27
package/dist/trace/redact.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { displayUrlOf, stripFormatCharacters } from "@sema-agent/core";
|
|
2
|
-
import { isHierarchicalUrl } from "@sema-agent/settings-schema";
|
|
2
|
+
import { CONTROL_AND_BIDI_CHARS, CREDENTIAL_PARAM_NAMES, isHierarchicalUrl } from "@sema-agent/settings-schema";
|
|
3
3
|
import { recordFailOpen } from "../observability/fail-open.js";
|
|
4
4
|
const normalizeForRedaction = stripFormatCharacters;
|
|
5
5
|
export function mapNormalizedToOriginal(text, normalized) {
|
|
@@ -28,43 +28,91 @@ export function mapNormalizedToOriginal(text, normalized) {
|
|
|
28
28
|
map[normalized.length] = text.length;
|
|
29
29
|
return map;
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
const SPELLED_FORMAT = 1, SPELLED_CONTROL = 2, RAW_CONTROL = 4, RAW_WHITESPACE = 8;
|
|
32
|
+
const INVISIBLE_UNIT_CLASS = (() => {
|
|
33
|
+
const inSet = new RegExp(`[${CONTROL_AND_BIDI_CHARS}]`);
|
|
34
|
+
const table = new Uint8Array(0x10000);
|
|
35
|
+
for (let unit = 0; unit < table.length; unit++) {
|
|
36
|
+
const ch = String.fromCharCode(unit);
|
|
37
|
+
if (inSet.test(ch))
|
|
38
|
+
table[unit] = /\s/.test(ch) ? 2 : 1;
|
|
39
|
+
}
|
|
40
|
+
return table;
|
|
41
|
+
})();
|
|
42
|
+
const RAW_STRIP_SET_RE = (() => {
|
|
43
|
+
let body = "";
|
|
44
|
+
for (let unit = 0; unit < 0x10000; unit++) {
|
|
45
|
+
if (INVISIBLE_UNIT_CLASS[unit] === 0)
|
|
46
|
+
continue;
|
|
47
|
+
let last = unit;
|
|
48
|
+
while (last + 1 < 0x10000 && INVISIBLE_UNIT_CLASS[last + 1] !== 0)
|
|
49
|
+
last += 1;
|
|
50
|
+
const hex = (u) => `\\u${u.toString(16).padStart(4, "0")}`;
|
|
51
|
+
body += last === unit ? hex(unit) : `${hex(unit)}-${hex(last)}`;
|
|
52
|
+
unit = last;
|
|
53
|
+
}
|
|
54
|
+
return new RegExp(`[${body}]`, "g");
|
|
55
|
+
})();
|
|
56
|
+
function collectRawControlCuts(s, allowed) {
|
|
57
|
+
const cuts = [];
|
|
58
|
+
let present = 0;
|
|
59
|
+
if ((allowed & (RAW_CONTROL | RAW_WHITESPACE)) === 0)
|
|
60
|
+
return { cuts, present };
|
|
61
|
+
RAW_STRIP_SET_RE.lastIndex = 0;
|
|
62
|
+
for (let m = RAW_STRIP_SET_RE.exec(s); m !== null; m = RAW_STRIP_SET_RE.exec(s)) {
|
|
63
|
+
const cls = INVISIBLE_UNIT_CLASS[s.charCodeAt(m.index)] === 2 ? RAW_WHITESPACE : RAW_CONTROL;
|
|
64
|
+
if ((cls & allowed) === 0)
|
|
65
|
+
continue;
|
|
66
|
+
cuts.push(m.index, m.index + 1, cls);
|
|
67
|
+
present |= cls;
|
|
68
|
+
}
|
|
69
|
+
return { cuts, present };
|
|
70
|
+
}
|
|
71
|
+
function collectSpelledCuts(s) {
|
|
72
|
+
const cuts = [];
|
|
73
|
+
let present = 0;
|
|
32
74
|
let i = s.indexOf("\\");
|
|
33
75
|
if (i < 0)
|
|
34
|
-
return {
|
|
76
|
+
return { cuts, present };
|
|
35
77
|
const n = s.length;
|
|
36
78
|
const read = { end: 0 };
|
|
37
|
-
let cuts;
|
|
38
79
|
while (i >= 0) {
|
|
39
80
|
let body = i + 1;
|
|
40
81
|
while (body < n && s.charCodeAt(body) === CH_BACKSLASH)
|
|
41
82
|
body += 1;
|
|
42
83
|
const cp = readSpelledCodePoint(s, body, read);
|
|
43
|
-
|
|
44
|
-
|
|
84
|
+
const cls = cp < 0 ? 0 : isFormatCodePoint(cp) ? SPELLED_FORMAT : cp < 0x10000 && INVISIBLE_UNIT_CLASS[cp] === 1 ? SPELLED_CONTROL : 0;
|
|
85
|
+
if (cls !== 0) {
|
|
86
|
+
cuts.push(i, read.end, cls);
|
|
87
|
+
present |= cls;
|
|
45
88
|
body = read.end;
|
|
46
89
|
}
|
|
47
90
|
i = s.indexOf("\\", body);
|
|
48
91
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
const
|
|
53
|
-
const
|
|
92
|
+
return { cuts, present };
|
|
93
|
+
}
|
|
94
|
+
function deleteInvisibleCharacters(s, all, mask) {
|
|
95
|
+
const atList = [];
|
|
96
|
+
const cumList = [];
|
|
54
97
|
const parts = [];
|
|
55
98
|
let from = 0;
|
|
56
99
|
let removed = 0;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
100
|
+
const { cuts } = all;
|
|
101
|
+
for (let k = 0; k < cuts.length; k += 3) {
|
|
102
|
+
if ((cuts[k + 2] & mask) === 0)
|
|
103
|
+
continue;
|
|
104
|
+
const a = cuts[k];
|
|
105
|
+
const b = cuts[k + 1];
|
|
60
106
|
parts.push(s.slice(from, a));
|
|
61
|
-
|
|
107
|
+
atList.push(a - removed);
|
|
62
108
|
removed += b - a;
|
|
63
|
-
|
|
109
|
+
cumList.push(removed);
|
|
64
110
|
from = b;
|
|
65
111
|
}
|
|
112
|
+
if (atList.length === 0)
|
|
113
|
+
return { text: s, at: undefined, cum: undefined };
|
|
66
114
|
parts.push(s.slice(from));
|
|
67
|
-
return { text: parts.join(""), at, cum };
|
|
115
|
+
return { text: parts.join(""), at: Int32Array.from(atList), cum: Int32Array.from(cumList) };
|
|
68
116
|
}
|
|
69
117
|
function viewIndexInInput(fold, v) {
|
|
70
118
|
const at = fold.at;
|
|
@@ -413,8 +461,9 @@ let urlSegmentRuns = 0;
|
|
|
413
461
|
let urlSegmentReplays = 0;
|
|
414
462
|
let ssh2ScanBytes = 0;
|
|
415
463
|
let mappedUnits = 0;
|
|
464
|
+
let readings = 0;
|
|
416
465
|
export function armPoolBudgetForTest() {
|
|
417
|
-
return { spanCount: poolSpanCount, coveredPositions, headScreenHits, fullYCalls, armCount: poolArmCount, boundaryArmCount: poolBoundaryArmCount, forensicLevels, forensicRuns, forensicSkips, urlSegmentRuns, urlSegmentReplays, ssh2ScanBytes, mappedUnits };
|
|
466
|
+
return { spanCount: poolSpanCount, coveredPositions, headScreenHits, fullYCalls, armCount: poolArmCount, boundaryArmCount: poolBoundaryArmCount, forensicLevels, forensicRuns, forensicSkips, urlSegmentRuns, urlSegmentReplays, ssh2ScanBytes, mappedUnits, readings };
|
|
418
467
|
}
|
|
419
468
|
export function resetArmPoolBudgetForTest() {
|
|
420
469
|
poolSpanCount = 0;
|
|
@@ -428,6 +477,7 @@ export function resetArmPoolBudgetForTest() {
|
|
|
428
477
|
urlSegmentReplays = 0;
|
|
429
478
|
ssh2ScanBytes = 0;
|
|
430
479
|
mappedUnits = 0;
|
|
480
|
+
readings = 0;
|
|
431
481
|
}
|
|
432
482
|
const unitBit = (t, c) => (t[c >>> 5] >>> (c & 31)) & 1;
|
|
433
483
|
let codeUnitDomain;
|
|
@@ -786,14 +836,19 @@ const CREDENTIAL_NAME_ANCHORS = {
|
|
|
786
836
|
"x-amz-signature": "structure-only", "x-amz-security-token": "structure-only", "x-amz-credential": "structure-only",
|
|
787
837
|
sas: "structure-only",
|
|
788
838
|
};
|
|
789
|
-
const CREDENTIAL_NAME_WORDS = Object.keys(CREDENTIAL_NAME_ANCHORS);
|
|
790
839
|
const CREDENTIAL_NAME_ALT = (() => {
|
|
791
|
-
for (const w of
|
|
840
|
+
for (const w of CREDENTIAL_PARAM_NAMES) {
|
|
792
841
|
if (!/^[a-z][a-z0-9_-]*$/.test(w))
|
|
793
842
|
throw new Error(`redact: credential name ${JSON.stringify(w)} must be lowercase [a-z0-9_-] (the alternation is built without escaping)`);
|
|
794
843
|
}
|
|
795
|
-
return [...
|
|
844
|
+
return [...CREDENTIAL_PARAM_NAMES].sort((a, b) => b.length - a.length || (a < b ? -1 : 1)).join("|");
|
|
796
845
|
})();
|
|
846
|
+
const CREDENTIAL_NAME_MAX = Math.max(...CREDENTIAL_PARAM_NAMES.map((w) => w.length));
|
|
847
|
+
const asciiLower = (s) => s.replace(/[A-Z]/g, (c) => c.toLowerCase());
|
|
848
|
+
function credentialNameAnchor(name) {
|
|
849
|
+
return CREDENTIAL_ANCHOR_OF.get(asciiLower(name));
|
|
850
|
+
}
|
|
851
|
+
const CREDENTIAL_ANCHOR_OF = new Map(Object.entries(CREDENTIAL_NAME_ANCHORS));
|
|
797
852
|
const STRUCTURAL_SECRET_PATTERNS = [
|
|
798
853
|
[/-----BEGIN(?:[^-](?:[^-](?:[^-]|-(?!-))*)?)?PRIVATE KEY(?: BLOCK)?-----[\s\S]{0,8192}?-----END(?:[^-](?:[^-](?:[^-]|-(?!-))*)?)?PRIVATE KEY(?: BLOCK)?-----/g, "«redacted:private-key»"],
|
|
799
854
|
[/---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----[\s\S]{0,8192}?---- END SSH2 ENCRYPTED PRIVATE KEY ----/g, "«redacted:private-key»"],
|
|
@@ -1029,14 +1084,17 @@ function isPemFenceLabel(s, from, to) {
|
|
|
1029
1084
|
return false;
|
|
1030
1085
|
if (!s.startsWith(PEM_KEY_WORD, end - PEM_KEY_WORD.length))
|
|
1031
1086
|
return false;
|
|
1087
|
+
return !pemLabelDashRuleBroken(s, from, to);
|
|
1088
|
+
}
|
|
1089
|
+
function pemLabelDashRuleBroken(s, from, to) {
|
|
1032
1090
|
if (s.charCodeAt(from) === 45)
|
|
1033
|
-
return
|
|
1091
|
+
return true;
|
|
1034
1092
|
if (s.charCodeAt(from + 1) === 45)
|
|
1035
|
-
return
|
|
1093
|
+
return true;
|
|
1036
1094
|
for (let i = from + 1; i < to; i++)
|
|
1037
1095
|
if (s.charCodeAt(i) === 45 && s.charCodeAt(i + 1) === 45)
|
|
1038
|
-
return
|
|
1039
|
-
return
|
|
1096
|
+
return true;
|
|
1097
|
+
return false;
|
|
1040
1098
|
}
|
|
1041
1099
|
const PEM_FENCE_OPEN = "-----BEGIN";
|
|
1042
1100
|
const PEM_FENCE_CLOSE = "-----";
|
|
@@ -1081,7 +1139,7 @@ function unitCountWithin(scan, from, to, max) {
|
|
|
1081
1139
|
}
|
|
1082
1140
|
return n <= max;
|
|
1083
1141
|
}
|
|
1084
|
-
function collectSsh2FenceSpans(scan, text, span) {
|
|
1142
|
+
function collectSsh2FenceSpans(scan, text, span, isHead) {
|
|
1085
1143
|
let cachedFrom = 0;
|
|
1086
1144
|
let cachedAt;
|
|
1087
1145
|
const nextClose = (from) => {
|
|
@@ -1107,6 +1165,10 @@ function collectSsh2FenceSpans(scan, text, span) {
|
|
|
1107
1165
|
continue;
|
|
1108
1166
|
}
|
|
1109
1167
|
const bodyFrom = fence + SSH2_FENCE_OPEN.length;
|
|
1168
|
+
if (isHead && unitCountWithin(scan, bodyFrom, text.length, SSH2_BODY_MAX)) {
|
|
1169
|
+
span(fence, text.length);
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1110
1172
|
const close = nextClose(bodyFrom);
|
|
1111
1173
|
if (close < 0)
|
|
1112
1174
|
return;
|
|
@@ -1121,11 +1183,20 @@ function collectSsh2FenceSpans(scan, text, span) {
|
|
|
1121
1183
|
}
|
|
1122
1184
|
const PEM_END_OPEN = "-----END";
|
|
1123
1185
|
const PEM_FENCE_BODY_MAX = 8192;
|
|
1186
|
+
const PEM_LINE_INVALID = -1;
|
|
1187
|
+
const PEM_LINE_OPEN = -2;
|
|
1124
1188
|
function pemFenceLineEnd(text, labelFrom) {
|
|
1125
1189
|
const close = text.indexOf(PEM_FENCE_CLOSE, labelFrom);
|
|
1126
|
-
|
|
1190
|
+
if (close < 0) {
|
|
1191
|
+
let to = text.length;
|
|
1192
|
+
while (to > labelFrom && text.charCodeAt(to - 1) === 45)
|
|
1193
|
+
to -= 1;
|
|
1194
|
+
const stillPossible = text.length - to >= 2 ? isPemFenceLabel(text, labelFrom, to) : !pemLabelDashRuleBroken(text, labelFrom, to);
|
|
1195
|
+
return stillPossible ? PEM_LINE_OPEN : PEM_LINE_INVALID;
|
|
1196
|
+
}
|
|
1197
|
+
return isPemFenceLabel(text, labelFrom, close) ? close + PEM_FENCE_CLOSE.length : PEM_LINE_INVALID;
|
|
1127
1198
|
}
|
|
1128
|
-
function collectPemFenceSpans(text, span) {
|
|
1199
|
+
function collectPemFenceSpans(text, span, isHead) {
|
|
1129
1200
|
let endFrom = -1;
|
|
1130
1201
|
let endAt = -1;
|
|
1131
1202
|
let endAfter = -1;
|
|
@@ -1145,13 +1216,17 @@ function collectPemFenceSpans(text, span) {
|
|
|
1145
1216
|
if (fence < 0)
|
|
1146
1217
|
return;
|
|
1147
1218
|
const bodyFrom = pemFenceLineEnd(text, fence + PEM_FENCE_OPEN.length);
|
|
1148
|
-
if (bodyFrom
|
|
1219
|
+
if (bodyFrom === PEM_LINE_INVALID) {
|
|
1149
1220
|
from = fence + 1;
|
|
1150
1221
|
continue;
|
|
1151
1222
|
}
|
|
1152
|
-
|
|
1153
|
-
|
|
1223
|
+
if (bodyFrom !== PEM_LINE_OPEN)
|
|
1224
|
+
earliestEndFence(bodyFrom);
|
|
1225
|
+
if (bodyFrom === PEM_LINE_OPEN || endAt < 0) {
|
|
1226
|
+
if (isHead)
|
|
1227
|
+
span(fence, text.length);
|
|
1154
1228
|
return;
|
|
1229
|
+
}
|
|
1155
1230
|
if (endAt - bodyFrom > PEM_FENCE_BODY_MAX) {
|
|
1156
1231
|
from = fence + 1;
|
|
1157
1232
|
continue;
|
|
@@ -1192,9 +1267,19 @@ function collectPemFragmentSpans(scan, text, json, span) {
|
|
|
1192
1267
|
cur = next;
|
|
1193
1268
|
}
|
|
1194
1269
|
}
|
|
1195
|
-
function collectHeadlessPpkSpans(scan, text, span) {
|
|
1270
|
+
function collectHeadlessPpkSpans(scan, text, span, isHead) {
|
|
1196
1271
|
const KEY = "Private-Lines: ";
|
|
1197
1272
|
const n = text.length;
|
|
1273
|
+
const LINE_NONE = -1;
|
|
1274
|
+
const LINE_OPEN = -2;
|
|
1275
|
+
const openAt = (i) => {
|
|
1276
|
+
if (!isHead)
|
|
1277
|
+
return false;
|
|
1278
|
+
let k = i;
|
|
1279
|
+
while (k < n && opaqueUnitEnd(scan, k) < 0 && text.charCodeAt(k) === 92)
|
|
1280
|
+
k += 1;
|
|
1281
|
+
return k >= n;
|
|
1282
|
+
};
|
|
1198
1283
|
const isB64 = (c) => (c >= 48 && c <= 57) || (c >= 65 && c <= 90) || (c >= 97 && c <= 122) || c === 43 || c === 47 || c === 61;
|
|
1199
1284
|
const b64At = (i) => opaqueUnitEnd(scan, i) < 0 && isB64(text.charCodeAt(i));
|
|
1200
1285
|
const skipHs = (i) => { while (i < n && opaqueUnitEnd(scan, i) < 0 && (text.charCodeAt(i) === 32 || text.charCodeAt(i) === 9))
|
|
@@ -1233,7 +1318,9 @@ function collectHeadlessPpkSpans(scan, text, span) {
|
|
|
1233
1318
|
seen = true;
|
|
1234
1319
|
q = skipHs(q);
|
|
1235
1320
|
}
|
|
1236
|
-
|
|
1321
|
+
if (openAt(q))
|
|
1322
|
+
return LINE_OPEN;
|
|
1323
|
+
return seen ? q : LINE_NONE;
|
|
1237
1324
|
};
|
|
1238
1325
|
const escapedNewlineLen = (i) => {
|
|
1239
1326
|
if (opaqueUnitEnd(scan, i) >= 0)
|
|
@@ -1248,13 +1335,35 @@ function collectHeadlessPpkSpans(scan, text, span) {
|
|
|
1248
1335
|
};
|
|
1249
1336
|
const atLineEnd = (i) => {
|
|
1250
1337
|
const b = skipHs(i);
|
|
1251
|
-
if (b >= n)
|
|
1338
|
+
if (b >= n || openAt(b))
|
|
1252
1339
|
return true;
|
|
1253
1340
|
if (opaqueUnitEnd(scan, b) >= 0)
|
|
1254
1341
|
return false;
|
|
1255
1342
|
const c = text.charCodeAt(b);
|
|
1256
1343
|
return c === 10 || c === 13 || c === 34 || escapedNewlineLen(b) > 0;
|
|
1257
1344
|
};
|
|
1345
|
+
const bodyLineAt = (from) => {
|
|
1346
|
+
const q0 = skipNewlines(from);
|
|
1347
|
+
if (q0 < 0)
|
|
1348
|
+
return q0;
|
|
1349
|
+
let q = q0;
|
|
1350
|
+
const mk = opaqueUnitEnd(scan, q) < 0 ? text.charCodeAt(q) : -1;
|
|
1351
|
+
if (mk === 43 || mk === 45)
|
|
1352
|
+
q = skipHs(q + 1);
|
|
1353
|
+
let r = q;
|
|
1354
|
+
while (r < n && b64At(r))
|
|
1355
|
+
r += 1;
|
|
1356
|
+
if (r - q < 4) {
|
|
1357
|
+
if (isHead && r >= n)
|
|
1358
|
+
return LINE_OPEN;
|
|
1359
|
+
r = q0;
|
|
1360
|
+
while (r < n && b64At(r))
|
|
1361
|
+
r += 1;
|
|
1362
|
+
if (r - q0 < 4)
|
|
1363
|
+
return LINE_NONE;
|
|
1364
|
+
}
|
|
1365
|
+
return atLineEnd(r) ? r : LINE_NONE;
|
|
1366
|
+
};
|
|
1258
1367
|
let search = 0;
|
|
1259
1368
|
for (;;) {
|
|
1260
1369
|
const at = text.indexOf(KEY, search);
|
|
@@ -1268,36 +1377,21 @@ function collectHeadlessPpkSpans(scan, text, span) {
|
|
|
1268
1377
|
const d0 = p;
|
|
1269
1378
|
while (p < n && opaqueUnitEnd(scan, p) < 0 && text.charCodeAt(p) >= 48 && text.charCodeAt(p) <= 57)
|
|
1270
1379
|
p += 1;
|
|
1271
|
-
if (p === d0) {
|
|
1380
|
+
if (p === d0 && p < n) {
|
|
1272
1381
|
search = at + KEY.length;
|
|
1273
1382
|
continue;
|
|
1274
1383
|
}
|
|
1275
|
-
let end =
|
|
1276
|
-
let
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
if (q0 === -1)
|
|
1384
|
+
let end = -1;
|
|
1385
|
+
for (let from = p;;) {
|
|
1386
|
+
const r = bodyLineAt(from);
|
|
1387
|
+
if (r === LINE_NONE)
|
|
1280
1388
|
break;
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
if (mk === 43 || mk === 45)
|
|
1284
|
-
q = skipHs(q + 1);
|
|
1285
|
-
let r = q;
|
|
1286
|
-
while (r < n && b64At(r))
|
|
1287
|
-
r += 1;
|
|
1288
|
-
if (r - q < 4) {
|
|
1289
|
-
r = q0;
|
|
1290
|
-
while (r < n && b64At(r))
|
|
1291
|
-
r += 1;
|
|
1292
|
-
if (r - q0 < 4)
|
|
1293
|
-
break;
|
|
1294
|
-
}
|
|
1295
|
-
if (!atLineEnd(r))
|
|
1389
|
+
end = r === LINE_OPEN ? n : r;
|
|
1390
|
+
if (r === LINE_OPEN)
|
|
1296
1391
|
break;
|
|
1297
|
-
|
|
1298
|
-
end = r;
|
|
1392
|
+
from = r;
|
|
1299
1393
|
}
|
|
1300
|
-
if (
|
|
1394
|
+
if (end < 0) {
|
|
1301
1395
|
search = p;
|
|
1302
1396
|
continue;
|
|
1303
1397
|
}
|
|
@@ -1386,9 +1480,7 @@ const isRegexSpace = (c) => c === 32 || (c >= 9 && c <= 13) || c === 0xa0 || c =
|
|
|
1386
1480
|
const isLineTerminator = (c) => c === 10 || c === 13 || c === 0x2028 || c === 0x2029;
|
|
1387
1481
|
const isControlCode = (c) => c < 0x20 || c === 0x7f;
|
|
1388
1482
|
const TOKEN_UNIT_Y = new RegExp(REDACTION_TOKEN_RE_SRC, "y");
|
|
1389
|
-
const
|
|
1390
|
-
const CREDENTIAL_NAME_SET = new Set(CREDENTIAL_NAME_WORDS);
|
|
1391
|
-
const CREDENTIAL_NAME_SCAN_MAX = Math.max(...CREDENTIAL_NAME_WORDS.map((w) => w.length)) * 3 + 1;
|
|
1483
|
+
const CREDENTIAL_NAME_SCAN_MAX = CREDENTIAL_NAME_MAX * 3 + 1;
|
|
1392
1484
|
function decodeAsciiName(name) {
|
|
1393
1485
|
let out = "";
|
|
1394
1486
|
for (let i = 0; i < name.length; i++) {
|
|
@@ -1409,9 +1501,6 @@ function decodeAsciiName(name) {
|
|
|
1409
1501
|
return out;
|
|
1410
1502
|
}
|
|
1411
1503
|
function credentialParamValueStart(text, p) {
|
|
1412
|
-
CREDENTIAL_PARAM_Y.lastIndex = p;
|
|
1413
|
-
if (CREDENTIAL_PARAM_Y.test(text))
|
|
1414
|
-
return CREDENTIAL_PARAM_Y.lastIndex;
|
|
1415
1504
|
const limit = Math.min(text.length, p + CREDENTIAL_NAME_SCAN_MAX);
|
|
1416
1505
|
let hasPct = false;
|
|
1417
1506
|
for (let i = p; i < limit; i++) {
|
|
@@ -1420,12 +1509,14 @@ function credentialParamValueStart(text, p) {
|
|
|
1420
1509
|
hasPct = true;
|
|
1421
1510
|
continue;
|
|
1422
1511
|
}
|
|
1423
|
-
if (c
|
|
1424
|
-
|
|
1425
|
-
|
|
1512
|
+
if (c === CH_EQ) {
|
|
1513
|
+
if (i === p)
|
|
1514
|
+
return -1;
|
|
1515
|
+
const name = hasPct ? decodeAsciiName(text.slice(p, i)) : text.slice(p, i);
|
|
1516
|
+
return name !== undefined && credentialNameAnchor(name) !== undefined ? i + 1 : -1;
|
|
1517
|
+
}
|
|
1518
|
+
if (!(isAsciiAlnumCode(c) || c === CH_UNDERSCORE || c === CH_MINUS))
|
|
1426
1519
|
return -1;
|
|
1427
|
-
const decoded = decodeAsciiName(text.slice(p, i));
|
|
1428
|
-
return decoded !== undefined && CREDENTIAL_NAME_SET.has(decoded.toLowerCase()) ? i + 1 : -1;
|
|
1429
1520
|
}
|
|
1430
1521
|
return -1;
|
|
1431
1522
|
}
|
|
@@ -1700,10 +1791,12 @@ function scanUrlRun(scan, text, i, kind, json) {
|
|
|
1700
1791
|
noteEvidenceRead(scan, i);
|
|
1701
1792
|
return i;
|
|
1702
1793
|
}
|
|
1703
|
-
function matchUserinfoAt(scan, text, p, json) {
|
|
1794
|
+
function matchUserinfoAt(scan, text, p, json, isHead) {
|
|
1704
1795
|
const probeEnd = scanUrlRun(scan, text, p, "plain-user", json);
|
|
1705
1796
|
const keyId = probeEnd > p && text.charCodeAt(probeEnd) === 58 && credentialSpansCover(scan, p, probeEnd);
|
|
1706
|
-
scanUrlRun(scan, text, p, keyId ? "token-pass" : "plain-pass", json);
|
|
1797
|
+
const runEnd = scanUrlRun(scan, text, p, keyId ? "token-pass" : "plain-pass", json);
|
|
1798
|
+
if (isHead && runEnd >= text.length && runEnd > p)
|
|
1799
|
+
return runEnd;
|
|
1707
1800
|
const at = scan.lastAt;
|
|
1708
1801
|
if (at <= p)
|
|
1709
1802
|
return null;
|
|
@@ -1721,7 +1814,7 @@ function growUrlSegments(list) {
|
|
|
1721
1814
|
list.a = bigger;
|
|
1722
1815
|
return true;
|
|
1723
1816
|
}
|
|
1724
|
-
function collectUrlCredentialSpans(scan, text, json, span) {
|
|
1817
|
+
function collectUrlCredentialSpans(scan, text, json, span, isHead) {
|
|
1725
1818
|
const dirty = scan.dirty;
|
|
1726
1819
|
const hr = scan.headsRead;
|
|
1727
1820
|
const hw = scan.headsWrite;
|
|
@@ -1757,7 +1850,7 @@ function collectUrlCredentialSpans(scan, text, json, span) {
|
|
|
1757
1850
|
else {
|
|
1758
1851
|
scan.footLo = FOOT_NONE;
|
|
1759
1852
|
scan.footHi = -1;
|
|
1760
|
-
at = matchUserinfoAt(scan, text, start, json) ?? -1;
|
|
1853
|
+
at = matchUserinfoAt(scan, text, start, json, isHead) ?? -1;
|
|
1761
1854
|
lo = scan.footLo;
|
|
1762
1855
|
hi = scan.footHi;
|
|
1763
1856
|
urlSegmentRuns += 1;
|
|
@@ -1834,24 +1927,19 @@ function collectUrlCredentialSpans(scan, text, json, span) {
|
|
|
1834
1927
|
scan.footHi = armHi;
|
|
1835
1928
|
}
|
|
1836
1929
|
const JSON_FIELD_ANCHOR = '"';
|
|
1837
|
-
const CREDENTIAL_NAME_MAX = Math.max(...CREDENTIAL_NAME_WORDS.map((w) => w.length));
|
|
1838
1930
|
function jsonSecretFieldValueQuoteAt(text, p) {
|
|
1839
1931
|
const n = text.length;
|
|
1840
|
-
let name = "";
|
|
1841
1932
|
let i = p + 1;
|
|
1842
1933
|
for (; i < n; i++) {
|
|
1843
|
-
|
|
1934
|
+
const c = text.charCodeAt(i);
|
|
1844
1935
|
if (c === CH_QUOTE)
|
|
1845
1936
|
break;
|
|
1846
1937
|
if (i - p > CREDENTIAL_NAME_MAX)
|
|
1847
1938
|
return -1;
|
|
1848
|
-
if (c
|
|
1849
|
-
c += 32;
|
|
1850
|
-
if (!((c >= CH_a && c <= CH_z) || (c >= CH_0 && c <= CH_9) || c === CH_UNDERSCORE || c === CH_MINUS))
|
|
1939
|
+
if (!(isAsciiAlnumCode(c) || c === CH_UNDERSCORE || c === CH_MINUS))
|
|
1851
1940
|
return -1;
|
|
1852
|
-
name += String.fromCharCode(c);
|
|
1853
1941
|
}
|
|
1854
|
-
if (i >= n ||
|
|
1942
|
+
if (i >= n || i === p + 1 || credentialNameAnchor(text.slice(p + 1, i)) === undefined)
|
|
1855
1943
|
return -1;
|
|
1856
1944
|
i += 1;
|
|
1857
1945
|
while (i < n && isRegexSpace(text.charCodeAt(i)))
|
|
@@ -1863,7 +1951,7 @@ function jsonSecretFieldValueQuoteAt(text, p) {
|
|
|
1863
1951
|
i += 1;
|
|
1864
1952
|
return text.charCodeAt(i) === CH_QUOTE ? i : -1;
|
|
1865
1953
|
}
|
|
1866
|
-
function jsonStringEndAt(text, q) {
|
|
1954
|
+
function jsonStringEndAt(text, q, isHead) {
|
|
1867
1955
|
const n = text.length;
|
|
1868
1956
|
for (let i = q + 1; i < n;) {
|
|
1869
1957
|
const c = text.charCodeAt(i);
|
|
@@ -1874,16 +1962,16 @@ function jsonStringEndAt(text, q) {
|
|
|
1874
1962
|
i += 2;
|
|
1875
1963
|
continue;
|
|
1876
1964
|
}
|
|
1877
|
-
return -1;
|
|
1965
|
+
return isHead && i + 1 >= n ? n : -1;
|
|
1878
1966
|
}
|
|
1879
1967
|
i += 1;
|
|
1880
1968
|
}
|
|
1881
|
-
return -1;
|
|
1969
|
+
return isHead ? n : -1;
|
|
1882
1970
|
}
|
|
1883
|
-
function collectJsonSecretFieldSpans(text, span) {
|
|
1971
|
+
function collectJsonSecretFieldSpans(text, span, isHead) {
|
|
1884
1972
|
for (let p = text.indexOf(JSON_FIELD_ANCHOR); p >= 0;) {
|
|
1885
1973
|
const q = jsonSecretFieldValueQuoteAt(text, p);
|
|
1886
|
-
const end = q < 0 ? -1 : jsonStringEndAt(text, q);
|
|
1974
|
+
const end = q < 0 ? -1 : jsonStringEndAt(text, q, isHead);
|
|
1887
1975
|
if (end < 0) {
|
|
1888
1976
|
p = text.indexOf(JSON_FIELD_ANCHOR, p + 1);
|
|
1889
1977
|
continue;
|
|
@@ -1896,7 +1984,6 @@ const STRONG_AUTH_SCHEMES = new Set(["basic", "bearer"]);
|
|
|
1896
1984
|
const STRONG_AUTH_SCHEME_MAX = Math.max(...[...STRONG_AUTH_SCHEMES].map((w) => w.length));
|
|
1897
1985
|
const ABSENT_OR_BOOLEAN_WORDS = new Set(["null", "nil", "none", "undefined", "true", "false", "yes", "no"]);
|
|
1898
1986
|
const ABSENT_OR_BOOLEAN_MAX = Math.max(...[...ABSENT_OR_BOOLEAN_WORDS].map((w) => w.length));
|
|
1899
|
-
const CREDENTIAL_ANCHOR_OF = new Map(Object.entries(CREDENTIAL_NAME_ANCHORS));
|
|
1900
1987
|
const CH_GRAVE = 96, CH_APOS = 39, CH_DOT = 46, CH_COMMA = 44, CH_SEMI = 59, CH_DOLLAR = 36;
|
|
1901
1988
|
const CH_LPAREN = 40, CH_RPAREN = 41, CH_RBRACKET = 93, CH_LBRACE = 123, CH_RBRACE = 125, CH_LT = 60, CH_GT = 62;
|
|
1902
1989
|
const CH_QMARK = 63, CH_AMP = 38, CH_HASH = 35;
|
|
@@ -2021,7 +2108,7 @@ function anchorHeadAt(text, op, json) {
|
|
|
2021
2108
|
return undefined;
|
|
2022
2109
|
before = j - openLen;
|
|
2023
2110
|
}
|
|
2024
|
-
const strength =
|
|
2111
|
+
const strength = credentialNameAnchor(text.slice(nameStart, nameEnd));
|
|
2025
2112
|
if (strength === undefined)
|
|
2026
2113
|
return undefined;
|
|
2027
2114
|
if (!afterEscape && runStart === j + 1 && quote === 0 && j >= 0 && text.charCodeAt(j) === CH_SLASH)
|
|
@@ -2037,7 +2124,7 @@ function anchorHeadAt(text, op, json) {
|
|
|
2037
2124
|
}
|
|
2038
2125
|
return { strength, quotedName: quote !== 0, spacedLeft, listSep };
|
|
2039
2126
|
}
|
|
2040
|
-
function quotedValueEnd(text, cs, quote, json) {
|
|
2127
|
+
function quotedValueEnd(text, cs, quote, json, isHead) {
|
|
2041
2128
|
const n = text.length;
|
|
2042
2129
|
let i = cs;
|
|
2043
2130
|
while (i < n) {
|
|
@@ -2046,18 +2133,18 @@ function quotedValueEnd(text, cs, quote, json) {
|
|
|
2046
2133
|
if (ch === quote)
|
|
2047
2134
|
return i;
|
|
2048
2135
|
if (ch === JSON_STRING_END)
|
|
2049
|
-
|
|
2136
|
+
return -1;
|
|
2050
2137
|
i += unitLenOf(unit);
|
|
2051
2138
|
if (ch === CH_BACKSLASH && quote !== JSON_STRING_END) {
|
|
2052
2139
|
if (i >= n)
|
|
2053
2140
|
break;
|
|
2054
2141
|
const escaped = readAnchorUnit(text, i, json);
|
|
2055
2142
|
if (unitChOf(escaped) === JSON_STRING_END)
|
|
2056
|
-
|
|
2143
|
+
return -1;
|
|
2057
2144
|
i += unitLenOf(escaped);
|
|
2058
2145
|
}
|
|
2059
2146
|
}
|
|
2060
|
-
return -1;
|
|
2147
|
+
return isHead ? n : -1;
|
|
2061
2148
|
}
|
|
2062
2149
|
function bareValueEnd(text, s, json, listSep) {
|
|
2063
2150
|
const n = text.length;
|
|
@@ -2102,7 +2189,7 @@ function bareValueEnd(text, s, json, listSep) {
|
|
|
2102
2189
|
}
|
|
2103
2190
|
return e;
|
|
2104
2191
|
}
|
|
2105
|
-
function literalValueAt(text, s, json, declaredIfBare, listSep) {
|
|
2192
|
+
function literalValueAt(text, s, json, declaredIfBare, listSep, isHead) {
|
|
2106
2193
|
const n = text.length;
|
|
2107
2194
|
if (s >= n)
|
|
2108
2195
|
return undefined;
|
|
@@ -2115,7 +2202,7 @@ function literalValueAt(text, s, json, declaredIfBare, listSep) {
|
|
|
2115
2202
|
return undefined;
|
|
2116
2203
|
if (!isAsciiAlnumCode(unitChOf(readAnchorUnit(text, vs, json))))
|
|
2117
2204
|
return undefined;
|
|
2118
|
-
const close = quotedValueEnd(text, vs, first, json);
|
|
2205
|
+
const close = quotedValueEnd(text, vs, first, json, isHead);
|
|
2119
2206
|
if (close >= 0)
|
|
2120
2207
|
return { start: vs, end: close, quoted: true };
|
|
2121
2208
|
}
|
|
@@ -2183,7 +2270,7 @@ function schemeValueAt(text, s, json) {
|
|
|
2183
2270
|
return undefined;
|
|
2184
2271
|
return { start: vs, end: e, quoted: false };
|
|
2185
2272
|
}
|
|
2186
|
-
function collectAnchoredValueSpans(text, json, span) {
|
|
2273
|
+
function collectAnchoredValueSpans(text, json, span, isHead) {
|
|
2187
2274
|
const n = text.length;
|
|
2188
2275
|
let resume = 0;
|
|
2189
2276
|
let nextEq = text.indexOf("=");
|
|
@@ -2224,10 +2311,10 @@ function collectAnchoredValueSpans(text, json, span) {
|
|
|
2224
2311
|
v = schemeValueAt(text, s, json);
|
|
2225
2312
|
break;
|
|
2226
2313
|
case "declarative":
|
|
2227
|
-
v = literalValueAt(text, s, json, head.quotedName || (!head.spacedLeft && !spacedRight), head.listSep);
|
|
2314
|
+
v = literalValueAt(text, s, json, head.quotedName || (!head.spacedLeft && !spacedRight), head.listSep, isHead);
|
|
2228
2315
|
break;
|
|
2229
2316
|
case "any-form":
|
|
2230
|
-
v = literalValueAt(text, s, json, true, head.listSep);
|
|
2317
|
+
v = literalValueAt(text, s, json, true, head.listSep, isHead);
|
|
2231
2318
|
break;
|
|
2232
2319
|
default: {
|
|
2233
2320
|
const unhandled = head.strength;
|
|
@@ -2243,7 +2330,7 @@ function collectAnchoredValueSpans(text, json, span) {
|
|
|
2243
2330
|
export function structuralScannerForTest(arm) {
|
|
2244
2331
|
const collect = (scan) => (text) => {
|
|
2245
2332
|
const out = [];
|
|
2246
|
-
scan(text, (start, end) => out.push([start, end]));
|
|
2333
|
+
scan(text, (start, end) => out.push([start, end]), false);
|
|
2247
2334
|
return out;
|
|
2248
2335
|
};
|
|
2249
2336
|
switch (arm) {
|
|
@@ -2256,7 +2343,7 @@ export function structuralScannerForTest(arm) {
|
|
|
2256
2343
|
let ppkScanBytes = 0;
|
|
2257
2344
|
export function ppkScanBytesForTest() { return ppkScanBytes; }
|
|
2258
2345
|
export function resetPpkScanBytesForTest() { ppkScanBytes = 0; }
|
|
2259
|
-
function collectPpkContainerSpans(scan, text,
|
|
2346
|
+
function collectPpkContainerSpans(scan, text, eat, span, isHead) {
|
|
2260
2347
|
const HEAD = "PuTTY-User-Key-File-";
|
|
2261
2348
|
const MAC = "Private-MAC: ";
|
|
2262
2349
|
const HASH = "Private-Hash: ";
|
|
@@ -2272,9 +2359,8 @@ function collectPpkContainerSpans(scan, text, record, span) {
|
|
|
2272
2359
|
cache.set(needle, v);
|
|
2273
2360
|
return v;
|
|
2274
2361
|
};
|
|
2275
|
-
const
|
|
2362
|
+
const versionEnd = (at) => {
|
|
2276
2363
|
let p = at + HEAD.length;
|
|
2277
|
-
const start = p;
|
|
2278
2364
|
while (p < text.length && opaqueUnitEnd(scan, p) < 0) {
|
|
2279
2365
|
const c = text.charCodeAt(p);
|
|
2280
2366
|
if (c >= 48 && c <= 57)
|
|
@@ -2282,7 +2368,15 @@ function collectPpkContainerSpans(scan, text, record, span) {
|
|
|
2282
2368
|
else
|
|
2283
2369
|
break;
|
|
2284
2370
|
}
|
|
2285
|
-
return p
|
|
2371
|
+
return p;
|
|
2372
|
+
};
|
|
2373
|
+
const isVersionedHead = (at) => {
|
|
2374
|
+
const p = versionEnd(at);
|
|
2375
|
+
return p > at + HEAD.length && text.startsWith(": ", p);
|
|
2376
|
+
};
|
|
2377
|
+
const isOpenHead = (at) => {
|
|
2378
|
+
const p = versionEnd(at);
|
|
2379
|
+
return p >= text.length || (p === text.length - 1 && p > at + HEAD.length && text.charCodeAt(p) === 58);
|
|
2286
2380
|
};
|
|
2287
2381
|
const nextVersionedHead = (from) => {
|
|
2288
2382
|
let p = find(HEAD, from);
|
|
@@ -2305,7 +2399,7 @@ function collectPpkContainerSpans(scan, text, record, span) {
|
|
|
2305
2399
|
while (at !== Number.POSITIVE_INFINITY) {
|
|
2306
2400
|
let pos = at + HEAD.length + 1;
|
|
2307
2401
|
let end = text.length;
|
|
2308
|
-
let ateToEnd =
|
|
2402
|
+
let ateToEnd = !isHead;
|
|
2309
2403
|
for (;;) {
|
|
2310
2404
|
const mac = find(MAC, pos);
|
|
2311
2405
|
const hash = find(HASH, pos);
|
|
@@ -2338,15 +2432,21 @@ function collectPpkContainerSpans(scan, text, record, span) {
|
|
|
2338
2432
|
}
|
|
2339
2433
|
}
|
|
2340
2434
|
}
|
|
2435
|
+
const undecided = isHead && limit === Number.POSITIVE_INFINITY;
|
|
2341
2436
|
ateToEnd = straggler < limit || !gapBlank;
|
|
2342
|
-
end = ateToEnd ? text.length : hexEnd;
|
|
2437
|
+
end = ateToEnd || undecided ? text.length : hexEnd;
|
|
2343
2438
|
break;
|
|
2344
2439
|
}
|
|
2345
|
-
if (ateToEnd &&
|
|
2346
|
-
|
|
2440
|
+
if (ateToEnd && eat !== undefined && eat.from < 0) {
|
|
2441
|
+
eat.from = at;
|
|
2442
|
+
eat.len = text.length;
|
|
2443
|
+
}
|
|
2347
2444
|
span(at, end);
|
|
2348
2445
|
at = end >= text.length ? Number.POSITIVE_INFINITY : nextVersionedHead(end);
|
|
2349
2446
|
}
|
|
2447
|
+
const last = isHead ? text.lastIndexOf(HEAD) : -1;
|
|
2448
|
+
if (last >= 0 && !inOpaqueUnit(scan, last) && isOpenHead(last))
|
|
2449
|
+
span(last, text.length);
|
|
2350
2450
|
}
|
|
2351
2451
|
const armPool = (() => {
|
|
2352
2452
|
const spanRepl = (token) => {
|
|
@@ -2376,8 +2476,8 @@ const armPool = (() => {
|
|
|
2376
2476
|
phase: 1,
|
|
2377
2477
|
lexical: LEXICAL_KEYWORD_ARMS.has(re),
|
|
2378
2478
|
collect: boundary === undefined
|
|
2379
|
-
? (text, _json,
|
|
2380
|
-
: (text, _json,
|
|
2479
|
+
? (text, _json, _eat, out) => collectRegexSpans(arm, text, out)
|
|
2480
|
+
: (text, _json, _eat, out) => collectValueArmSpans(boundary, text, out),
|
|
2381
2481
|
retry: boundary === undefined ? undefined : (text, at, out) => collectStickySpans(boundary, text, at, out),
|
|
2382
2482
|
headSrc: boundary === undefined ? undefined : headSrc,
|
|
2383
2483
|
headFirst: boundary === undefined ? undefined : headFirst,
|
|
@@ -2391,7 +2491,7 @@ const armPool = (() => {
|
|
|
2391
2491
|
order,
|
|
2392
2492
|
phase: 1,
|
|
2393
2493
|
lexical,
|
|
2394
|
-
collect: (text, json,
|
|
2494
|
+
collect: (text, json, eat, out, isHead) => arm(text, json, eat, (start, end) => out.push({ start, end, repl, rank, order }), isHead),
|
|
2395
2495
|
retry: undefined,
|
|
2396
2496
|
headSrc: undefined,
|
|
2397
2497
|
headFirst: undefined,
|
|
@@ -2406,7 +2506,7 @@ const armPool = (() => {
|
|
|
2406
2506
|
order,
|
|
2407
2507
|
phase: 2,
|
|
2408
2508
|
lexical: false,
|
|
2409
|
-
collect: (scan, text, json,
|
|
2509
|
+
collect: (scan, text, json, eat, out, isHead) => arm(scan, text, json, eat, (start, end) => out.push({ start, end, repl, rank, order }), isHead),
|
|
2410
2510
|
retry: undefined,
|
|
2411
2511
|
headSrc: undefined,
|
|
2412
2512
|
headFirst: undefined,
|
|
@@ -2414,22 +2514,22 @@ const armPool = (() => {
|
|
|
2414
2514
|
};
|
|
2415
2515
|
const structuralScannerMember = (row, order) => {
|
|
2416
2516
|
if (row === PEM_FENCE_PATTERN)
|
|
2417
|
-
return scannerMember(row[1], order, (text, _json,
|
|
2517
|
+
return scannerMember(row[1], order, (text, _json, _eat, span, isHead) => collectPemFenceSpans(text, span, isHead));
|
|
2418
2518
|
if (row === SSH2_FENCE_PATTERN)
|
|
2419
|
-
return forensicMember(row[1], order, (scan, text, _json,
|
|
2519
|
+
return forensicMember(row[1], order, (scan, text, _json, _eat, span, isHead) => collectSsh2FenceSpans(scan, text, span, isHead));
|
|
2420
2520
|
if (row === URL_CREDENTIAL_PATTERN)
|
|
2421
|
-
return forensicMember(row[1], order, (scan, text, json,
|
|
2521
|
+
return forensicMember(row[1], order, (scan, text, json, _eat, span, isHead) => collectUrlCredentialSpans(scan, text, json, span, isHead));
|
|
2422
2522
|
if (row === JSON_SECRET_FIELD_PATTERN)
|
|
2423
|
-
return scannerMember(row[1], order, (text, _json,
|
|
2523
|
+
return scannerMember(row[1], order, (text, _json, _eat, span, isHead) => collectJsonSecretFieldSpans(text, span, isHead));
|
|
2424
2524
|
throw new Error(`redact: structural row /${row[0].source}/ has no hand-written scanner — structural grammars are declared as regexes but never executed as one (S-102 / S-265)`);
|
|
2425
2525
|
};
|
|
2426
2526
|
const members = [];
|
|
2427
2527
|
for (const row of STRUCTURAL_SECRET_PATTERNS)
|
|
2428
2528
|
members.push(structuralScannerMember(row, members.length));
|
|
2429
|
-
members.push(forensicMember(PPK_CONTAINER_TOKEN, members.length, (scan, text, _json,
|
|
2430
|
-
members.push(forensicMember(PEM_FRAGMENT_TOKEN, members.length, (scan, text, json,
|
|
2431
|
-
members.push(forensicMember(HEADLESS_PPK_TOKEN, members.length, (scan, text, _json,
|
|
2432
|
-
members.push(scannerMember(ANCHORED_VALUE_TOKEN, members.length, (text, json,
|
|
2529
|
+
members.push(forensicMember(PPK_CONTAINER_TOKEN, members.length, (scan, text, _json, eat, span, isHead) => collectPpkContainerSpans(scan, text, eat, span, isHead)));
|
|
2530
|
+
members.push(forensicMember(PEM_FRAGMENT_TOKEN, members.length, (scan, text, json, _eat, span) => collectPemFragmentSpans(scan, text, json, span)));
|
|
2531
|
+
members.push(forensicMember(HEADLESS_PPK_TOKEN, members.length, (scan, text, _json, _eat, span, isHead) => collectHeadlessPpkSpans(scan, text, span, isHead)));
|
|
2532
|
+
members.push(scannerMember(ANCHORED_VALUE_TOKEN, members.length, (text, json, _eat, span, isHead) => collectAnchoredValueSpans(text, json, span, isHead), ARM_RANK.keyword, true));
|
|
2433
2533
|
for (const row of KEYWORD_SECRET_PATTERNS)
|
|
2434
2534
|
members.push(regexMember(row, ARM_RANK.keyword, members.length));
|
|
2435
2535
|
for (const row of SHAPE_SECRET_PATTERNS)
|
|
@@ -2460,7 +2560,8 @@ const armPool = (() => {
|
|
|
2460
2560
|
const headFirstUnit = unionMembers(retryMembers.map((m) => m.headFirst)) ?? new Uint32Array(0x10000 >>> 5).fill(0xffffffff);
|
|
2461
2561
|
poolArmCount = members.length;
|
|
2462
2562
|
poolBoundaryArmCount = retryMembers.length;
|
|
2463
|
-
return (text, wantCount, json,
|
|
2563
|
+
return (text, wantCount, json, eat, scope, isHead) => {
|
|
2564
|
+
readings += 1;
|
|
2464
2565
|
const lane = LANES[scope];
|
|
2465
2566
|
const spans = [];
|
|
2466
2567
|
let tried;
|
|
@@ -2496,7 +2597,7 @@ const armPool = (() => {
|
|
|
2496
2597
|
}
|
|
2497
2598
|
};
|
|
2498
2599
|
for (const m of lane.phase1)
|
|
2499
|
-
m.collect(text, json,
|
|
2600
|
+
m.collect(text, json, eat, spans, isHead);
|
|
2500
2601
|
closeCoveragePositions(0);
|
|
2501
2602
|
if (lane.phase2.length > 0) {
|
|
2502
2603
|
const scan = buildForensicScan(credentialSpans(text), lane.phase2.length);
|
|
@@ -2513,7 +2614,7 @@ const armPool = (() => {
|
|
|
2513
2614
|
}
|
|
2514
2615
|
scan.footLo = FOOT_NONE;
|
|
2515
2616
|
scan.footHi = -1;
|
|
2516
|
-
lane.phase2[j].collect(scan, text, json,
|
|
2617
|
+
lane.phase2[j].collect(scan, text, json, level === 0 ? eat : undefined, spans, isHead);
|
|
2517
2618
|
foot[2 * j] = scan.footLo;
|
|
2518
2619
|
foot[2 * j + 1] = scan.footHi;
|
|
2519
2620
|
forensicRuns += 1;
|
|
@@ -2559,8 +2660,8 @@ let onRedaction;
|
|
|
2559
2660
|
export function setRedactionObserver(fn) {
|
|
2560
2661
|
onRedaction = fn;
|
|
2561
2662
|
}
|
|
2562
|
-
function applyRules(text, wantCount, json,
|
|
2563
|
-
return armPool(text, wantCount, json,
|
|
2663
|
+
function applyRules(text, wantCount, json, eat, scope, isHead) {
|
|
2664
|
+
return armPool(text, wantCount, json, eat, scope, isHead);
|
|
2564
2665
|
}
|
|
2565
2666
|
function reportHits(hits) {
|
|
2566
2667
|
if (onRedaction === undefined)
|
|
@@ -2573,24 +2674,151 @@ function reportHits(hits) {
|
|
|
2573
2674
|
}
|
|
2574
2675
|
}
|
|
2575
2676
|
}
|
|
2576
|
-
function
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2677
|
+
function invisibleClassesOf(layout) {
|
|
2678
|
+
switch (layout) {
|
|
2679
|
+
case "multi-line":
|
|
2680
|
+
return SPELLED_FORMAT | SPELLED_CONTROL | RAW_CONTROL;
|
|
2681
|
+
case "single-line":
|
|
2682
|
+
return SPELLED_FORMAT | SPELLED_CONTROL | RAW_CONTROL | RAW_WHITESPACE;
|
|
2683
|
+
default: {
|
|
2684
|
+
const unhandled = layout;
|
|
2685
|
+
throw new Error(`redact: unhandled layout ${String(unhandled)}`);
|
|
2686
|
+
}
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
function trailingPartialEscapeStart(s) {
|
|
2690
|
+
const n = s.length;
|
|
2691
|
+
const runStart = (end) => {
|
|
2692
|
+
let k = end;
|
|
2693
|
+
while (k > 0 && s.charCodeAt(k - 1) === CH_BACKSLASH)
|
|
2694
|
+
k -= 1;
|
|
2695
|
+
return k;
|
|
2696
|
+
};
|
|
2697
|
+
const highSurrogateEscapeStartBefore = (end) => {
|
|
2698
|
+
let j = end;
|
|
2699
|
+
let value = -1;
|
|
2700
|
+
let bodyStart = -1;
|
|
2701
|
+
if (j >= 1 && s.charCodeAt(j - 1) === CH_RBRACE) {
|
|
2702
|
+
let k = j - 1;
|
|
2703
|
+
while (k > 0 && hexDigitValue(s.charCodeAt(k - 1)) >= 0)
|
|
2704
|
+
k -= 1;
|
|
2705
|
+
if (k >= 2 && s.charCodeAt(k - 1) === CH_LBRACE && s.charCodeAt(k - 2) === CH_u && j - 1 - k >= 1) {
|
|
2706
|
+
value = readHexRunValue(s, k, j - 1);
|
|
2707
|
+
bodyStart = k - 2;
|
|
2708
|
+
}
|
|
2709
|
+
}
|
|
2710
|
+
else if (j >= 5 && s.charCodeAt(j - 5) === CH_u) {
|
|
2711
|
+
value = readHexRun(s, j - 4, 4);
|
|
2712
|
+
bodyStart = j - 5;
|
|
2713
|
+
}
|
|
2714
|
+
if (value < 0xd800 || value > 0xdbff)
|
|
2715
|
+
return -1;
|
|
2716
|
+
const k = runStart(bodyStart);
|
|
2717
|
+
return k < bodyStart ? k : -1;
|
|
2718
|
+
};
|
|
2719
|
+
let j = n;
|
|
2720
|
+
while (j > 0 && hexDigitValue(s.charCodeAt(j - 1)) >= 0)
|
|
2721
|
+
j -= 1;
|
|
2722
|
+
const hexRun = n - j;
|
|
2723
|
+
let element = -1;
|
|
2724
|
+
if (j >= 2 && s.charCodeAt(j - 1) === CH_LBRACE && s.charCodeAt(j - 2) === CH_u)
|
|
2725
|
+
element = j - 2;
|
|
2726
|
+
else if (j >= 1 && s.charCodeAt(j - 1) === CH_u && hexRun <= 3)
|
|
2727
|
+
element = j - 1;
|
|
2728
|
+
else if (j >= 1 && s.charCodeAt(j - 1) === CH_x && hexRun <= 1)
|
|
2729
|
+
element = j - 1;
|
|
2730
|
+
else if (hexRun === 0 && n >= 1 && s.charCodeAt(n - 1) === CH_BACKSLASH)
|
|
2731
|
+
element = n;
|
|
2732
|
+
if (element >= 0) {
|
|
2733
|
+
const k = runStart(element);
|
|
2734
|
+
if (k >= element)
|
|
2735
|
+
return -1;
|
|
2736
|
+
const high = highSurrogateEscapeStartBefore(k);
|
|
2737
|
+
return high >= 0 ? high : k;
|
|
2738
|
+
}
|
|
2739
|
+
return highSurrogateEscapeStartBefore(n);
|
|
2740
|
+
}
|
|
2741
|
+
function readHexRunValue(s, from, to) {
|
|
2742
|
+
let v = 0;
|
|
2743
|
+
for (let k = from; k < to; k++) {
|
|
2744
|
+
const d = hexDigitValue(s.charCodeAt(k));
|
|
2745
|
+
if (d < 0)
|
|
2746
|
+
return -1;
|
|
2747
|
+
v = v * 16 + d;
|
|
2748
|
+
if (v > 0x10ffff)
|
|
2749
|
+
return -1;
|
|
2750
|
+
}
|
|
2751
|
+
return v;
|
|
2752
|
+
}
|
|
2753
|
+
function shortestReading(text, layout) {
|
|
2754
|
+
const raw = collectRawControlCuts(text, invisibleClassesOf(layout));
|
|
2755
|
+
const normalized = normalizeForRedaction(deleteInvisibleCharacters(text, raw, raw.present).text);
|
|
2756
|
+
const open = trailingPartialEscapeStart(normalized);
|
|
2757
|
+
const spelled = collectSpelledCuts(normalized);
|
|
2758
|
+
const length = deleteInvisibleCharacters(normalized, spelled, spelled.present).text.length;
|
|
2759
|
+
return open < 0 ? { visible: length, partial: false } : { visible: length - (normalized.length - open), partial: true };
|
|
2760
|
+
}
|
|
2761
|
+
export function readingHeadEnd(text, layout, units, from = 0) {
|
|
2762
|
+
const rest = text.length - from;
|
|
2763
|
+
let len = Math.min(rest, units);
|
|
2764
|
+
let first = true;
|
|
2765
|
+
let grow = 64;
|
|
2766
|
+
while (len < rest) {
|
|
2767
|
+
const { visible, partial } = shortestReading(text.slice(from, from + len), layout);
|
|
2768
|
+
if (visible >= units) {
|
|
2769
|
+
if (!partial)
|
|
2770
|
+
return from + len;
|
|
2771
|
+
len = Math.min(rest, len + grow);
|
|
2772
|
+
grow *= 2;
|
|
2773
|
+
continue;
|
|
2774
|
+
}
|
|
2775
|
+
const step = first && visible * 2 >= len ? Math.ceil((units - visible) / (visible / len)) + 1 : Math.max(units - visible, len);
|
|
2776
|
+
first = false;
|
|
2777
|
+
len = Math.min(rest, len + step);
|
|
2778
|
+
}
|
|
2779
|
+
return text.length;
|
|
2780
|
+
}
|
|
2781
|
+
function runRedaction(text, observe, json, wantHits, scope, layout, extent) {
|
|
2782
|
+
const wantCount = wantHits || (onRedaction !== undefined && observe);
|
|
2783
|
+
const eat = observe ? { from: -1, len: 0 } : undefined;
|
|
2784
|
+
let spans = [];
|
|
2785
|
+
let hits = NO_HITS;
|
|
2786
|
+
let readsSoFar = 0;
|
|
2787
|
+
let unioned = false;
|
|
2788
|
+
const read = (layers, view) => {
|
|
2789
|
+
const r = applyRules(view, wantCount, json, eat, scope, extent === "head");
|
|
2586
2790
|
forgetEscapedSeparatorTails();
|
|
2587
|
-
|
|
2588
|
-
if (
|
|
2589
|
-
spans =
|
|
2590
|
-
hits =
|
|
2791
|
+
readsSoFar += 1;
|
|
2792
|
+
if (readsSoFar === 1) {
|
|
2793
|
+
spans = spansInOriginal(layers, r.kept);
|
|
2794
|
+
hits = r.hits;
|
|
2795
|
+
return;
|
|
2591
2796
|
}
|
|
2797
|
+
const extra = spansInOriginal(layers, r.kept);
|
|
2798
|
+
if (extra.length === 0)
|
|
2799
|
+
return;
|
|
2800
|
+
spans = resolveSpanOverlaps([...spans, ...extra]);
|
|
2801
|
+
unioned = true;
|
|
2802
|
+
};
|
|
2803
|
+
const raw = collectRawControlCuts(text, invisibleClassesOf(layout));
|
|
2804
|
+
for (let rmask = 0;; rmask = (rmask - raw.present) & raw.present) {
|
|
2805
|
+
const rfold = deleteInvisibleCharacters(text, raw, rmask);
|
|
2806
|
+
const normalized = normalizeForRedaction(rfold.text);
|
|
2807
|
+
const spelled = collectSpelledCuts(normalized);
|
|
2808
|
+
for (let smask = 0;; smask = (smask - spelled.present) & spelled.present) {
|
|
2809
|
+
const sfold = deleteInvisibleCharacters(normalized, spelled, smask);
|
|
2810
|
+
read([{ fold: sfold }, { input: rfold.text, view: normalized }, { fold: rfold }], sfold.text);
|
|
2811
|
+
if (smask === spelled.present)
|
|
2812
|
+
break;
|
|
2813
|
+
}
|
|
2814
|
+
if (rmask === raw.present)
|
|
2815
|
+
break;
|
|
2592
2816
|
}
|
|
2593
|
-
if (
|
|
2817
|
+
if (unioned && wantCount)
|
|
2818
|
+
hits = hitsOfSpans(spans);
|
|
2819
|
+
if (eat !== undefined && eat.from >= 0)
|
|
2820
|
+
recordFailOpen("server.redact.ppk-eat-to-end", `from=${eat.from} len=${eat.len}`);
|
|
2821
|
+
if (observe)
|
|
2594
2822
|
reportHits(hits);
|
|
2595
2823
|
return { text: applySpans(text, spans).out, hits, spans };
|
|
2596
2824
|
}
|
|
@@ -2608,28 +2836,41 @@ function hitsOfSpans(spans) {
|
|
|
2608
2836
|
}
|
|
2609
2837
|
return [...by.values()].map(({ token, arm, count }) => ({ label: labelOfToken(token), count, arm }));
|
|
2610
2838
|
}
|
|
2611
|
-
function spansInOriginal(
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2839
|
+
function spansInOriginal(layers, kept) {
|
|
2840
|
+
let out = kept;
|
|
2841
|
+
for (const layer of layers) {
|
|
2842
|
+
if (out.length === 0)
|
|
2843
|
+
return out;
|
|
2844
|
+
let at;
|
|
2845
|
+
if ("fold" in layer) {
|
|
2846
|
+
const fold = layer.fold;
|
|
2847
|
+
if (fold.at === undefined)
|
|
2848
|
+
continue;
|
|
2849
|
+
at = (v) => viewIndexInInput(fold, v);
|
|
2850
|
+
}
|
|
2851
|
+
else {
|
|
2852
|
+
if (layer.view === layer.input)
|
|
2853
|
+
continue;
|
|
2854
|
+
const map = mapNormalizedToOriginal(layer.input, layer.view);
|
|
2855
|
+
at = (v) => map[v];
|
|
2856
|
+
}
|
|
2857
|
+
out = out.map((s) => ({ ...s, start: at(s.start), end: at(s.end - 1) + 1 }));
|
|
2858
|
+
}
|
|
2859
|
+
return out;
|
|
2619
2860
|
}
|
|
2620
2861
|
export function redactSecrets(text, opts) {
|
|
2621
|
-
return runRedaction(text, opts?.observe ?? true, opts?.json === true, false, "free-text").text;
|
|
2862
|
+
return runRedaction(text, opts?.observe ?? true, opts?.json === true, false, "free-text", "multi-line", "whole").text;
|
|
2622
2863
|
}
|
|
2623
2864
|
export function redactSecretsWithArms(text, opts) {
|
|
2624
|
-
const r = runRedaction(text, opts?.observe ?? true, opts?.json === true, true, "free-text");
|
|
2865
|
+
const r = runRedaction(text, opts?.observe ?? true, opts?.json === true, true, "free-text", "multi-line", "whole");
|
|
2625
2866
|
return { text: r.text, arms: new Set(r.hits.map((h) => h.arm)) };
|
|
2626
2867
|
}
|
|
2627
2868
|
export function redactionSpansForTest(text, opts) {
|
|
2628
|
-
const r = runRedaction(text, false, opts?.json === true, false, "free-text");
|
|
2869
|
+
const r = runRedaction(text, false, opts?.json === true, false, "free-text", "multi-line", "whole");
|
|
2629
2870
|
return { text: r.text, spans: r.spans.map((sp) => ({ start: sp.start, end: sp.end })) };
|
|
2630
2871
|
}
|
|
2631
|
-
export function proposeRedactionSpans(text, scope,
|
|
2632
|
-
return runRedaction(text, true, false, false, scope,
|
|
2872
|
+
export function proposeRedactionSpans(text, scope, layout, extent) {
|
|
2873
|
+
return runRedaction(text, true, false, false, scope, layout, extent).spans.map((sp) => ({ start: sp.start, end: sp.end, repl: sp.repl }));
|
|
2633
2874
|
}
|
|
2634
2875
|
const REDACT_MAX_DEPTH = 64;
|
|
2635
2876
|
export function redactDeep(value) {
|
|
@@ -2731,7 +2972,7 @@ function unitCarriesCredential(unit) {
|
|
|
2731
2972
|
for (const v of armValueClassViews())
|
|
2732
2973
|
views.add(boundedUnitView(spelling, v.inClass, v.filler));
|
|
2733
2974
|
views.delete("");
|
|
2734
|
-
const hit = [...views].some((view) => runRedaction(view, true, false, false, "bounded-unit").text !== view);
|
|
2975
|
+
const hit = [...views].some((view) => runRedaction(view, true, false, false, "bounded-unit", "multi-line", "whole").text !== view);
|
|
2735
2976
|
return { hit, unreadable: decoded.residue };
|
|
2736
2977
|
}
|
|
2737
2978
|
function displaySafePathname(pathname) {
|
|
@@ -2761,7 +3002,7 @@ function shapeLawCredentialInQueryOrFragment(canonical) {
|
|
|
2761
3002
|
const boundary = canonical.indexOf("?");
|
|
2762
3003
|
if (boundary < 0)
|
|
2763
3004
|
return false;
|
|
2764
|
-
if (runRedaction(canonical, false, false, false, "free-text").spans.some((sp) => sp.end > boundary))
|
|
3005
|
+
if (runRedaction(canonical, false, false, false, "free-text", "multi-line", "whole").spans.some((sp) => sp.end > boundary))
|
|
2765
3006
|
return true;
|
|
2766
3007
|
for (const unit of canonical.slice(boundary + 1).split("&").flatMap((sg) => {
|
|
2767
3008
|
const eq = sg.indexOf("=");
|