@sema-agent/client-core 0.93.1 → 0.95.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/CHANGELOG.md +554 -0
- package/README.md +89 -55
- package/dist/adapt/arms.js +13 -11
- package/dist/adapt/panelTasks.js +4 -10
- package/dist/adapt/toolCards.js +2 -2
- package/dist/adapt/wireShapes.js +3 -8
- package/dist/adapter/activeRunSelfHeal.d.ts +8 -3
- package/dist/adapter/activeRunSelfHeal.js +20 -12
- package/dist/adapter/downstream/eventToSdkMessage.js +24 -17
- package/dist/adapter/downstream/terminalToSdkResult.js +13 -6
- package/dist/adapter/runStream.js +2 -1
- package/dist/adapter/types.d.ts +7 -0
- package/dist/adapter/types.js +15 -0
- package/dist/agentSession/backgroundView.js +5 -1
- package/dist/agentSession/engineAgentRegistryRead.js +2 -1
- package/dist/agentSession/engineSessionBackgroundStop.js +5 -3
- package/dist/agentsWireCaps.d.ts +17 -0
- package/dist/agentsWireCaps.js +111 -1
- package/dist/approvalDecidedByCapability.d.ts +0 -1
- package/dist/approvalDecidedByCapability.js +2 -7
- package/dist/approvalReachWire.d.ts +18 -0
- package/dist/approvalReachWire.js +58 -0
- package/dist/approvalsStreamLiveCapability.d.ts +0 -1
- package/dist/approvalsStreamLiveCapability.js +15 -14
- package/dist/atMostOnce.d.ts +8 -0
- package/dist/atMostOnce.js +36 -0
- package/dist/attachmentSeatCapability.d.ts +0 -1
- package/dist/attachmentSeatCapability.js +0 -3
- package/dist/attachmentsWireCaps.js +11 -6
- package/dist/bashExitReading.d.ts +10 -0
- package/dist/bashExitReading.js +12 -0
- package/dist/callerCwdCapability.d.ts +15 -0
- package/dist/callerCwdCapability.js +42 -0
- package/dist/centerWiringCapability.d.ts +1 -3
- package/dist/centerWiringCapability.js +18 -21
- package/dist/classifierStatus.js +4 -4
- package/dist/cloudConfigWireCaps.js +43 -21
- package/dist/compensations.js +1 -1
- package/dist/controlRouter.js +3 -10
- package/dist/coreValuePorts.d.ts +64 -1
- package/dist/coreValuePorts.js +30 -0
- package/dist/cycleOrder.d.ts +15 -0
- package/dist/cycleOrder.js +45 -0
- package/dist/decideFailureNote.js +4 -1
- package/dist/decideReceipt.d.ts +2 -1
- package/dist/decideReceipt.js +41 -13
- package/dist/declared/supportFloorDeclared.d.ts +1 -0
- package/dist/declared/supportFloorDeclared.js +5 -0
- package/dist/detachWire.d.ts +1 -4
- package/dist/detachWire.js +1 -1
- package/dist/deviceExecutorManagementCapability.d.ts +0 -1
- package/dist/deviceExecutorManagementCapability.js +36 -40
- package/dist/deviceFlowPolling.d.ts +5 -0
- package/dist/deviceFlowPolling.js +28 -0
- package/dist/deviceRebind.d.ts +88 -0
- package/dist/deviceRebind.js +242 -0
- package/dist/displayUntrusted.d.ts +1 -0
- package/dist/displayUntrusted.js +963 -30
- package/dist/engineAgentAbsence.d.ts +2 -2
- package/dist/engineAgentPanelStore.d.ts +8 -18
- package/dist/engineAgentPanelStore.js +19 -537
- package/dist/engineCapReader.d.ts +6 -6
- package/dist/engineCapReader.js +30 -43
- package/dist/engineCapsCache.d.ts +7 -2
- package/dist/engineCapsCache.js +64 -26
- package/dist/engineCredentialRequirement.d.ts +9 -0
- package/dist/engineCredentialRequirement.js +23 -0
- package/dist/engineEnvSourcing.d.ts +53 -0
- package/dist/engineEnvSourcing.js +81 -0
- package/dist/engineErrorCodes.d.ts +19 -4
- package/dist/engineErrorCodes.js +39 -21
- package/dist/engineIdentity.js +2 -0
- package/dist/engineNoticeCodes.d.ts +22 -2
- package/dist/engineNoticeCodes.js +73 -6
- package/dist/engineRefusedToolName.d.ts +1 -0
- package/dist/engineRefusedToolName.js +8 -0
- package/dist/engineWireSdk.js +2 -2
- package/dist/executionLaneCapability.d.ts +2 -3
- package/dist/executionLaneCapability.js +28 -28
- package/dist/fileHistoryCaptureCapability.d.ts +0 -1
- package/dist/fileHistoryCaptureCapability.js +13 -12
- package/dist/fileHistoryLegNotice.d.ts +14 -2
- package/dist/fileHistoryLegNotice.js +101 -15
- package/dist/fleet/fleetLedger.d.ts +2 -0
- package/dist/fleet/fleetLedger.js +74 -52
- package/dist/fleet/fleetProjection.d.ts +0 -3
- package/dist/fleet/fleetProjection.js +9 -16
- package/dist/fleetAgentPanelProjection.d.ts +4 -17
- package/dist/fleetAgentPanelProjection.js +7 -197
- package/dist/fleetAgentRowLike.d.ts +16 -0
- package/dist/fleetAgentRowLike.js +1 -0
- package/dist/gateOutcome.d.ts +2 -1
- package/dist/gateOutcome.js +33 -18
- package/dist/gateVocabulary.js +1 -1
- package/dist/generated/engineAskFaceTables.d.ts +3 -0
- package/dist/generated/engineAskFaceTables.js +12 -0
- package/dist/generated/engineFactTables.d.ts +4 -2
- package/dist/generated/engineFactTables.js +13 -0
- package/dist/generated/engineNoticeTables.d.ts +5 -0
- package/dist/generated/engineNoticeTables.js +7 -0
- package/dist/generated/sdkFactTables.d.ts +5 -0
- package/dist/generated/sdkFactTables.js +34 -0
- package/dist/generated/settingsSchemaFns.d.ts +10 -0
- package/dist/generated/settingsSchemaFns.js +22 -0
- package/dist/generated/settingsSchemaTables.d.ts +3 -0
- package/dist/generated/settingsSchemaTables.js +3 -0
- package/dist/headlessPermissionModeWire.d.ts +2 -2
- package/dist/headlessPermissionModeWire.js +11 -21
- package/dist/headlessReconnectWire.js +49 -20
- package/dist/hitl/allowRuleShadow.d.ts +1 -1
- package/dist/hitl/allowRuleShadow.js +49 -8
- package/dist/hitl/approvalCompleteParked.d.ts +1 -0
- package/dist/hitl/approvalCompleteParked.js +14 -0
- package/dist/hitl/approvalEndingCause.d.ts +5 -0
- package/dist/hitl/approvalEndingCause.js +61 -0
- package/dist/hitl/approvalHolds.d.ts +46 -0
- package/dist/hitl/approvalHolds.js +140 -0
- package/dist/hitl/approvalOutcomeNote.js +2 -1
- package/dist/hitl/approvalResolution.js +9 -1
- package/dist/hitl/approvalsFeed.js +23 -6
- package/dist/hitl/askGateWire.d.ts +2 -1
- package/dist/hitl/askGateWire.js +29 -1
- package/dist/hitl/automaticAnswerVerdict.d.ts +8 -2
- package/dist/hitl/automaticAnswerVerdict.js +71 -23
- package/dist/hitl/crashConverged.js +2 -0
- package/dist/hitl/decisionConflict.d.ts +3 -0
- package/dist/hitl/decisionConflict.js +43 -0
- package/dist/hitl/decisionRefusal.d.ts +23 -0
- package/dist/hitl/decisionRefusal.js +88 -0
- package/dist/hitl/frameRouter.d.ts +10 -0
- package/dist/hitl/frameRouter.js +71 -32
- package/dist/hitl/gateLedger.d.ts +8 -0
- package/dist/hitl/gateLedger.js +38 -0
- package/dist/hitl/hitlBridge.d.ts +14 -3
- package/dist/hitl/hitlBridge.js +75 -62
- package/dist/hitl/hitlHostSurface.d.ts +3 -0
- package/dist/hitl/hitlHostSurface.js +17 -15
- package/dist/hitl/livePendingAsk.d.ts +16 -6
- package/dist/hitl/livePendingAsk.js +36 -4
- package/dist/hitl/localAllowRule.js +2 -1
- package/dist/hitl/noAllowCause.d.ts +9 -0
- package/dist/hitl/noAllowCause.js +26 -0
- package/dist/hitl/parkExpiryJudgements.d.ts +19 -0
- package/dist/hitl/parkExpiryJudgements.js +46 -0
- package/dist/hitl/parkResolver.d.ts +3 -7
- package/dist/hitl/parkResolver.js +55 -28
- package/dist/hitl/parkRowBirthWait.js +2 -1
- package/dist/hitl/persistedRulesWire.d.ts +6 -1
- package/dist/hitl/persistedRulesWire.js +16 -4
- package/dist/hitl/planReviewWire.d.ts +2 -3
- package/dist/hitl/planReviewWire.js +86 -39
- package/dist/hitl/replayedApproval.d.ts +8 -0
- package/dist/hitl/replayedApproval.js +125 -10
- package/dist/hitl/resumeRunningCard.d.ts +2 -0
- package/dist/hitl/resumeRunningCard.js +15 -4
- package/dist/hitl/sessionPolicyDeliverable.d.ts +1 -1
- package/dist/hitl/sessionPolicyDeliverable.js +3 -8
- package/dist/hitl/sessionPolicyWire.js +1 -1
- package/dist/hitl/toolApprovalWire.d.ts +50 -5
- package/dist/hitl/toolApprovalWire.js +368 -56
- package/dist/hooksWireCaps.js +38 -6
- package/dist/host.d.ts +5 -0
- package/dist/host.js +3 -1
- package/dist/hostCallbackGuard.d.ts +1 -0
- package/dist/hostCallbackGuard.js +25 -0
- package/dist/humanTurnRead.d.ts +15 -1
- package/dist/humanTurnRead.js +28 -2
- package/dist/index.d.ts +45 -14
- package/dist/index.js +33 -12
- package/dist/interactiveInterrupt.d.ts +8 -0
- package/dist/interactiveInterrupt.js +54 -0
- package/dist/limitsWire.d.ts +5 -1
- package/dist/limitsWire.js +51 -13
- package/dist/liveModelCatalog.d.ts +109 -0
- package/dist/liveModelCatalog.js +344 -18
- package/dist/mcpEngineLeg.d.ts +25 -0
- package/dist/mcpEngineLeg.js +71 -15
- package/dist/mcpPanel.js +2 -1
- package/dist/mcpProbeCapability.d.ts +0 -1
- package/dist/mcpProbeCapability.js +13 -12
- package/dist/mcpReconnect.d.ts +1 -3
- package/dist/mcpReconnect.js +20 -10
- package/dist/memoryComplianceCapability.d.ts +0 -1
- package/dist/memoryComplianceCapability.js +14 -13
- package/dist/memoryOriginCapability.d.ts +0 -1
- package/dist/memoryOriginCapability.js +14 -13
- package/dist/memoryVerbsWire.d.ts +1 -1
- package/dist/memoryVerbsWire.js +4 -0
- package/dist/model/liveCatalogShape.d.ts +14 -0
- package/dist/model/liveCatalogShape.js +71 -0
- package/dist/model/modelSupplyRules.d.ts +1 -0
- package/dist/model/modelSupplyRules.js +30 -9
- package/dist/model/modelsPolicy.d.ts +21 -0
- package/dist/model/modelsPolicy.js +90 -0
- package/dist/modelIdentityResolvability.d.ts +4 -2
- package/dist/modelIdentityResolvability.js +25 -5
- package/dist/modelSwitchFallback.d.ts +69 -0
- package/dist/modelSwitchFallback.js +206 -0
- package/dist/notifications.js +12 -11
- package/dist/outputStyleSeatCapability.d.ts +15 -0
- package/dist/outputStyleSeatCapability.js +42 -0
- package/dist/ownKey.d.ts +7 -0
- package/dist/ownKey.js +58 -0
- package/dist/panelReduce.d.ts +114 -0
- package/dist/panelReduce.js +1135 -0
- package/dist/panelStateHolder.d.ts +17 -0
- package/dist/panelStateHolder.js +201 -0
- package/dist/peerLaneCapability.d.ts +0 -1
- package/dist/peerLaneCapability.js +15 -14
- package/dist/permissionModesCapability.d.ts +0 -1
- package/dist/permissionModesCapability.js +5 -10
- package/dist/permissionRuleIssue.js +1 -1
- package/dist/permissionRulesWriteCapability.d.ts +0 -1
- package/dist/permissionRulesWriteCapability.js +15 -14
- package/dist/permissionsAllowGrantCapability.d.ts +2 -1
- package/dist/permissionsAllowGrantCapability.js +35 -19
- package/dist/permissionsDeclaration.d.ts +16 -1
- package/dist/permissionsDeclaration.js +142 -15
- package/dist/printToolResultFrame.js +2 -10
- package/dist/promptDelivery.js +0 -8
- package/dist/protocolSegment.d.ts +1 -0
- package/dist/protocolSegment.js +13 -1
- package/dist/request/taskRequest.d.ts +11 -3
- package/dist/request/taskRequest.js +13 -1
- package/dist/resultFrameKeys.d.ts +4 -0
- package/dist/resultFrameKeys.js +13 -0
- package/dist/resumeRefusalCopy.d.ts +18 -1
- package/dist/resumeRefusalCopy.js +132 -31
- package/dist/retryStatus.js +6 -4
- package/dist/rewindArchiveCapability.d.ts +2 -1
- package/dist/rewindArchiveCapability.js +28 -15
- package/dist/rewindEngineAction.d.ts +21 -0
- package/dist/rewindEngineAction.js +36 -0
- package/dist/rewindWireCaps.d.ts +2 -1
- package/dist/rewindWireCaps.js +1 -0
- package/dist/{hitl/rosterMountedNames.d.ts → rosterMountedNames.d.ts} +1 -1
- package/dist/runCancelContext.js +2 -1
- package/dist/runTerminal.d.ts +0 -11
- package/dist/runTerminal.js +4 -27
- package/dist/sdkRegistryTransit.d.ts +2 -1
- package/dist/sdkRegistryTransit.js +1 -0
- package/dist/sealedKeyCapability.d.ts +0 -1
- package/dist/sealedKeyCapability.js +19 -20
- package/dist/seatContract.d.ts +85 -28
- package/dist/seatContract.js +512 -148
- package/dist/sessionIdSegment.d.ts +1 -0
- package/dist/sessionIdSegment.js +11 -0
- package/dist/sessionMemoryErase.d.ts +1 -1
- package/dist/sessionMemoryErase.js +6 -1
- package/dist/sessionMemoryStatus.js +3 -2
- package/dist/sessionPolicyCapability.d.ts +0 -1
- package/dist/sessionPolicyCapability.js +14 -13
- package/dist/sessionReadRedactionCapability.d.ts +15 -0
- package/dist/sessionReadRedactionCapability.js +42 -0
- package/dist/sessionSyncFileHistoryCapability.d.ts +0 -1
- package/dist/sessionSyncFileHistoryCapability.js +13 -12
- package/dist/skillToolListsCapability.d.ts +0 -1
- package/dist/skillToolListsCapability.js +13 -12
- package/dist/skillsWireCaps.d.ts +4 -0
- package/dist/skillsWireCaps.js +66 -1
- package/dist/sqlEngineCapability.d.ts +0 -1
- package/dist/sqlEngineCapability.js +21 -21
- package/dist/steerPriorityCapability.d.ts +0 -1
- package/dist/steerPriorityCapability.js +18 -19
- package/dist/storePostureCapability.d.ts +1 -1
- package/dist/storePostureCapability.js +16 -16
- package/dist/streamDrainingLegs.d.ts +6 -0
- package/dist/streamDrainingLegs.js +23 -0
- package/dist/subagent/agentStateDetail.d.ts +1 -0
- package/dist/subagent/agentStateDetail.js +41 -0
- package/dist/subagent/engineCompactWire.d.ts +15 -0
- package/dist/subagent/engineCompactWire.js +82 -45
- package/dist/subagent/engineDelegatedPrompt.js +10 -6
- package/dist/subagent/engineSubagentOutput.d.ts +0 -1
- package/dist/subagent/engineSubagentOutput.js +5 -20
- package/dist/subagent/engineSubagentTail.d.ts +0 -1
- package/dist/subagent/engineSubagentTail.js +7 -32
- package/dist/subagentContentStore.js +3 -3
- package/dist/supportFloor.js +2 -5
- package/dist/taskRequestWords.d.ts +2 -4
- package/dist/taskRequestWords.js +3 -2
- package/dist/terminalStatuses.d.ts +30 -0
- package/dist/terminalStatuses.js +67 -0
- package/dist/toolResult.d.ts +5 -0
- package/dist/toolResult.js +88 -36
- package/dist/types/engineState.d.ts +2 -1
- package/dist/usageAnalytics.d.ts +146 -0
- package/dist/usageAnalytics.js +311 -0
- package/dist/userAttachmentEnvelope.d.ts +22 -1
- package/dist/userAttachmentEnvelope.js +90 -2
- package/dist/userInvokedSkillsCapability.d.ts +0 -1
- package/dist/userInvokedSkillsCapability.js +13 -12
- package/dist/webSearchBackendCapability.d.ts +0 -1
- package/dist/webSearchBackendCapability.js +20 -19
- package/dist/webSearchWireCaps.js +3 -11
- package/dist/wireErrorTriage.d.ts +11 -0
- package/dist/wireErrorTriage.js +35 -0
- package/dist/wireFailureShape.d.ts +10 -0
- package/dist/wireFailureShape.js +72 -5
- package/dist/wireRefusalCopy.d.ts +6 -1
- package/dist/wireRefusalCopy.js +23 -25
- package/dist/wiringInstructionsAttribution.d.ts +10 -0
- package/dist/wiringInstructionsAttribution.js +67 -0
- package/dist/workflowClient.js +19 -2
- package/dist/workflowsJournalCapability.d.ts +0 -1
- package/dist/workflowsJournalCapability.js +13 -12
- package/dist/writeProtectionCapability.d.ts +0 -1
- package/dist/writeProtectionCapability.js +26 -26
- package/docs/INTEGRATION-CLIENTS.md +1733 -52
- package/package.json +5 -5
- package/dist/askSurvivesStandingAnswer.d.ts +0 -13
- package/dist/askSurvivesStandingAnswer.js +0 -53
- package/dist/engineCapsGenerationGuard.d.ts +0 -4
- package/dist/engineCapsGenerationGuard.js +0 -19
- package/dist/hitl/askSurvivesPosture.d.ts +0 -20
- package/dist/hitl/askSurvivesPosture.js +0 -48
- package/dist/panelRunningHistory.d.ts +0 -22
- package/dist/panelRunningHistory.js +0 -82
- package/dist/registryConflict.d.ts +0 -3
- package/dist/registryConflict.js +0 -44
- /package/dist/{hitl/rosterMountedNames.js → rosterMountedNames.js} +0 -0
package/dist/displayUntrusted.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SETTINGS_SECRET_LITERAL_RE } from './generated/settingsSchemaTables.js';
|
|
1
|
+
import { SETTINGS_PRIVATE_KEY_PEM_HEADER, SETTINGS_SECRET_LITERAL_RE } from './generated/settingsSchemaTables.js';
|
|
2
2
|
export const REDACTION_MARKER_PREFIX = '\u00abredacted';
|
|
3
3
|
const MARKER_RE = /^\u00abredacted(?::[a-z-]{1,16}){0,2}\u00bb$/;
|
|
4
4
|
const REDACTED_USERINFO = '\u00abredacted:userinfo\u00bb';
|
|
@@ -28,9 +28,12 @@ const UNIT_NONE = 0;
|
|
|
28
28
|
const UNIT_SEQUENCE = 1;
|
|
29
29
|
const UNIT_SINGLE = 2;
|
|
30
30
|
const SECRET_LITERAL_RE = SETTINGS_SECRET_LITERAL_RE;
|
|
31
|
+
const PRIVATE_KEY_PEM_HEADER = SETTINGS_PRIVATE_KEY_PEM_HEADER;
|
|
31
32
|
const SCHEME_TOKEN_RE = /(?:^|[^A-Za-z0-9_-])(?:bearer|basic)[ \t]+\S{8,4096}/i;
|
|
32
33
|
const JWT_RE = /(?:^|[^A-Za-z0-9_-])eyJ[A-Za-z0-9_-]{8,2048}\.[A-Za-z0-9_-]{8,2048}\.[A-Za-z0-9_-]{4,2048}/i;
|
|
33
34
|
function scanForSecretLiteral(s) {
|
|
35
|
+
if (PRIVATE_KEY_PEM_HEADER.test(s))
|
|
36
|
+
return true;
|
|
34
37
|
if (SECRET_LITERAL_RE.test(s) || SCHEME_TOKEN_RE.test(s) || JWT_RE.test(s))
|
|
35
38
|
return true;
|
|
36
39
|
return s.split(/[^A-Za-z0-9_-]+/).some(tok => tok !== '' && SECRET_LITERAL_RE.test(tok));
|
|
@@ -100,8 +103,8 @@ function valueIsWholeMarker(S, start, end, tokenInner = true) {
|
|
|
100
103
|
return j >= end || !isKeyWordChar(text.charCodeAt(j)) || credentialWordStartsExactlyAt(text, j, tokenInner) || credentialPairAt(S, j);
|
|
101
104
|
}
|
|
102
105
|
const CREDENTIAL_NAME = /(?:(?:access|refresh|id|client|api|x[-_]api|session|auth)[-_]?)?(?:token|key|secret|password|authorization|credential)s?|bearer|basic/iy;
|
|
103
|
-
const LABEL_SEPARATOR = /(?:\\*["'])?[\s\u115F\u1160\u3164\uFFA0\u2800]*[:=\uFF1A\uFF1D]/y;
|
|
104
|
-
const SCHEME_SEPARATOR = /[\s:=\uFF1A\uFF1D\u115F\u1160\u3164\uFFA0\u2800]/y;
|
|
106
|
+
const LABEL_SEPARATOR = /(?:\\*["'])?(?:[\s\u115F\u1160\u3164\uFFA0\u2800]|\\t)*[:=\uFF1A\uFF1D]/y;
|
|
107
|
+
const SCHEME_SEPARATOR = /(?:[\s:=\uFF1A\uFF1D\u115F\u1160\u3164\uFFA0\u2800]|\\t)/y;
|
|
105
108
|
function credentialPairAt(S, at) {
|
|
106
109
|
const text = S.text;
|
|
107
110
|
const re = new RegExp(CREDENTIAL_NAME.source, 'iy');
|
|
@@ -283,15 +286,22 @@ function pathCandidates(src, base, path, opaqueSegments, edits, soft) {
|
|
|
283
286
|
for (const segment of path.split('/')) {
|
|
284
287
|
const semi = segment.indexOf(';');
|
|
285
288
|
const head = semi === -1 ? segment : segment.slice(0, semi);
|
|
286
|
-
if (opaqueSegments
|
|
289
|
+
if (opaqueSegments) {
|
|
287
290
|
let a = 0;
|
|
288
291
|
let b = head.length;
|
|
289
292
|
while (a < b && !isKeyWordChar(head.charCodeAt(a)))
|
|
290
293
|
a++;
|
|
291
294
|
while (b > a && !isKeyWordChar(head.charCodeAt(b - 1)))
|
|
292
295
|
b--;
|
|
293
|
-
if (
|
|
294
|
-
|
|
296
|
+
if (isKnownSecretSegment(head)) {
|
|
297
|
+
if (b > a)
|
|
298
|
+
pushEdit(edits, src, pos + a, pos + b, REDACTED_SECRET);
|
|
299
|
+
}
|
|
300
|
+
else if (b > a) {
|
|
301
|
+
const glued = gluedLiteralStart(head.slice(a, b));
|
|
302
|
+
if (glued > 0)
|
|
303
|
+
pushEdit(edits, src, pos + a + glued, pos + b, REDACTED_SECRET);
|
|
304
|
+
}
|
|
295
305
|
}
|
|
296
306
|
if (semi !== -1) {
|
|
297
307
|
let ppos = pos + semi + 1;
|
|
@@ -398,6 +408,7 @@ function urlCandidates(text, out, regions, unitPos = () => false, soft) {
|
|
|
398
408
|
runStart--;
|
|
399
409
|
if (runStart < end && !VALUE_BOUNDARY_TAIL.test(text.slice(start, runStart)))
|
|
400
410
|
end = runStart;
|
|
411
|
+
end = trailingCloserEnd(text, start, mark + 3, end, unitPos);
|
|
401
412
|
const tokenEdits = [];
|
|
402
413
|
urlTokenCandidatesAt(text, start, end, tokenEdits, soft);
|
|
403
414
|
editsToCandidates(tokenEdits, 'url', out, end);
|
|
@@ -417,6 +428,47 @@ function urlCandidates(text, out, regions, unitPos = () => false, soft) {
|
|
|
417
428
|
mark = text.indexOf('://', end > mark + 3 ? end : mark + 3);
|
|
418
429
|
}
|
|
419
430
|
}
|
|
431
|
+
function trailingCloserEnd(text, start, floor, end, unitPos) {
|
|
432
|
+
const opens = new Map();
|
|
433
|
+
const closes = new Map();
|
|
434
|
+
for (const [o, c] of BRACKET_PAIRS) {
|
|
435
|
+
opens.set(o, 0);
|
|
436
|
+
closes.set(c, 0);
|
|
437
|
+
}
|
|
438
|
+
for (let k = start; k < end; k++) {
|
|
439
|
+
if (unitPos(k))
|
|
440
|
+
continue;
|
|
441
|
+
const ch = text.charAt(k);
|
|
442
|
+
const o = opens.get(ch);
|
|
443
|
+
if (o !== undefined)
|
|
444
|
+
opens.set(ch, o + 1);
|
|
445
|
+
const c = closes.get(ch);
|
|
446
|
+
if (c !== undefined)
|
|
447
|
+
closes.set(ch, c + 1);
|
|
448
|
+
}
|
|
449
|
+
let e = end;
|
|
450
|
+
for (;;) {
|
|
451
|
+
if (e <= floor || unitPos(e - 1))
|
|
452
|
+
return e;
|
|
453
|
+
const ch = text.charAt(e - 1);
|
|
454
|
+
const c = closes.get(ch);
|
|
455
|
+
if (c === undefined)
|
|
456
|
+
return e;
|
|
457
|
+
let open = '';
|
|
458
|
+
for (const [o, cl] of BRACKET_PAIRS)
|
|
459
|
+
if (cl === ch)
|
|
460
|
+
open = o;
|
|
461
|
+
if (c <= (opens.get(open) ?? 0))
|
|
462
|
+
return e;
|
|
463
|
+
closes.set(ch, c - 1);
|
|
464
|
+
e--;
|
|
465
|
+
let runStart = e;
|
|
466
|
+
while (runStart > floor && TRAILING_PUNCTUATION.has(text.charAt(runStart - 1)))
|
|
467
|
+
runStart--;
|
|
468
|
+
if (runStart < e && !VALUE_BOUNDARY_TAIL.test(text.slice(start, runStart)))
|
|
469
|
+
e = runStart;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
420
472
|
function atInAuthority(text, from) {
|
|
421
473
|
for (let p = from; p < text.length; p++) {
|
|
422
474
|
const ch = text.charAt(p);
|
|
@@ -760,9 +812,9 @@ const NAME_BLANK_RANGES = [
|
|
|
760
812
|
const isNameBlank = (cp) => NAME_BLANK_RANGES.some(([a, b]) => cp >= a && cp <= b);
|
|
761
813
|
const isFoldedBlank = (c) => isNameBlank(c) && isRegexSpace(c);
|
|
762
814
|
const isUnicodeBlank = (c) => (c > 0x7f && isRegexSpace(c) && c !== 0xfeff) || isNameBlank(c);
|
|
763
|
-
const SECRET_SCHEME_WORD = /(?:\b|(?<=\\[A-Za-z"']))(bearer|basic|token)[\s:=\uFF1A\uFF1D\u115F\u1160\u3164\uFFA0\u2800]+/gi;
|
|
815
|
+
const SECRET_SCHEME_WORD = /(?:\b|(?<=\\[A-Za-z"']))(?!(?<=(?<!\\)\\)(?:bearer|basic|token)\\t)(bearer|basic|token)(?:[\s:=\uFF1A\uFF1D\u115F\u1160\u3164\uFFA0\u2800]|\\t)+/gi;
|
|
764
816
|
const schemeWordIsInner = (word, tokenInner) => tokenInner || word.toLowerCase() !== 'token';
|
|
765
|
-
const SECRET_LABELLED_WORD = /(?:\b|(?<=_)|(?<=\\[A-Za-z"']))((?:access[-_ ]?|refresh[-_ ]?|id[-_ ]?|client[-_ ]?|api[-_ ]?|x[-_]api[-_ ]?|session[-_ ]?|auth[-_ ]?)?(?:token|key|secret|password|authorization|credential)s?)(?:\\*["'])?[\s\u115F\u1160\u3164\uFFA0\u2800]*[:=\uFF1A\uFF1D][\s\u115F\u1160\u3164\uFFA0\u2800]*/gi;
|
|
817
|
+
const SECRET_LABELLED_WORD = /(?:\b|(?<=_)|(?<=\\[A-Za-z"']))((?:access[-_ ]?|refresh[-_ ]?|id[-_ ]?|client[-_ ]?|api[-_ ]?|x[-_]api[-_ ]?|session[-_ ]?|auth[-_ ]?)?(?:token|key|secret|password|authorization|credential)s?)(?:\\*["'])?(?:[\s\u115F\u1160\u3164\uFFA0\u2800]|\\t)*[:=\uFF1A\uFF1D](?:[\s\u115F\u1160\u3164\uFFA0\u2800]|\\t)*/gi;
|
|
766
818
|
const DIAGNOSTIC_VALUE_WORDS = new Set([
|
|
767
819
|
'missing', 'required', 'invalid', 'expired', 'unauthorized', 'unauthenticated', 'authentication',
|
|
768
820
|
'authorization', 'credential', 'credentials', 'unsupported', 'malformed', 'rejected', 'absent',
|
|
@@ -817,18 +869,67 @@ const AUTH_SCHEME_WORDS = new Set([
|
|
|
817
869
|
const AUTH_SIGNATURE_SCHEME = /^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+){2,}$/;
|
|
818
870
|
const BARE_VALUE_STOP_CHARS = new Set([',', ';', '"', "'", '\\', '(', ')', '[', ']', '{', '}', '<', '>']);
|
|
819
871
|
const isBareValueStop = (ch) => ch <= ' ' || BARE_VALUE_STOP_CHARS.has(ch);
|
|
872
|
+
function isPlainAt(S, rawUnit, k) {
|
|
873
|
+
if (S.dropped(k) || S.painted(k) || S.unitAt(k) !== UNIT_NONE)
|
|
874
|
+
return false;
|
|
875
|
+
return rawUnit === null || rawUnit[S.rawStart(k)] !== 1;
|
|
876
|
+
}
|
|
877
|
+
function codeSpanClose(text, plain) {
|
|
878
|
+
const n = text.length;
|
|
879
|
+
const close = new Int32Array(n + 1).fill(-1);
|
|
880
|
+
let openLen = 0;
|
|
881
|
+
let spanFrom = -1;
|
|
882
|
+
let k = 0;
|
|
883
|
+
while (k < n) {
|
|
884
|
+
const c = text.charCodeAt(k);
|
|
885
|
+
if (c === 0x0a || c === 0x0d || c === 0x2028 || c === 0x2029) {
|
|
886
|
+
openLen = 0;
|
|
887
|
+
spanFrom = -1;
|
|
888
|
+
k++;
|
|
889
|
+
continue;
|
|
890
|
+
}
|
|
891
|
+
if (c !== 0x60 || !plain(k)) {
|
|
892
|
+
k++;
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
let e = k;
|
|
896
|
+
while (e < n && text.charCodeAt(e) === 0x60 && plain(e))
|
|
897
|
+
e++;
|
|
898
|
+
const len = e - k;
|
|
899
|
+
if (openLen === 0) {
|
|
900
|
+
openLen = len;
|
|
901
|
+
spanFrom = e;
|
|
902
|
+
}
|
|
903
|
+
else if (len === openLen) {
|
|
904
|
+
for (let x = spanFrom; x < k; x++)
|
|
905
|
+
close[x] = k;
|
|
906
|
+
openLen = 0;
|
|
907
|
+
spanFrom = -1;
|
|
908
|
+
}
|
|
909
|
+
k = e;
|
|
910
|
+
}
|
|
911
|
+
return close;
|
|
912
|
+
}
|
|
913
|
+
const BRACKET_PAIRS = new Map([['(', ')'], ['[', ']']]);
|
|
820
914
|
class InnerWordIndex {
|
|
821
915
|
text;
|
|
822
916
|
tokenInner;
|
|
823
917
|
probes;
|
|
824
|
-
|
|
918
|
+
plain;
|
|
919
|
+
spanClose = null;
|
|
920
|
+
constructor(text, tokenInner = true, plain = () => true) {
|
|
825
921
|
this.text = text;
|
|
826
922
|
this.tokenInner = tokenInner;
|
|
923
|
+
this.plain = plain;
|
|
827
924
|
this.probes = [
|
|
828
925
|
{ re: new RegExp(SECRET_LABELLED_WORD.source, SECRET_LABELLED_WORD.flags), scheme: false, from: -1, hit: null },
|
|
829
926
|
{ re: new RegExp(SECRET_SCHEME_WORD.source, SECRET_SCHEME_WORD.flags), scheme: true, from: -1, hit: null },
|
|
830
927
|
];
|
|
831
928
|
}
|
|
929
|
+
closingTickFrom(i) {
|
|
930
|
+
this.spanClose ??= codeSpanClose(this.text, this.plain);
|
|
931
|
+
return this.spanClose[i] ?? -1;
|
|
932
|
+
}
|
|
832
933
|
next(q) {
|
|
833
934
|
let best = null;
|
|
834
935
|
for (const p of this.probes) {
|
|
@@ -854,6 +955,45 @@ class InnerWordIndex {
|
|
|
854
955
|
return best;
|
|
855
956
|
}
|
|
856
957
|
}
|
|
958
|
+
const WRAPPED_PLACEHOLDER = /^(?:[A-Z]{1,12}(?:_[A-Z]{1,12})*|[a-z]{1,12}(?:-[a-z]{1,12})*)$/;
|
|
959
|
+
function wrappedValueAt(text, from, idx) {
|
|
960
|
+
let k = from;
|
|
961
|
+
while (k < text.length && text[k] === VIEW_SEPARATOR)
|
|
962
|
+
k++;
|
|
963
|
+
const close = BRACKET_PAIRS.get(text.charAt(k));
|
|
964
|
+
if (close === undefined || credentialWordStartsAt(text, k + 1, idx.tokenInner))
|
|
965
|
+
return null;
|
|
966
|
+
const inner = scanSecretValue(text, k + 1, idx);
|
|
967
|
+
if (inner === null || inner.start !== k + 1)
|
|
968
|
+
return null;
|
|
969
|
+
let c = inner.end;
|
|
970
|
+
while (c < text.length && text[c] === VIEW_SEPARATOR)
|
|
971
|
+
c++;
|
|
972
|
+
if (text.charAt(c) !== close || (close === ']' && text.charAt(c + 1) === '('))
|
|
973
|
+
return null;
|
|
974
|
+
return inner;
|
|
975
|
+
}
|
|
976
|
+
function tokenSchemeValueEnd(text, start, end, idx) {
|
|
977
|
+
if (withoutSeparators(text.slice(start, end)).toLowerCase() !== 'token')
|
|
978
|
+
return -1;
|
|
979
|
+
const re = new RegExp(SECRET_SCHEME_WORD.source, 'iy');
|
|
980
|
+
re.lastIndex = start;
|
|
981
|
+
const m = re.exec(text);
|
|
982
|
+
if (m === null || (m[1] ?? '').toLowerCase() !== 'token')
|
|
983
|
+
return -1;
|
|
984
|
+
const sepEnd = start + m[0].length;
|
|
985
|
+
if (/[\n\r\u2028\u2029:=\uFF1A\uFF1D]/.test(text.slice(start + (m[1] ?? '').length, sepEnd)))
|
|
986
|
+
return -1;
|
|
987
|
+
if (credentialWordStartsAt(text, sepEnd, idx.tokenInner))
|
|
988
|
+
return -1;
|
|
989
|
+
const iv = scanSecretValue(text, sepEnd, idx);
|
|
990
|
+
if (iv === null)
|
|
991
|
+
return -1;
|
|
992
|
+
const inner = withoutSeparators(text.slice(iv.start, iv.end));
|
|
993
|
+
if (schemeFollowerReleased('token', inner, false) || isDiagnosticWord(inner))
|
|
994
|
+
return -1;
|
|
995
|
+
return iv.end;
|
|
996
|
+
}
|
|
857
997
|
function innerWordFits(text, w) {
|
|
858
998
|
for (let k = w.start; k <= w.sepAt && k < text.length; k++)
|
|
859
999
|
if (isBareValueStop(text.charAt(k)))
|
|
@@ -909,6 +1049,7 @@ function scanSecretValue(text, from, idx) {
|
|
|
909
1049
|
let pending = cuttable ? idx.next(i + 1) : null;
|
|
910
1050
|
let cut = false;
|
|
911
1051
|
let j = i;
|
|
1052
|
+
const closingTick = idx === undefined ? -1 : idx.closingTickFrom(i);
|
|
912
1053
|
while (j < text.length) {
|
|
913
1054
|
if (pending !== null && j >= pending.start) {
|
|
914
1055
|
if (j === pending.start && innerWordFits(text, pending)) {
|
|
@@ -933,6 +1074,18 @@ function scanSecretValue(text, from, idx) {
|
|
|
933
1074
|
}
|
|
934
1075
|
while (j > i && text[j - 1] === VIEW_SEPARATOR)
|
|
935
1076
|
j--;
|
|
1077
|
+
if (closingTick > i && closingTick < j) {
|
|
1078
|
+
let t = closingTick;
|
|
1079
|
+
while (t < j && text.charCodeAt(t) === 0x60)
|
|
1080
|
+
t++;
|
|
1081
|
+
while (t < j && TRAILING_PUNCTUATION.has(text.charAt(t)))
|
|
1082
|
+
t++;
|
|
1083
|
+
if (t === j && text.charCodeAt(closingTick) === 0x60) {
|
|
1084
|
+
j = closingTick;
|
|
1085
|
+
while (j > i && text[j - 1] === VIEW_SEPARATOR)
|
|
1086
|
+
j--;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
936
1089
|
if (cut) {
|
|
937
1090
|
while (j > i && isCutDelimiter(text.charAt(j - 1))) {
|
|
938
1091
|
j--;
|
|
@@ -952,6 +1105,9 @@ function isDiagnosticValue(value, raw = value) {
|
|
|
952
1105
|
return true;
|
|
953
1106
|
if (ADDRESS_SCHEME_RE.test(raw))
|
|
954
1107
|
return true;
|
|
1108
|
+
return isDiagnosticWord(value);
|
|
1109
|
+
}
|
|
1110
|
+
function isDiagnosticWord(value) {
|
|
955
1111
|
const bare = value.replace(/^\.+/, '').replace(/[.,;:!?)\]}'"]{0,8}$/, '').toLowerCase();
|
|
956
1112
|
return bare === '' || DIAGNOSTIC_VALUE_WORDS.has(bare);
|
|
957
1113
|
}
|
|
@@ -1011,6 +1167,26 @@ function isNamedNotValue(label, value) {
|
|
|
1011
1167
|
return true;
|
|
1012
1168
|
return isBacktickedCredentialName(value);
|
|
1013
1169
|
}
|
|
1170
|
+
function schemeIsLabelValue(text, at) {
|
|
1171
|
+
let k = at;
|
|
1172
|
+
while (k > 0 && text[k - 1] === VIEW_SEPARATOR)
|
|
1173
|
+
k--;
|
|
1174
|
+
if (k > 0 && isQuoteChar(text.charAt(k - 1))) {
|
|
1175
|
+
k--;
|
|
1176
|
+
while (k > 0 && text.charCodeAt(k - 1) === 0x5c)
|
|
1177
|
+
k--;
|
|
1178
|
+
}
|
|
1179
|
+
return k > 0 && labelEndsAt(text, k);
|
|
1180
|
+
}
|
|
1181
|
+
function labelQuotedAt(text, at, sep) {
|
|
1182
|
+
const q = text.charAt(at - 1);
|
|
1183
|
+
if (!isQuoteChar(q))
|
|
1184
|
+
return false;
|
|
1185
|
+
let k = 0;
|
|
1186
|
+
while (sep.charCodeAt(k) === 0x5c)
|
|
1187
|
+
k++;
|
|
1188
|
+
return sep.charAt(k) === q;
|
|
1189
|
+
}
|
|
1014
1190
|
function labelStartsAt(text, at) {
|
|
1015
1191
|
const re = new RegExp(SECRET_LABELLED_WORD.source, 'iy');
|
|
1016
1192
|
re.lastIndex = at;
|
|
@@ -1474,13 +1650,467 @@ function quotedAddressEnd(S, from, to) {
|
|
|
1474
1650
|
}
|
|
1475
1651
|
return to;
|
|
1476
1652
|
}
|
|
1653
|
+
function isInlineBlank(ch) {
|
|
1654
|
+
if (ch === VIEW_SEPARATOR)
|
|
1655
|
+
return true;
|
|
1656
|
+
const c = ch.charCodeAt(0);
|
|
1657
|
+
if (c === 0x0a || c === 0x0d || c === 0x2028 || c === 0x2029)
|
|
1658
|
+
return false;
|
|
1659
|
+
return isRegexSpace(c) || isNameBlank(c);
|
|
1660
|
+
}
|
|
1661
|
+
const isAnyBlank = (ch) => ch === VIEW_SEPARATOR || isRegexSpace(ch.charCodeAt(0)) || isNameBlank(ch.charCodeAt(0));
|
|
1662
|
+
function nodePropertyEnd(text, at) {
|
|
1663
|
+
const sigil = text.charAt(at);
|
|
1664
|
+
let j = at + 1;
|
|
1665
|
+
if (sigil === '!') {
|
|
1666
|
+
if (text.charAt(j) === '<') {
|
|
1667
|
+
const limit = Math.min(text.length, j + 512);
|
|
1668
|
+
let k = j + 1;
|
|
1669
|
+
while (k < limit && text.charAt(k) !== '>' && !isAnyBlank(text.charAt(k)))
|
|
1670
|
+
k++;
|
|
1671
|
+
if (text.charAt(k) !== '>' || k === j + 1)
|
|
1672
|
+
return -1;
|
|
1673
|
+
j = k + 1;
|
|
1674
|
+
}
|
|
1675
|
+
else {
|
|
1676
|
+
while (j < text.length && !isBareValueStop(text.charAt(j)))
|
|
1677
|
+
j++;
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
else if (sigil === '&') {
|
|
1681
|
+
while (j < text.length && !isBareValueStop(text.charAt(j)))
|
|
1682
|
+
j++;
|
|
1683
|
+
if (j === at + 1)
|
|
1684
|
+
return -1;
|
|
1685
|
+
}
|
|
1686
|
+
else
|
|
1687
|
+
return -1;
|
|
1688
|
+
return j < text.length && isInlineBlank(text.charAt(j)) ? j : -1;
|
|
1689
|
+
}
|
|
1690
|
+
function nodeProperties(text, from) {
|
|
1691
|
+
let i = from;
|
|
1692
|
+
while (text.charAt(i) === VIEW_SEPARATOR)
|
|
1693
|
+
i++;
|
|
1694
|
+
const start = i;
|
|
1695
|
+
let end = -1;
|
|
1696
|
+
for (;;) {
|
|
1697
|
+
const c = text.charAt(i);
|
|
1698
|
+
if (c !== '!' && c !== '&')
|
|
1699
|
+
break;
|
|
1700
|
+
const e = nodePropertyEnd(text, i);
|
|
1701
|
+
if (e === -1)
|
|
1702
|
+
break;
|
|
1703
|
+
end = e;
|
|
1704
|
+
i = e;
|
|
1705
|
+
while (i < text.length && isInlineBlank(text.charAt(i)))
|
|
1706
|
+
i++;
|
|
1707
|
+
}
|
|
1708
|
+
return end === -1 ? null : { start, end, next: i };
|
|
1709
|
+
}
|
|
1710
|
+
function propertiesSameLine(S, pr) {
|
|
1711
|
+
if (pr.next >= S.text.length)
|
|
1712
|
+
return false;
|
|
1713
|
+
const a = S.rawStart(pr.start);
|
|
1714
|
+
const b = S.rawStart(pr.next);
|
|
1715
|
+
return b >= a && !/[\n\r\u2028\u2029\u0085]/.test(S.raw.slice(a, b));
|
|
1716
|
+
}
|
|
1717
|
+
function hasValueAt(text, at) {
|
|
1718
|
+
if (at >= text.length)
|
|
1719
|
+
return false;
|
|
1720
|
+
const c = text.charAt(at);
|
|
1721
|
+
if (c === '|' || c === '>' || c === '[' || c === '\\' || isQuoteChar(c))
|
|
1722
|
+
return true;
|
|
1723
|
+
return !isBareValueStop(c) && c !== VIEW_SEPARATOR;
|
|
1724
|
+
}
|
|
1725
|
+
const SGR_REMNANT = /^\[[0-9;]*m(?:\u00abredacted|\s|$)/;
|
|
1726
|
+
function bracketPairs(text) {
|
|
1727
|
+
const pairs = new Int32Array(text.length).fill(-1);
|
|
1728
|
+
const stack = [];
|
|
1729
|
+
for (let i = 0; i < text.length; i++) {
|
|
1730
|
+
const c = text.charCodeAt(i);
|
|
1731
|
+
if (c === 0x5b)
|
|
1732
|
+
stack.push(i);
|
|
1733
|
+
else if (c === 0x5d) {
|
|
1734
|
+
const o = stack.pop();
|
|
1735
|
+
if (o !== undefined)
|
|
1736
|
+
pairs[o] = i;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
return pairs;
|
|
1740
|
+
}
|
|
1741
|
+
const LIST_NEUTRAL_ITEM = /^(?:object Object|Object|Array|Circular|Getter|Setter|Getter\/Setter|native code|hidden|masked|omitted|truncated)$/i;
|
|
1742
|
+
function afterClosingQuote(text, end) {
|
|
1743
|
+
let k = end;
|
|
1744
|
+
while (text.charAt(k) === VIEW_SEPARATOR)
|
|
1745
|
+
k++;
|
|
1746
|
+
let q = k;
|
|
1747
|
+
while (text.charCodeAt(q) === 0x5c)
|
|
1748
|
+
q++;
|
|
1749
|
+
const c = text.charAt(q);
|
|
1750
|
+
return isQuoteChar(c) ? q + 1 : end;
|
|
1751
|
+
}
|
|
1752
|
+
function matchBrace(text, open) {
|
|
1753
|
+
let depth = 0;
|
|
1754
|
+
let quote = '';
|
|
1755
|
+
for (let i = open; i < text.length; i++) {
|
|
1756
|
+
const c = text.charAt(i);
|
|
1757
|
+
if (quote !== '') {
|
|
1758
|
+
if (c === '\\')
|
|
1759
|
+
i++;
|
|
1760
|
+
else if (c === quote)
|
|
1761
|
+
quote = '';
|
|
1762
|
+
continue;
|
|
1763
|
+
}
|
|
1764
|
+
if (isQuoteChar(c))
|
|
1765
|
+
quote = c;
|
|
1766
|
+
else if (c === '{')
|
|
1767
|
+
depth++;
|
|
1768
|
+
else if (c === '}' && --depth === 0)
|
|
1769
|
+
return i;
|
|
1770
|
+
}
|
|
1771
|
+
return text.length;
|
|
1772
|
+
}
|
|
1773
|
+
function flowListItems(text, open, idx, budget) {
|
|
1774
|
+
if (budget.left <= 0 || SGR_REMNANT.test(text.slice(open, open + 32)))
|
|
1775
|
+
return null;
|
|
1776
|
+
budget.pairs ??= bracketPairs(text);
|
|
1777
|
+
const plainClose = budget.pairs[open] ?? -1;
|
|
1778
|
+
if (plainClose >= 0 && text.charAt(plainClose + 1) === '(')
|
|
1779
|
+
return null;
|
|
1780
|
+
const out = flowListScan(text, open, idx);
|
|
1781
|
+
budget.left -= out.end - open;
|
|
1782
|
+
return out.link ? null : { items: out.items, end: out.end };
|
|
1783
|
+
}
|
|
1784
|
+
function flowListScan(text, open, idx) {
|
|
1785
|
+
const items = [];
|
|
1786
|
+
const n = text.length;
|
|
1787
|
+
let depth = 0;
|
|
1788
|
+
let i = open;
|
|
1789
|
+
while (i < n) {
|
|
1790
|
+
const ch = text.charAt(i);
|
|
1791
|
+
if (ch === '[') {
|
|
1792
|
+
depth++;
|
|
1793
|
+
i++;
|
|
1794
|
+
continue;
|
|
1795
|
+
}
|
|
1796
|
+
if (ch === ']') {
|
|
1797
|
+
depth--;
|
|
1798
|
+
i++;
|
|
1799
|
+
if (depth <= 0)
|
|
1800
|
+
return { items, end: i, link: text.charAt(i) === '(' };
|
|
1801
|
+
continue;
|
|
1802
|
+
}
|
|
1803
|
+
if (ch === ',' || ch === '}' || isAnyBlank(ch) || ch === '\n' || ch === '\r') {
|
|
1804
|
+
i++;
|
|
1805
|
+
continue;
|
|
1806
|
+
}
|
|
1807
|
+
const escapedBreak = ch === '\\' ? lineBreakLengthAt(text, i) : 0;
|
|
1808
|
+
if (escapedBreak > 0) {
|
|
1809
|
+
i += escapedBreak;
|
|
1810
|
+
continue;
|
|
1811
|
+
}
|
|
1812
|
+
if (ch === '{') {
|
|
1813
|
+
const e = matchBrace(text, i);
|
|
1814
|
+
if (e > i + 1)
|
|
1815
|
+
items.push({ start: i + 1, end: e });
|
|
1816
|
+
i = Math.min(n, e + 1);
|
|
1817
|
+
continue;
|
|
1818
|
+
}
|
|
1819
|
+
let q = i;
|
|
1820
|
+
while (text.charCodeAt(q) === 0x5c)
|
|
1821
|
+
q++;
|
|
1822
|
+
if (isQuoteChar(text.charAt(q))) {
|
|
1823
|
+
const v = scanSecretValue(text, i, idx);
|
|
1824
|
+
if (v === null) {
|
|
1825
|
+
i = q + 1;
|
|
1826
|
+
continue;
|
|
1827
|
+
}
|
|
1828
|
+
items.push({ start: v.start, end: v.end, quoted: true });
|
|
1829
|
+
i = Math.max(afterClosingQuote(text, v.end), i + 1);
|
|
1830
|
+
continue;
|
|
1831
|
+
}
|
|
1832
|
+
let j = i;
|
|
1833
|
+
while (j < n) {
|
|
1834
|
+
const c = text.charAt(j);
|
|
1835
|
+
if (c === ',' || c === ']' || c === '[' || c === '{' || c === '}' || c === '\n' || c === '\r' || (c === '\\' && lineBreakLengthAt(text, j) > 0))
|
|
1836
|
+
break;
|
|
1837
|
+
j++;
|
|
1838
|
+
}
|
|
1839
|
+
let e = j;
|
|
1840
|
+
while (e > i && isAnyBlank(text.charAt(e - 1)))
|
|
1841
|
+
e--;
|
|
1842
|
+
if (e > i)
|
|
1843
|
+
items.push({ start: i, end: e });
|
|
1844
|
+
i = j > i ? j : i + 1;
|
|
1845
|
+
}
|
|
1846
|
+
return { items, end: n, link: false };
|
|
1847
|
+
}
|
|
1848
|
+
const PAIR_ITEM = /^[A-Za-z_][A-Za-z0-9_.-]*(?:=|:(?!\/))[^\s,;]/;
|
|
1849
|
+
function lineBreakAtView(S, k) {
|
|
1850
|
+
const ch = S.text.charAt(k);
|
|
1851
|
+
if (ch === '\n' || ch === '\r' || ch === '\u2028' || ch === '\u2029')
|
|
1852
|
+
return true;
|
|
1853
|
+
if (ch !== VIEW_SEPARATOR)
|
|
1854
|
+
return false;
|
|
1855
|
+
const a = S.rawStart(k);
|
|
1856
|
+
return /[\n\r\u2028\u2029\u0085]/.test(S.raw.slice(a, Math.max(a + 1, S.rawEnd(k))));
|
|
1857
|
+
}
|
|
1858
|
+
function scanListItem(S, i, idx) {
|
|
1859
|
+
const text = S.text;
|
|
1860
|
+
const v = scanSecretValue(text, i, idx);
|
|
1861
|
+
if (v === null)
|
|
1862
|
+
return null;
|
|
1863
|
+
let q = i;
|
|
1864
|
+
while (text.charCodeAt(q) === 0x5c)
|
|
1865
|
+
q++;
|
|
1866
|
+
if (isQuoteChar(text.charAt(q)))
|
|
1867
|
+
return v;
|
|
1868
|
+
for (let k = v.start; k < v.end; k++) {
|
|
1869
|
+
if (text.charAt(k) !== VIEW_SEPARATOR || !lineBreakAtView(S, k))
|
|
1870
|
+
continue;
|
|
1871
|
+
let e = k;
|
|
1872
|
+
while (e > v.start && text.charAt(e - 1) === VIEW_SEPARATOR)
|
|
1873
|
+
e--;
|
|
1874
|
+
return e > v.start ? { start: v.start, end: e } : null;
|
|
1875
|
+
}
|
|
1876
|
+
return v;
|
|
1877
|
+
}
|
|
1878
|
+
function commaListTail(S, from, idx) {
|
|
1879
|
+
const text = S.text;
|
|
1880
|
+
const items = [];
|
|
1881
|
+
const n = text.length;
|
|
1882
|
+
let i = from;
|
|
1883
|
+
let end = from;
|
|
1884
|
+
for (;;) {
|
|
1885
|
+
let k = i;
|
|
1886
|
+
while (k < n && isInlineBlank(text.charAt(k)) && !lineBreakAtView(S, k))
|
|
1887
|
+
k++;
|
|
1888
|
+
if (text.charAt(k) !== ',')
|
|
1889
|
+
break;
|
|
1890
|
+
k++;
|
|
1891
|
+
while (k < n && isInlineBlank(text.charAt(k)) && !lineBreakAtView(S, k))
|
|
1892
|
+
k++;
|
|
1893
|
+
if (k >= n || credentialWordStartsAt(text, k, idx.tokenInner) || PAIR_ITEM.test(text.slice(k, k + 256)))
|
|
1894
|
+
break;
|
|
1895
|
+
let q = k;
|
|
1896
|
+
while (text.charCodeAt(q) === 0x5c)
|
|
1897
|
+
q++;
|
|
1898
|
+
const quotedItem = isQuoteChar(text.charAt(q));
|
|
1899
|
+
if (q > k && !quotedItem)
|
|
1900
|
+
break;
|
|
1901
|
+
const v = scanListItem(S, k, idx);
|
|
1902
|
+
if (v === null)
|
|
1903
|
+
break;
|
|
1904
|
+
const after = quotedItem ? afterClosingQuote(text, v.end) : v.end;
|
|
1905
|
+
let t = after;
|
|
1906
|
+
let lineEnd = false;
|
|
1907
|
+
while (t < n && isInlineBlank(text.charAt(t))) {
|
|
1908
|
+
if (lineBreakAtView(S, t)) {
|
|
1909
|
+
lineEnd = true;
|
|
1910
|
+
break;
|
|
1911
|
+
}
|
|
1912
|
+
t++;
|
|
1913
|
+
}
|
|
1914
|
+
const term = text.charAt(t);
|
|
1915
|
+
const stops = lineEnd || t >= n || term === ',' || term === ';' || term === ')' || term === ']' || term === '}' || term === '\\' || isQuoteChar(term) || term === '\n' || term === '\r';
|
|
1916
|
+
if (!stops)
|
|
1917
|
+
break;
|
|
1918
|
+
items.push(v);
|
|
1919
|
+
i = after;
|
|
1920
|
+
end = after;
|
|
1921
|
+
}
|
|
1922
|
+
return { items, end };
|
|
1923
|
+
}
|
|
1924
|
+
function viewIndexOfRaw(S, p) {
|
|
1925
|
+
let lo = 0;
|
|
1926
|
+
let hi = S.text.length;
|
|
1927
|
+
while (lo < hi) {
|
|
1928
|
+
const mid = (lo + hi) >> 1;
|
|
1929
|
+
if (S.rawStart(mid) < p)
|
|
1930
|
+
lo = mid + 1;
|
|
1931
|
+
else
|
|
1932
|
+
hi = mid;
|
|
1933
|
+
}
|
|
1934
|
+
while (lo < S.text.length && S.text.charAt(lo) === VIEW_SEPARATOR)
|
|
1935
|
+
lo++;
|
|
1936
|
+
return lo;
|
|
1937
|
+
}
|
|
1938
|
+
function dotsBeforeMarker(raw, p) {
|
|
1939
|
+
let k = p;
|
|
1940
|
+
while (raw.charCodeAt(k) === 0x2e)
|
|
1941
|
+
k++;
|
|
1942
|
+
if (k === p)
|
|
1943
|
+
return p;
|
|
1944
|
+
let m = k;
|
|
1945
|
+
while (m < k + 3 && (raw.charCodeAt(m) === 0x5c || raw.charCodeAt(m) === 0x22 || raw.charCodeAt(m) === 0x27))
|
|
1946
|
+
m++;
|
|
1947
|
+
if (raw.startsWith(REDACTION_MARKER_PREFIX, m) || /^\[[0-9;]{0,12}m\u00abredacted/.test(raw.slice(k, k + 24)))
|
|
1948
|
+
return k;
|
|
1949
|
+
return p;
|
|
1950
|
+
}
|
|
1951
|
+
function escapedBlankLen(raw, p) {
|
|
1952
|
+
if (raw.charCodeAt(p) !== 0x5c || raw.charCodeAt(p + 1) !== 0x75)
|
|
1953
|
+
return 0;
|
|
1954
|
+
const hex = raw.slice(p + 2, p + 6);
|
|
1955
|
+
return /^[0-9A-Fa-f]{4}$/.test(hex) && isRawBlank(Number.parseInt(hex, 16)) ? 6 : 0;
|
|
1956
|
+
}
|
|
1957
|
+
function dotsBeforeDash(raw, p) {
|
|
1958
|
+
let k = p;
|
|
1959
|
+
while (raw.charCodeAt(k) === 0x2e)
|
|
1960
|
+
k++;
|
|
1961
|
+
return k > p && raw.charCodeAt(k) === 0x2d ? k : p;
|
|
1962
|
+
}
|
|
1963
|
+
function dashEntryAt(scan, p, escaped) {
|
|
1964
|
+
const raw = scan.raw;
|
|
1965
|
+
if (raw.charCodeAt(p) !== 0x2d)
|
|
1966
|
+
return false;
|
|
1967
|
+
if (p + 1 >= raw.length)
|
|
1968
|
+
return true;
|
|
1969
|
+
return isRawBlank(raw.charCodeAt(p + 1)) || scan.view.rawUnit[p + 1] === 1 || blockBreakAt(raw, p + 1, escaped) > 0 || escapedBlankLen(raw, p + 1) > 0 || dotsBeforeMarker(raw, p + 1) !== p + 1;
|
|
1970
|
+
}
|
|
1971
|
+
function lineContentStart(scan, lines, i, skipDots = true) {
|
|
1972
|
+
const raw = scan.raw;
|
|
1973
|
+
const unit = scan.view.rawUnit;
|
|
1974
|
+
const { seq, payload } = blockMarks(scan);
|
|
1975
|
+
const end = lines.ends[i] ?? raw.length;
|
|
1976
|
+
let k = lines.starts[i] ?? 0;
|
|
1977
|
+
while (k < end) {
|
|
1978
|
+
if (payload[k] === 1)
|
|
1979
|
+
break;
|
|
1980
|
+
if (seq[k] === 1 || isRawBlank(raw.charCodeAt(k)) || unit[k] === 1)
|
|
1981
|
+
k++;
|
|
1982
|
+
else if (escapedBlankLen(raw, k) > 0)
|
|
1983
|
+
k += 6;
|
|
1984
|
+
else
|
|
1985
|
+
break;
|
|
1986
|
+
}
|
|
1987
|
+
return skipDots && k < end ? dotsBeforeDash(raw, k) : k;
|
|
1988
|
+
}
|
|
1989
|
+
function seqLineIndent(scan, lines, i) {
|
|
1990
|
+
const base = lines.indent[i] ?? -1;
|
|
1991
|
+
if (base < 0)
|
|
1992
|
+
return base;
|
|
1993
|
+
const raw = scan.raw;
|
|
1994
|
+
const unit = scan.view.rawUnit;
|
|
1995
|
+
const { seq, payload } = blockMarks(scan);
|
|
1996
|
+
const end = lines.ends[i] ?? raw.length;
|
|
1997
|
+
let k = lines.starts[i] ?? 0;
|
|
1998
|
+
let width = 0;
|
|
1999
|
+
while (k < end) {
|
|
2000
|
+
if (payload[k] === 1)
|
|
2001
|
+
break;
|
|
2002
|
+
if (escapedBlankLen(raw, k) > 0) {
|
|
2003
|
+
width++;
|
|
2004
|
+
k += 6;
|
|
2005
|
+
}
|
|
2006
|
+
else if (seq[k] === 1)
|
|
2007
|
+
k++;
|
|
2008
|
+
else if (isRawBlank(raw.charCodeAt(k))) {
|
|
2009
|
+
width++;
|
|
2010
|
+
k++;
|
|
2011
|
+
}
|
|
2012
|
+
else if (unit[k] === 1)
|
|
2013
|
+
k++;
|
|
2014
|
+
else
|
|
2015
|
+
break;
|
|
2016
|
+
}
|
|
2017
|
+
if (k < end) {
|
|
2018
|
+
const d = dotsBeforeDash(raw, k);
|
|
2019
|
+
width += d - k;
|
|
2020
|
+
}
|
|
2021
|
+
return width;
|
|
2022
|
+
}
|
|
2023
|
+
function blockSeqEntries(scan, rawFrom, rawLabel) {
|
|
2024
|
+
const raw = scan.raw;
|
|
2025
|
+
const unit = scan.view.rawUnit;
|
|
2026
|
+
let p = dotsBeforeDash(raw, rawFrom);
|
|
2027
|
+
let escaped = false;
|
|
2028
|
+
if (raw.charCodeAt(p) === 0x5c && lineBreakLengthAt(raw, p) > 0) {
|
|
2029
|
+
escaped = true;
|
|
2030
|
+
for (;;) {
|
|
2031
|
+
const n = lineBreakLengthAt(raw, p);
|
|
2032
|
+
if (n === 0 || raw.charCodeAt(p) !== 0x5c)
|
|
2033
|
+
break;
|
|
2034
|
+
p += n;
|
|
2035
|
+
while (p < raw.length && (isRawBlank(raw.charCodeAt(p)) || unit[p] === 1 || escapedBlankLen(raw, p) > 0)) {
|
|
2036
|
+
const n = escapedBlankLen(raw, p);
|
|
2037
|
+
p += n > 0 ? n : 1;
|
|
2038
|
+
}
|
|
2039
|
+
p = dotsBeforeDash(raw, p);
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
if (!dashEntryAt(scan, p, escaped))
|
|
2043
|
+
return null;
|
|
2044
|
+
const lines = blockLines(scan, escaped);
|
|
2045
|
+
const first = blockLineOf(lines, p);
|
|
2046
|
+
const labelLine = blockLineOf(lines, rawLabel);
|
|
2047
|
+
const labelIndent = Math.max(0, lines.indent[labelLine] ?? 0);
|
|
2048
|
+
const entryIndent = seqLineIndent(scan, lines, first);
|
|
2049
|
+
const labelHead = lineContentStart(scan, lines, labelLine, false);
|
|
2050
|
+
const labelFirst = rawLabel >= labelHead && !/\s/.test(raw.slice(labelHead, rawLabel));
|
|
2051
|
+
if (lineContentStart(scan, lines, first) !== p || entryIndent < 0 || (labelFirst ? entryIndent < labelIndent : entryIndent <= labelIndent))
|
|
2052
|
+
return null;
|
|
2053
|
+
const out = [];
|
|
2054
|
+
const work = [first];
|
|
2055
|
+
const total = lines.starts.length;
|
|
2056
|
+
while (work.length > 0) {
|
|
2057
|
+
let i = work.pop() ?? total;
|
|
2058
|
+
const ind = seqLineIndent(scan, lines, i);
|
|
2059
|
+
while (i < total) {
|
|
2060
|
+
const dash = lineContentStart(scan, lines, i);
|
|
2061
|
+
const end = lines.ends[i] ?? raw.length;
|
|
2062
|
+
let v = dash + 1;
|
|
2063
|
+
while (v < end && (isRawBlank(raw.charCodeAt(v)) || unit[v] === 1 || escapedBlankLen(raw, v) > 0)) {
|
|
2064
|
+
const n = escapedBlankLen(raw, v);
|
|
2065
|
+
v += n > 0 ? n : 1;
|
|
2066
|
+
}
|
|
2067
|
+
v = dotsBeforeMarker(raw, v);
|
|
2068
|
+
if (v < end) {
|
|
2069
|
+
let whole = -1;
|
|
2070
|
+
if (dashEntryAt(scan, v, escaped)) {
|
|
2071
|
+
let last = (lines.outOf[i] ?? total) - 1;
|
|
2072
|
+
while (last > i && (lines.indent[last] ?? -1) === -1)
|
|
2073
|
+
last--;
|
|
2074
|
+
whole = lines.ends[last] ?? end;
|
|
2075
|
+
}
|
|
2076
|
+
out.push({ dash, value: v, whole });
|
|
2077
|
+
}
|
|
2078
|
+
else {
|
|
2079
|
+
const k = lines.nextContent[i + 1] ?? total;
|
|
2080
|
+
if (k < total && seqLineIndent(scan, lines, k) > ind) {
|
|
2081
|
+
const kp = lineContentStart(scan, lines, k);
|
|
2082
|
+
if (dashEntryAt(scan, kp, escaped)) {
|
|
2083
|
+
out.push({ dash, value: -1, whole: -1 });
|
|
2084
|
+
work.push(k);
|
|
2085
|
+
}
|
|
2086
|
+
else
|
|
2087
|
+
out.push({ dash, value: kp, whole: -1 });
|
|
2088
|
+
}
|
|
2089
|
+
else
|
|
2090
|
+
out.push({ dash, value: -1, whole: -1 });
|
|
2091
|
+
}
|
|
2092
|
+
const j = lines.outOf[i] ?? total;
|
|
2093
|
+
if (j >= total || seqLineIndent(scan, lines, j) !== ind || !dashEntryAt(scan, lineContentStart(scan, lines, j), escaped))
|
|
2094
|
+
break;
|
|
2095
|
+
i = j;
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
return out;
|
|
2099
|
+
}
|
|
1477
2100
|
function labelCandidates(S, pass, regions, out, blocks) {
|
|
1478
2101
|
const text = S.text;
|
|
1479
2102
|
const unitAt = (k) => S.unitAt(k);
|
|
1480
2103
|
const re = pass === 'label' ? SECRET_LABELLED_WORD : SECRET_SCHEME_WORD;
|
|
1481
2104
|
const schemePass = pass !== 'label';
|
|
1482
2105
|
const tokenPass = pass === 'token';
|
|
1483
|
-
const
|
|
2106
|
+
const rawUnitMap = blocks?.view.rawUnit ?? null;
|
|
2107
|
+
const plainAt = (k) => isPlainAt(S, rawUnitMap, k);
|
|
2108
|
+
const idx = new InnerWordIndex(text, tokenPass, plainAt);
|
|
2109
|
+
let listIdx = null;
|
|
2110
|
+
const listIndex = () => (listIdx ??= new InnerWordIndex(text, idx.tokenInner, plainAt));
|
|
2111
|
+
let skipFrom = -1;
|
|
2112
|
+
let skipTo = -1;
|
|
2113
|
+
const flowBudget = { left: 4 * text.length + 4096, pairs: null };
|
|
1484
2114
|
const extensionCache = new Map();
|
|
1485
2115
|
let stops;
|
|
1486
2116
|
const push = (start, end, kindText, te = -1, cls) => {
|
|
@@ -1603,6 +2233,88 @@ function labelCandidates(S, pass, regions, out, blocks) {
|
|
|
1603
2233
|
r0++;
|
|
1604
2234
|
maskGaps(r0, outerEnd);
|
|
1605
2235
|
};
|
|
2236
|
+
const itemNeutral = (a, b) => {
|
|
2237
|
+
const rawItem = text.slice(a, b);
|
|
2238
|
+
const item = withoutSeparators(rawItem).trim();
|
|
2239
|
+
if (item === '')
|
|
2240
|
+
return true;
|
|
2241
|
+
return valueIsWholeMarker(S, a, b, idx.tokenInner) || MARKER_WITH_DOTS.test(item) || isDiagnosticValue(item, rawItem) || LIST_NEUTRAL_ITEM.test(item);
|
|
2242
|
+
};
|
|
2243
|
+
const flowListLike = (label, items) => {
|
|
2244
|
+
if (/s$/i.test(label) || items.length !== 1)
|
|
2245
|
+
return true;
|
|
2246
|
+
const only = items[0];
|
|
2247
|
+
return only === undefined || only.quoted === true || !/\s/.test(withoutSeparators(text.slice(only.start, only.end)).trim());
|
|
2248
|
+
};
|
|
2249
|
+
const listMask = (label, spans, valueLike) => {
|
|
2250
|
+
const neutral = spans.map((s) => itemNeutral(s.start, s.end));
|
|
2251
|
+
const names = !valueLike && spans.every((s, i) => neutral[i] === true || isNamedNotValue(label, withoutSeparators(text.slice(s.start, s.end)).trim()));
|
|
2252
|
+
return spans.map((_, i) => !names && neutral[i] !== true);
|
|
2253
|
+
};
|
|
2254
|
+
const seqItems = (scan, ents, label) => {
|
|
2255
|
+
const li = listIndex();
|
|
2256
|
+
const spans = [];
|
|
2257
|
+
let valueLike = false;
|
|
2258
|
+
for (const e of ents) {
|
|
2259
|
+
if (e.value < 0)
|
|
2260
|
+
continue;
|
|
2261
|
+
if (e.whole >= 0) {
|
|
2262
|
+
scan.out.push({ start: e.value, end: e.whole, kind: 'secret', cls: 'word', tokenEnd: e.whole, pretrimmed: true });
|
|
2263
|
+
valueLike = true;
|
|
2264
|
+
continue;
|
|
2265
|
+
}
|
|
2266
|
+
let vi = viewIndexOfRaw(S, e.value);
|
|
2267
|
+
if (vi >= text.length)
|
|
2268
|
+
continue;
|
|
2269
|
+
const pr = nodeProperties(text, vi);
|
|
2270
|
+
if (pr !== null && hasValueAt(text, pr.next) && propertiesSameLine(S, pr)) {
|
|
2271
|
+
push(pr.start, pr.end, REDACTED_SECRET);
|
|
2272
|
+
vi = pr.next;
|
|
2273
|
+
}
|
|
2274
|
+
const c = text.charAt(vi);
|
|
2275
|
+
if (c === '|' || c === '>') {
|
|
2276
|
+
const blk = blockScalarExtent(scan, S.rawStart(vi), e.dash);
|
|
2277
|
+
if (blk !== null) {
|
|
2278
|
+
scan.out.push({ start: blk.start, end: blk.end, kind: 'secret', cls: 'word', tokenEnd: blk.end, pretrimmed: true });
|
|
2279
|
+
valueLike = true;
|
|
2280
|
+
continue;
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
if (c === '[') {
|
|
2284
|
+
const fl = flowListItems(text, vi, li, flowBudget);
|
|
2285
|
+
if (fl !== null && flowListLike(label, fl.items)) {
|
|
2286
|
+
for (const it of fl.items)
|
|
2287
|
+
spans.push(it);
|
|
2288
|
+
continue;
|
|
2289
|
+
}
|
|
2290
|
+
}
|
|
2291
|
+
if (c === '{') {
|
|
2292
|
+
const close = matchBrace(text, vi);
|
|
2293
|
+
if (close > vi + 1)
|
|
2294
|
+
spans.push({ start: vi + 1, end: close });
|
|
2295
|
+
continue;
|
|
2296
|
+
}
|
|
2297
|
+
if (c === '*')
|
|
2298
|
+
continue;
|
|
2299
|
+
let q = vi;
|
|
2300
|
+
while (text.charCodeAt(q) === 0x5c)
|
|
2301
|
+
q++;
|
|
2302
|
+
const quotedItem = isQuoteChar(text.charAt(q));
|
|
2303
|
+
const v = scanListItem(S, vi, li);
|
|
2304
|
+
if (v === null)
|
|
2305
|
+
continue;
|
|
2306
|
+
const keyAt = quotedItem ? afterClosingQuote(text, v.end) : v.end - 1;
|
|
2307
|
+
const keyNext = text.charAt(keyAt + 1);
|
|
2308
|
+
if (text.charAt(keyAt) === ':' && (keyAt + 1 >= text.length || isAnyBlank(keyNext) || keyNext === '\n' || keyNext === '\r'))
|
|
2309
|
+
continue;
|
|
2310
|
+
spans.push(v);
|
|
2311
|
+
}
|
|
2312
|
+
const flags = listMask(label, spans, valueLike);
|
|
2313
|
+
spans.forEach((s, i) => {
|
|
2314
|
+
if (flags[i] === true)
|
|
2315
|
+
push(s.start, s.end, REDACTED_SECRET);
|
|
2316
|
+
});
|
|
2317
|
+
};
|
|
1606
2318
|
const regionKind = regions.length === 0 ? null : new Uint8Array(text.length);
|
|
1607
2319
|
if (regionKind !== null)
|
|
1608
2320
|
for (const r of regions)
|
|
@@ -1632,8 +2344,10 @@ function labelCandidates(S, pass, regions, out, blocks) {
|
|
|
1632
2344
|
return a;
|
|
1633
2345
|
};
|
|
1634
2346
|
re.lastIndex = 0;
|
|
1635
|
-
for (let hit = re.exec(text); hit !== null; hit = re.exec(text)) {
|
|
2347
|
+
hits: for (let hit = re.exec(text); hit !== null; hit = re.exec(text)) {
|
|
1636
2348
|
const label = hit[1] ?? '';
|
|
2349
|
+
if (hit.index >= skipFrom && hit.index < skipTo)
|
|
2350
|
+
continue;
|
|
1637
2351
|
if (schemePass && (label.toLowerCase() === 'token') !== tokenPass)
|
|
1638
2352
|
continue;
|
|
1639
2353
|
if (isTokenCountLabel(text, hit.index, label))
|
|
@@ -1642,18 +2356,89 @@ function labelCandidates(S, pass, regions, out, blocks) {
|
|
|
1642
2356
|
continue;
|
|
1643
2357
|
if (schemePass && labelStartsAt(text, hit.index))
|
|
1644
2358
|
continue;
|
|
1645
|
-
|
|
1646
|
-
if (
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
2359
|
+
let from = hit.index + hit[0].length;
|
|
2360
|
+
if (!schemePass && text.charCodeAt(from) === 0x3e && text.charCodeAt(from - 1) === 0x3d && labelQuotedAt(text, hit.index, hit[0].slice(label.length))) {
|
|
2361
|
+
let k = from + 1;
|
|
2362
|
+
while (k < text.length && isInlineBlank(text.charAt(k)))
|
|
2363
|
+
k++;
|
|
2364
|
+
let q = k;
|
|
2365
|
+
while (text.charCodeAt(q) === 0x5c)
|
|
2366
|
+
q++;
|
|
2367
|
+
if (isQuoteChar(text.charAt(q)))
|
|
2368
|
+
from = k;
|
|
2369
|
+
}
|
|
2370
|
+
const colonSep = isColonSeparator(hit[0].slice((hit[1] ?? '').length));
|
|
2371
|
+
let bulletSkipped = false;
|
|
2372
|
+
for (;;) {
|
|
2373
|
+
if (colonSep) {
|
|
2374
|
+
const pr = nodeProperties(text, from);
|
|
2375
|
+
if (pr !== null && hasValueAt(text, pr.next) && propertiesSameLine(S, pr) && !credentialWordStartsAt(text, pr.next, idx.tokenInner)) {
|
|
2376
|
+
push(pr.start, pr.end, REDACTED_SECRET);
|
|
2377
|
+
from = pr.next;
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
if (blocks !== undefined && (text.charCodeAt(from) === 0x7c || text.charCodeAt(from) === 0x3e) && colonSep) {
|
|
2381
|
+
const blk = blockScalarExtent(blocks, S.rawStart(from), S.rawStart(hit.index));
|
|
2382
|
+
if (blk !== null)
|
|
2383
|
+
blocks.out.push({ start: blk.start, end: blk.end, kind: 'secret', cls: 'word', tokenEnd: blk.end, pretrimmed: true });
|
|
2384
|
+
}
|
|
2385
|
+
if (credentialWordStartsAt(text, from, idx.tokenInner)) {
|
|
2386
|
+
pushInnerRemainder(from);
|
|
2387
|
+
re.lastIndex = from;
|
|
2388
|
+
continue hits;
|
|
2389
|
+
}
|
|
2390
|
+
if (!schemePass && text.charAt(from) === '[') {
|
|
2391
|
+
const fl = flowListItems(text, from, listIndex(), flowBudget);
|
|
2392
|
+
if (fl !== null && flowListLike(label, fl.items)) {
|
|
2393
|
+
const flags = listMask(label, fl.items, false);
|
|
2394
|
+
fl.items.forEach((s, i) => {
|
|
2395
|
+
if (flags[i] === true)
|
|
2396
|
+
push(s.start, s.end, REDACTED_SECRET);
|
|
2397
|
+
});
|
|
2398
|
+
re.lastIndex = Math.max(fl.end, from);
|
|
2399
|
+
continue hits;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
if (!schemePass && colonSep && blocks !== undefined && (text.charAt(from) === '-' || text.charAt(from) === '\\' || text.charAt(from) === '.')) {
|
|
2403
|
+
const ents = blockSeqEntries(blocks, S.rawStart(from), S.rawStart(hit.index));
|
|
2404
|
+
if (ents !== null) {
|
|
2405
|
+
seqItems(blocks, ents, label);
|
|
2406
|
+
re.lastIndex = from;
|
|
2407
|
+
continue hits;
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
if (!(colonSep && text.charAt(from) === '-' && from + 1 < text.length))
|
|
2411
|
+
break;
|
|
2412
|
+
const afterDots = dotsBeforeMarker(text, from + 1);
|
|
2413
|
+
if (!(isInlineBlank(text.charAt(from + 1)) || S.gapAfter(from) || afterDots !== from + 1))
|
|
2414
|
+
break;
|
|
2415
|
+
let b = afterDots;
|
|
2416
|
+
while (b < text.length && isInlineBlank(text.charAt(b)))
|
|
2417
|
+
b++;
|
|
2418
|
+
if (b >= text.length || isAnyBlank(text.charAt(b)))
|
|
2419
|
+
break;
|
|
2420
|
+
from = b;
|
|
2421
|
+
bulletSkipped = true;
|
|
2422
|
+
}
|
|
2423
|
+
if (bulletSkipped) {
|
|
2424
|
+
const first = scanListItem(S, from, listIndex());
|
|
2425
|
+
const j = first === null ? from : first.end;
|
|
2426
|
+
if (j > from + 1 && text.charAt(j - 1) === ':' && (j >= text.length || isAnyBlank(text.charAt(j)))) {
|
|
2427
|
+
re.lastIndex = from;
|
|
2428
|
+
continue;
|
|
2429
|
+
}
|
|
1655
2430
|
}
|
|
1656
2431
|
let v0s = scanSecretValue(text, from, idx);
|
|
2432
|
+
let wrapEnd = -1;
|
|
2433
|
+
if (v0s === null) {
|
|
2434
|
+
const w = wrappedValueAt(text, from, idx);
|
|
2435
|
+
if (w !== null) {
|
|
2436
|
+
if (WRAPPED_PLACEHOLDER.test(withoutSeparators(text.slice(w.start, w.end))))
|
|
2437
|
+
continue;
|
|
2438
|
+
v0s = w;
|
|
2439
|
+
wrapEnd = w.end;
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
1657
2442
|
if (v0s === null) {
|
|
1658
2443
|
let k = from;
|
|
1659
2444
|
while (k < text.length && text[k] === VIEW_SEPARATOR)
|
|
@@ -1702,6 +2487,23 @@ function labelCandidates(S, pass, regions, out, blocks) {
|
|
|
1702
2487
|
continue;
|
|
1703
2488
|
}
|
|
1704
2489
|
}
|
|
2490
|
+
let forceFirstMask = false;
|
|
2491
|
+
if (!schemePass && /s$/i.test(label) && !inQuery(v.start)) {
|
|
2492
|
+
const afterFirst = quoted ? afterClosingQuote(text, v0.end) : v0.end;
|
|
2493
|
+
const tail = commaListTail(S, afterFirst, listIndex());
|
|
2494
|
+
if (tail.items.length > 0) {
|
|
2495
|
+
const spans = [{ start: v.start, end: v.end }, ...tail.items];
|
|
2496
|
+
const flags = listMask(label, spans, false);
|
|
2497
|
+
for (let i = 1; i < spans.length; i++) {
|
|
2498
|
+
const s = spans[i];
|
|
2499
|
+
if (s !== undefined && flags[i] === true)
|
|
2500
|
+
push(s.start, s.end, REDACTED_SECRET);
|
|
2501
|
+
}
|
|
2502
|
+
forceFirstMask = flags[0] === true;
|
|
2503
|
+
skipFrom = afterFirst;
|
|
2504
|
+
skipTo = tail.end;
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
1705
2507
|
if (valueIsWholeMarker(S, v.start, v.end, idx.tokenInner)) {
|
|
1706
2508
|
re.lastIndex = quoted ? from : v.end;
|
|
1707
2509
|
continue;
|
|
@@ -1733,6 +2535,13 @@ function labelCandidates(S, pass, regions, out, blocks) {
|
|
|
1733
2535
|
if (a !== -1)
|
|
1734
2536
|
v.end = a;
|
|
1735
2537
|
}
|
|
2538
|
+
if (wrapEnd !== -1 && v.end > wrapEnd)
|
|
2539
|
+
v.end = wrapEnd;
|
|
2540
|
+
if (!schemePass && !quoted && wrapEnd === -1 && !inQuery(v.start) && !/authorizations?$/i.test(label)) {
|
|
2541
|
+
const ext = tokenSchemeValueEnd(text, v.start, v.end, idx);
|
|
2542
|
+
if (ext > v.end)
|
|
2543
|
+
v.end = ext;
|
|
2544
|
+
}
|
|
1736
2545
|
if (!quoted) {
|
|
1737
2546
|
const trailing = trailingLabelStart(text, v.start, v.end, idx.tokenInner);
|
|
1738
2547
|
if (trailing > 0 && innerWordHasValue(text, v.start + trailing, idx)) {
|
|
@@ -1757,7 +2566,7 @@ function labelCandidates(S, pass, regions, out, blocks) {
|
|
|
1757
2566
|
re.lastIndex = v.end;
|
|
1758
2567
|
continue;
|
|
1759
2568
|
}
|
|
1760
|
-
if (!schemePass && isNamedNotValue(label, value)) {
|
|
2569
|
+
if (!schemePass && !forceFirstMask && isNamedNotValue(label, value)) {
|
|
1761
2570
|
re.lastIndex = v.end;
|
|
1762
2571
|
continue;
|
|
1763
2572
|
}
|
|
@@ -1795,6 +2604,11 @@ function labelCandidates(S, pass, regions, out, blocks) {
|
|
|
1795
2604
|
const trailing = trailingLabelStart(text, v.start, end, idx.tokenInner);
|
|
1796
2605
|
if (trailing !== -1)
|
|
1797
2606
|
end = v.start + trailing;
|
|
2607
|
+
if (schemePass && schemeIsLabelValue(text, hit.index)) {
|
|
2608
|
+
push(v.start, Math.max(end, v.end), REDACTED_SECRET);
|
|
2609
|
+
re.lastIndex = quoted ? from : Math.max(end, v.end);
|
|
2610
|
+
continue;
|
|
2611
|
+
}
|
|
1798
2612
|
if (gluedToSingleUnit(v.start, hit.index, unitAt) || userinfoHostHidden(text, v.start, unitAt)) {
|
|
1799
2613
|
const cut = trailing !== -1 ? end : Math.max(end, v.end);
|
|
1800
2614
|
const schemeHit = ADDRESS_SCHEME_RE.exec(text.slice(v.start, v.start + 20))?.[0] ?? '';
|
|
@@ -1866,8 +2680,20 @@ function longestAlnumRun(word) {
|
|
|
1866
2680
|
return best;
|
|
1867
2681
|
}
|
|
1868
2682
|
const JWT_WORD = /^eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{4,}$/;
|
|
1869
|
-
const PEM_BEGIN_SOURCE =
|
|
2683
|
+
const PEM_BEGIN_SOURCE = `${PRIVATE_KEY_PEM_HEADER.source}(?: BLOCK)?-----`;
|
|
2684
|
+
const PEM_CASE_FLAGS = PRIVATE_KEY_PEM_HEADER.flags.includes('i') ? 'i' : '';
|
|
2685
|
+
const PEM_LEAD = '-----BEGIN';
|
|
1870
2686
|
const PEM_END_MARK = '-----END';
|
|
2687
|
+
function pemEndIndex(text, from) {
|
|
2688
|
+
const re = new RegExp(PEM_END_MARK, `g${PEM_CASE_FLAGS}`);
|
|
2689
|
+
re.lastIndex = from;
|
|
2690
|
+
const m = re.exec(text);
|
|
2691
|
+
return m === null ? -1 : m.index;
|
|
2692
|
+
}
|
|
2693
|
+
function pemLeadAt(s, at) {
|
|
2694
|
+
const seg = s.slice(at, at + PEM_LEAD.length);
|
|
2695
|
+
return PEM_CASE_FLAGS === 'i' ? seg.toUpperCase() === PEM_LEAD : seg === PEM_LEAD;
|
|
2696
|
+
}
|
|
1871
2697
|
function lineBreakLengthAt(text, at) {
|
|
1872
2698
|
if (text.startsWith('\r\n', at))
|
|
1873
2699
|
return 2;
|
|
@@ -1971,7 +2797,18 @@ function blockLines(scan, escaped) {
|
|
|
1971
2797
|
nextContent[starts.length] = starts.length;
|
|
1972
2798
|
for (let i = starts.length - 1; i >= 0; i--)
|
|
1973
2799
|
nextContent[i] = (indent[i] ?? -1) !== -1 ? i : (nextContent[i + 1] ?? starts.length);
|
|
1974
|
-
const
|
|
2800
|
+
const outOf = new Int32Array(starts.length + 1).fill(starts.length);
|
|
2801
|
+
const stack = [];
|
|
2802
|
+
for (let i = starts.length - 1; i >= 0; i--) {
|
|
2803
|
+
const ind = indent[i] ?? -1;
|
|
2804
|
+
if (ind === -1)
|
|
2805
|
+
continue;
|
|
2806
|
+
while (stack.length > 0 && (indent[stack[stack.length - 1] ?? 0] ?? -1) > ind)
|
|
2807
|
+
stack.pop();
|
|
2808
|
+
outOf[i] = stack.length > 0 ? (stack[stack.length - 1] ?? starts.length) : starts.length;
|
|
2809
|
+
stack.push(i);
|
|
2810
|
+
}
|
|
2811
|
+
const built = { starts, ends, indent, nextContent, outOf, memo: new Map() };
|
|
1975
2812
|
scan.lines[slot] = built;
|
|
1976
2813
|
return built;
|
|
1977
2814
|
}
|
|
@@ -2068,11 +2905,11 @@ function pemBodyEndWithoutTrailer(text, from) {
|
|
|
2068
2905
|
}
|
|
2069
2906
|
function pemBlocks(text, soft = () => false) {
|
|
2070
2907
|
const out = [];
|
|
2071
|
-
if (!text.includes(
|
|
2908
|
+
if (!(PEM_CASE_FLAGS === 'i' ? text.toUpperCase().includes(PEM_LEAD) : text.includes(PEM_LEAD)))
|
|
2072
2909
|
return out;
|
|
2073
2910
|
const head = pemHeadView(text, soft);
|
|
2074
|
-
const begin = new RegExp(PEM_BEGIN_SOURCE,
|
|
2075
|
-
const trailer =
|
|
2911
|
+
const begin = new RegExp(PEM_BEGIN_SOURCE, `g${PEM_CASE_FLAGS}`);
|
|
2912
|
+
const trailer = new RegExp(`${PEM_END_MARK}[A-Z0-9 ]*-----`, `y${PEM_CASE_FLAGS}`);
|
|
2076
2913
|
let nextEnd = -2;
|
|
2077
2914
|
for (let b = begin.exec(head); b !== null; b = begin.exec(head)) {
|
|
2078
2915
|
let bodyStart = b.index + b[0].length;
|
|
@@ -2083,7 +2920,7 @@ function pemBlocks(text, soft = () => false) {
|
|
|
2083
2920
|
while (bodyStart < text.length && (text[bodyStart] === ' ' || text[bodyStart] === '\t'))
|
|
2084
2921
|
bodyStart++;
|
|
2085
2922
|
if (nextEnd !== -1 && nextEnd < bodyStart)
|
|
2086
|
-
nextEnd = text
|
|
2923
|
+
nextEnd = pemEndIndex(text, bodyStart);
|
|
2087
2924
|
let bodyEnd;
|
|
2088
2925
|
let regionEnd;
|
|
2089
2926
|
if (nextEnd === -1) {
|
|
@@ -2114,8 +2951,8 @@ function pemHeadView(text, soft) {
|
|
|
2114
2951
|
return chars === null ? text : chars.join('');
|
|
2115
2952
|
}
|
|
2116
2953
|
function pemBeginAt(S, at) {
|
|
2117
|
-
const k = at +
|
|
2118
|
-
return S.text
|
|
2954
|
+
const k = at + PEM_LEAD.length;
|
|
2955
|
+
return pemLeadAt(S.text, at) && (S.text[k] === ' ' || (k < S.text.length && pemSoft(S, k)));
|
|
2119
2956
|
}
|
|
2120
2957
|
const pemSoft = (S, k) => S.dropped(k) || S.painted(k);
|
|
2121
2958
|
function pemBlockToRaw(S, blk) {
|
|
@@ -2169,6 +3006,90 @@ function authParamEdits(text) {
|
|
|
2169
3006
|
}
|
|
2170
3007
|
return edits;
|
|
2171
3008
|
}
|
|
3009
|
+
const LITERAL_PROBE_WINDOW = 64;
|
|
3010
|
+
function gluedLiteralStart(word) {
|
|
3011
|
+
const n = word.length;
|
|
3012
|
+
if (n < PROSE_LITERAL_MIN_RUN + 2)
|
|
3013
|
+
return 0;
|
|
3014
|
+
const runFrom = new Int32Array(n + 1);
|
|
3015
|
+
let best = 0;
|
|
3016
|
+
let run = 0;
|
|
3017
|
+
for (let k = n - 1; k >= 0; k--) {
|
|
3018
|
+
if (isAlnumCode(word.charCodeAt(k))) {
|
|
3019
|
+
run++;
|
|
3020
|
+
if (run > best)
|
|
3021
|
+
best = run;
|
|
3022
|
+
}
|
|
3023
|
+
else
|
|
3024
|
+
run = 0;
|
|
3025
|
+
runFrom[k] = best;
|
|
3026
|
+
}
|
|
3027
|
+
for (let k = 1; k < n; k++) {
|
|
3028
|
+
const left = word.charCodeAt(k - 1);
|
|
3029
|
+
if ((left !== 0x5f && left !== 0x2d) || !isAlnumCode(word.charCodeAt(k)))
|
|
3030
|
+
continue;
|
|
3031
|
+
if ((runFrom[k] ?? 0) < PROSE_LITERAL_MIN_RUN)
|
|
3032
|
+
return 0;
|
|
3033
|
+
if (SECRET_LITERAL_RE.test(word.slice(k, k + LITERAL_PROBE_WINDOW)))
|
|
3034
|
+
return k;
|
|
3035
|
+
}
|
|
3036
|
+
return 0;
|
|
3037
|
+
}
|
|
3038
|
+
const OPAQUE_MIN_LENGTH = 24;
|
|
3039
|
+
const OPAQUE_MIN_ENTROPY = 3.5;
|
|
3040
|
+
const OPAQUE_MAX_AVG_SEGMENT = 2.5;
|
|
3041
|
+
const BASE64_FILE_SIGNATURES = ['iVBORw0KGgo', 'R0lGOD', 'UklGR', 'JVBERi0', 'UEsDB', 'H4sI', 'PHN2Zy', 'PD94bWwg', 'AAABAA'];
|
|
3042
|
+
const NON_SECRET_ID_PREFIXES = new Set(['toolu', 'srvtoolu', 'msg', 'msgbatch', 'req', 'file', 'chatcmpl', 'call', 'resp']);
|
|
3043
|
+
function isOpaqueWord(text, i, end) {
|
|
3044
|
+
if (end - i < OPAQUE_MIN_LENGTH)
|
|
3045
|
+
return false;
|
|
3046
|
+
const prev = text.charAt(i - 1);
|
|
3047
|
+
const next = text.charAt(end);
|
|
3048
|
+
if (prev === '+' || prev === '@' || next === '+' || next === '/' || next === '=' || next === '@')
|
|
3049
|
+
return false;
|
|
3050
|
+
if (next === '.' && isKeyWordChar(text.charCodeAt(end + 1)))
|
|
3051
|
+
return false;
|
|
3052
|
+
if (text.slice(Math.max(0, i - 7), i).toLowerCase() === 'base64,')
|
|
3053
|
+
return false;
|
|
3054
|
+
const word = text.slice(i, end);
|
|
3055
|
+
if (/^[0-9A-Fa-f_-]+$/.test(word) || /^sha(?:1|256|384|512)-/i.test(word))
|
|
3056
|
+
return false;
|
|
3057
|
+
if (BASE64_FILE_SIGNATURES.some((sig) => word.startsWith(sig)))
|
|
3058
|
+
return false;
|
|
3059
|
+
const typed = /^([a-z]+)[_-]/.exec(word);
|
|
3060
|
+
if (typed !== null && NON_SECRET_ID_PREFIXES.has(typed[1] ?? ''))
|
|
3061
|
+
return false;
|
|
3062
|
+
let upper = false;
|
|
3063
|
+
let lower = false;
|
|
3064
|
+
let digit = false;
|
|
3065
|
+
const counts = new Map();
|
|
3066
|
+
for (let k = 0; k < word.length; k++) {
|
|
3067
|
+
const c = word.charCodeAt(k);
|
|
3068
|
+
if (c >= 0x41 && c <= 0x5a)
|
|
3069
|
+
upper = true;
|
|
3070
|
+
else if (c >= 0x61 && c <= 0x7a)
|
|
3071
|
+
lower = true;
|
|
3072
|
+
else if (c >= 0x30 && c <= 0x39)
|
|
3073
|
+
digit = true;
|
|
3074
|
+
counts.set(c, (counts.get(c) ?? 0) + 1);
|
|
3075
|
+
}
|
|
3076
|
+
if (!upper || !lower || !digit)
|
|
3077
|
+
return false;
|
|
3078
|
+
let entropy = 0;
|
|
3079
|
+
for (const n of counts.values()) {
|
|
3080
|
+
const p = n / word.length;
|
|
3081
|
+
entropy -= p * Math.log2(p);
|
|
3082
|
+
}
|
|
3083
|
+
if (entropy < OPAQUE_MIN_ENTROPY)
|
|
3084
|
+
return false;
|
|
3085
|
+
let segments = 0;
|
|
3086
|
+
let segmentChars = 0;
|
|
3087
|
+
for (const m of word.matchAll(/[A-Z]?[a-z]+|[A-Z]+(?![a-z])|[0-9]+/g)) {
|
|
3088
|
+
segments++;
|
|
3089
|
+
segmentChars += m[0].length;
|
|
3090
|
+
}
|
|
3091
|
+
return segments > 0 && segmentChars / segments <= OPAQUE_MAX_AVG_SEGMENT;
|
|
3092
|
+
}
|
|
2172
3093
|
function proseLiteralEdits(text) {
|
|
2173
3094
|
const edits = [];
|
|
2174
3095
|
let i = 0;
|
|
@@ -2203,6 +3124,13 @@ function proseLiteralEdits(text) {
|
|
|
2203
3124
|
if (!pathish && SECRET_LITERAL_RE.test(word) && longestAlnumRun(word) >= PROSE_LITERAL_MIN_RUN) {
|
|
2204
3125
|
pushEdit(edits, text, i, end, REDACTED_SECRET);
|
|
2205
3126
|
}
|
|
3127
|
+
else if (!pathish) {
|
|
3128
|
+
const glued = gluedLiteralStart(word);
|
|
3129
|
+
if (glued > 0)
|
|
3130
|
+
pushEdit(edits, text, i + glued, end, REDACTED_SECRET);
|
|
3131
|
+
else if (!hostSlot && isOpaqueWord(text, i, end))
|
|
3132
|
+
pushEdit(edits, text, i, end, REDACTED_SECRET);
|
|
3133
|
+
}
|
|
2206
3134
|
i = end;
|
|
2207
3135
|
}
|
|
2208
3136
|
return edits;
|
|
@@ -3451,6 +4379,10 @@ export function displayUntrusted(text, opts = {}) {
|
|
|
3451
4379
|
const out = renderUntrusted(text, opts, null);
|
|
3452
4380
|
return typeof out === 'string' ? out : out.text;
|
|
3453
4381
|
}
|
|
4382
|
+
export function quoteUntrustedForSentence(text, max) {
|
|
4383
|
+
const shown = displayUntrusted(text, { max, blanks: true, escapeBackslashes: true });
|
|
4384
|
+
return shown.trim() === '' ? undefined : `"${shown.replace(/"/g, '\\"')}"`;
|
|
4385
|
+
}
|
|
3454
4386
|
export function displayUntrustedMarks(text, opts = {}) {
|
|
3455
4387
|
const ledger = { cps: [], lens: [] };
|
|
3456
4388
|
const out = renderUntrusted(text, opts, ledger);
|
|
@@ -3458,3 +4390,4 @@ export function displayUntrustedMarks(text, opts = {}) {
|
|
|
3458
4390
|
return { text: out, marks: [] };
|
|
3459
4391
|
return { text: out.text, marks: collectMarks(out, ledger) };
|
|
3460
4392
|
}
|
|
4393
|
+
const isQuoteChar = (c) => c.charCodeAt(0) === 0x22 || c.charCodeAt(0) === 0x27;
|