@sema-agent/client-core 0.100.0 → 0.102.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 +452 -0
- package/README.md +172 -120
- package/dist/adapt/arms.js +51 -16
- package/dist/adapt/textStream.js +7 -4
- package/dist/adapt/toolCards.d.ts +2 -1
- package/dist/adapt/toolCards.js +28 -13
- package/dist/adapt.d.ts +1 -1
- package/dist/adapt.js +8 -2
- package/dist/adapter/activeRunSelfHeal.d.ts +24 -2
- package/dist/adapter/activeRunSelfHeal.js +108 -6
- package/dist/adapter/downstream/eventToSdkMessage.js +38 -79
- package/dist/adapter/downstream/terminalToSdkResult.d.ts +60 -1
- package/dist/adapter/downstream/terminalToSdkResult.js +209 -39
- package/dist/adapter/downstream/wiringManifestView.d.ts +1 -0
- package/dist/adapter/downstream/wiringManifestView.js +138 -0
- package/dist/adapter/runStream.d.ts +4 -4
- package/dist/adapter/runStream.js +158 -43
- package/dist/agentsWireCaps.d.ts +2 -7
- package/dist/agentsWireCaps.js +1 -2
- package/dist/approvalDecidedByCapability.js +2 -2
- package/dist/approvalFrameFamilies.d.ts +33 -0
- package/dist/approvalFrameFamilies.js +120 -0
- package/dist/approvalsStreamLiveCapability.js +2 -2
- package/dist/attachmentsWireCaps.js +41 -13
- package/dist/callerCwdCapability.js +2 -2
- package/dist/centerWiringCapability.js +2 -2
- package/dist/clockReading.d.ts +2 -0
- package/dist/clockReading.js +4 -0
- package/dist/cloudConfigWireCaps.d.ts +19 -5
- package/dist/cloudConfigWireCaps.js +193 -56
- package/dist/compensations.js +1 -1
- package/dist/coreValuePorts.d.ts +12 -2
- package/dist/coreValuePorts.js +9 -0
- package/dist/decideFailureNote.js +5 -3
- package/dist/decideReceipt.js +2 -2
- package/dist/deviceExecutorManagementCapability.js +2 -2
- package/dist/deviceFlowPolling.js +1 -1
- package/dist/disableSkillsWire.d.ts +1 -1
- package/dist/disableSkillsWire.js +4 -3
- package/dist/displayUntrusted.d.ts +9 -4
- package/dist/displayUntrusted.js +834 -104
- package/dist/engineCapReader.js +1 -1
- package/dist/engineConfigDrift.js +1 -1
- package/dist/engineErrorCodes.d.ts +14 -5
- package/dist/engineErrorCodes.js +27 -6
- package/dist/engineGenerationConvergence.d.ts +39 -0
- package/dist/engineGenerationConvergence.js +95 -0
- package/dist/engineGenerationPort.d.ts +61 -0
- package/dist/engineGenerationPort.js +144 -0
- package/dist/engineHealthFacts.d.ts +23 -0
- package/dist/engineHealthFacts.js +92 -0
- package/dist/engineIdentity.d.ts +4 -0
- package/dist/engineIdentity.js +11 -0
- package/dist/engineNoticeCodes.d.ts +2 -5
- package/dist/engineRowRef.js +4 -0
- package/dist/engineSessionMessages.js +2 -2
- package/dist/engineToolDirectory.js +2 -2
- package/dist/engineWireFor.d.ts +99 -0
- package/dist/engineWireFor.js +248 -6
- package/dist/engineWireTarget.d.ts +1 -0
- package/dist/engineWireTarget.js +8 -0
- package/dist/env/uiLanguage.js +1 -1
- package/dist/errorSupplementRoles.d.ts +3 -0
- package/dist/errorSupplementRoles.js +37 -0
- package/dist/executionLaneCapability.js +2 -2
- package/dist/fileHistoryCaptureCapability.js +3 -3
- package/dist/finalVerifyWire.d.ts +6 -3
- package/dist/finalVerifyWire.js +6 -23
- package/dist/flagInput.d.ts +4 -0
- package/dist/flagInput.js +24 -0
- package/dist/fleet/fleetLedger.js +5 -2
- package/dist/fleet/fleetProjection.d.ts +1 -0
- package/dist/fleet/fleetProjection.js +16 -3
- package/dist/gateVocabulary.js +3 -0
- package/dist/generated/engineFactTables.d.ts +7 -3
- package/dist/generated/engineFactTables.js +52 -0
- package/dist/generated/engineNoticeTables.js +12 -0
- package/dist/generated/settingsSchemaActiveTiers.d.ts +1 -0
- package/dist/generated/settingsSchemaActiveTiers.js +14 -0
- package/dist/generated/settingsSchemaCallerTextEcho.d.ts +1 -0
- package/dist/generated/settingsSchemaCallerTextEcho.js +8 -0
- package/dist/generated/settingsSchemaControlAndBidi.d.ts +1 -0
- package/dist/generated/settingsSchemaControlAndBidi.js +8 -0
- package/dist/generated/settingsSchemaDefaultModel.d.ts +11 -0
- package/dist/generated/settingsSchemaDefaultModel.js +25 -0
- package/dist/generated/settingsSchemaFns.d.ts +54 -0
- package/dist/generated/settingsSchemaFns.js +26 -1
- package/dist/generated/settingsSchemaMcpRequestEntry.d.ts +1 -1
- package/dist/generated/settingsSchemaMcpRequestEntry.js +1 -7
- package/dist/generated/settingsSchemaSafetyMergeSpec.d.ts +1 -0
- package/dist/generated/settingsSchemaSafetyMergeSpec.js +95 -0
- package/dist/generated/settingsSchemaSettingsSources.d.ts +1 -0
- package/dist/generated/settingsSchemaSettingsSources.js +58 -0
- package/dist/generated/settingsSchemaTables.d.ts +2 -0
- package/dist/generated/settingsSchemaTables.js +13 -0
- package/dist/generated/settingsSchemaUrlPattern.d.ts +1 -0
- package/dist/generated/settingsSchemaUrlPattern.js +183 -0
- package/dist/headlessPermissionModeWire.d.ts +18 -2
- package/dist/headlessPermissionModeWire.js +30 -19
- package/dist/hitl/allowRuleShadow.js +7 -5
- package/dist/hitl/approvalCardReading.d.ts +3 -0
- package/dist/hitl/approvalCardReading.js +17 -0
- package/dist/hitl/approvalCompleteParked.js +1 -1
- package/dist/hitl/approvalDelivery.d.ts +87 -0
- package/dist/hitl/approvalDelivery.js +193 -0
- package/dist/hitl/approvalResolution.d.ts +11 -0
- package/dist/hitl/approvalResolution.js +50 -11
- package/dist/hitl/askClassPair.d.ts +6 -0
- package/dist/hitl/askClassPair.js +30 -3
- package/dist/hitl/askParkAutoReopenBlock.d.ts +30 -0
- package/dist/hitl/askParkAutoReopenBlock.js +117 -0
- package/dist/hitl/askParkRowRouting.js +4 -1
- package/dist/hitl/attributionLadder.d.ts +42 -3
- package/dist/hitl/attributionLadder.js +79 -8
- package/dist/hitl/automaticAnswerVerdict.d.ts +6 -1
- package/dist/hitl/automaticAnswerVerdict.js +46 -11
- package/dist/hitl/crashConverged.js +2 -2
- package/dist/hitl/decisionConflict.d.ts +6 -2
- package/dist/hitl/decisionConflict.js +24 -9
- package/dist/hitl/decisionRefusal.d.ts +20 -10
- package/dist/hitl/decisionRefusal.js +99 -54
- package/dist/hitl/decisionSend.d.ts +3 -0
- package/dist/hitl/decisionSend.js +87 -103
- package/dist/hitl/frameRouter.d.ts +1 -0
- package/dist/hitl/frameRouter.js +9 -2
- package/dist/hitl/hitlBridge.d.ts +18 -6
- package/dist/hitl/hitlBridge.js +41 -37
- package/dist/hitl/livePendingAsk.js +4 -3
- package/dist/hitl/noAllowCause.js +1 -1
- package/dist/hitl/parkResolver.js +3 -2
- package/dist/hitl/persistedRulesWire.js +1 -0
- package/dist/hitl/planReviewWire.d.ts +4 -0
- package/dist/hitl/planReviewWire.js +59 -30
- package/dist/hitl/resumeRunningCard.d.ts +3 -2
- package/dist/hitl/resumeRunningCard.js +17 -11
- package/dist/hitl/sessionPolicyDeliverable.d.ts +5 -2
- package/dist/hitl/sessionPolicyDeliverable.js +62 -29
- package/dist/hitl/sessionPolicyWire.d.ts +13 -3
- package/dist/hitl/sessionPolicyWire.js +81 -16
- package/dist/hitl/standingRows.js +1 -1
- package/dist/hitl/toolApprovalWire.d.ts +9 -10
- package/dist/hitl/toolApprovalWire.js +72 -54
- package/dist/hookMatcherVerdict.d.ts +2 -0
- package/dist/hookMatcherVerdict.js +12 -0
- package/dist/hooksCompactTransition.d.ts +19 -0
- package/dist/hooksCompactTransition.js +41 -0
- package/dist/hooksWireCaps.d.ts +1 -1
- package/dist/hooksWireCaps.js +202 -203
- package/dist/host.d.ts +1 -14
- package/dist/host.js +0 -8
- package/dist/hostCallbackGuard.d.ts +1 -0
- package/dist/hostCallbackGuard.js +1 -1
- package/dist/hostSettingsSource.d.ts +172 -0
- package/dist/hostSettingsSource.js +675 -0
- package/dist/hostTurnSettings.d.ts +73 -17
- package/dist/hostTurnSettings.js +594 -97
- package/dist/httpHookPolicy.d.ts +37 -0
- package/dist/httpHookPolicy.js +176 -0
- package/dist/humanTurn.d.ts +2 -1
- package/dist/humanTurn.js +37 -7
- package/dist/humanTurnRead.js +4 -3
- package/dist/humanTurnSentences.d.ts +10 -0
- package/dist/humanTurnSentences.js +74 -0
- package/dist/i18n/messages.en.d.ts +222 -2
- package/dist/i18n/messages.en.js +225 -5
- package/dist/i18n/messages.zh.js +237 -5
- package/dist/i18n/translate.js +3 -3
- package/dist/index.d.ts +77 -15
- package/dist/index.js +50 -13
- package/dist/inheritEnvCapability.d.ts +3 -1
- package/dist/inheritEnvCapability.js +31 -17
- package/dist/inheritEnvWire.d.ts +2 -1
- package/dist/inheritEnvWire.js +11 -5
- package/dist/interactiveHalt.d.ts +3 -1
- package/dist/interactiveHalt.js +2 -0
- package/dist/interactiveInterrupt.d.ts +2 -0
- package/dist/interactiveInterrupt.js +15 -0
- package/dist/interactiveToolsWire.d.ts +4 -2
- package/dist/interactiveToolsWire.js +5 -5
- package/dist/jsonFaithful.d.ts +20 -0
- package/dist/jsonFaithful.js +152 -0
- package/dist/limitsWire.d.ts +7 -2
- package/dist/limitsWire.js +19 -13
- package/dist/liveInitToolFace.d.ts +6 -1
- package/dist/liveInitToolFace.js +5 -3
- package/dist/liveModelCatalog.d.ts +22 -0
- package/dist/liveModelCatalog.js +132 -18
- package/dist/mcpPanel.js +1 -1
- package/dist/mcpProbeCapability.js +2 -2
- package/dist/mcpStatusSupersetKeys.d.ts +24 -0
- package/dist/mcpStatusSupersetKeys.js +45 -0
- package/dist/mcpToolToggles.js +2 -1
- package/dist/mcpWireCaps.d.ts +39 -1
- package/dist/mcpWireCaps.js +254 -50
- package/dist/memoryComplianceCapability.js +2 -2
- package/dist/memoryOriginCapability.js +2 -2
- package/dist/model/catalogDefault.d.ts +24 -0
- package/dist/model/catalogDefault.js +4 -0
- package/dist/model/liveCatalogShape.js +5 -4
- package/dist/model/modelsPolicy.js +4 -3
- package/dist/model/onboardJudgement.d.ts +1 -0
- package/dist/model/onboardJudgement.js +1 -1
- package/dist/model/subagentModelWord.js +2 -2
- package/dist/modelCapabilityProbe.js +6 -6
- package/dist/modelIdentityResolvability.d.ts +10 -1
- package/dist/modelIdentityResolvability.js +62 -39
- package/dist/modsFace.d.ts +8 -0
- package/dist/modsFace.js +59 -0
- package/dist/modsKernelIdentity.d.ts +10 -0
- package/dist/modsKernelIdentity.js +103 -0
- package/dist/modsKernelTransit.d.ts +8 -0
- package/dist/modsKernelTransit.js +6 -0
- package/dist/notifications.d.ts +30 -12
- package/dist/notifications.js +241 -53
- package/dist/outputStyleSeatCapability.js +2 -2
- package/dist/ownKey.d.ts +12 -0
- package/dist/ownKey.js +179 -3
- package/dist/panelReduce.js +1 -1
- package/dist/peerFrames.d.ts +1 -1
- package/dist/peerFrames.js +6 -2
- package/dist/peerLaneCapability.js +2 -2
- package/dist/permissionModesCapability.js +4 -4
- package/dist/permissionRuleIssue.js +2 -0
- package/dist/permissionRulesWriteCapability.js +2 -2
- package/dist/permissionsAllowGrantCapability.js +2 -2
- package/dist/permissionsDeclaration.d.ts +43 -4
- package/dist/permissionsDeclaration.js +102 -35
- package/dist/pluginHooksWire.d.ts +20 -4
- package/dist/pluginHooksWire.js +92 -53
- package/dist/prepareRefusal.d.ts +3 -2
- package/dist/prepareRefusal.js +27 -9
- package/dist/printInitToolFace.js +2 -2
- package/dist/printModelStatus.js +1 -1
- package/dist/printToolResultFrame.js +1 -1
- package/dist/projectMemory.d.ts +32 -0
- package/dist/projectMemory.js +70 -0
- package/dist/promptBlockedCopy.d.ts +2 -1
- package/dist/promptBlockedCopy.js +2 -1
- package/dist/promptDelivery.d.ts +23 -3
- package/dist/promptDelivery.js +169 -30
- package/dist/providerRejection.d.ts +19 -1
- package/dist/providerRejection.js +75 -4
- package/dist/queuedDelivery.d.ts +48 -0
- package/dist/queuedDelivery.js +233 -0
- package/dist/reattachWindow.d.ts +94 -0
- package/dist/reattachWindow.js +127 -0
- package/dist/request/printNotification.d.ts +1 -1
- package/dist/request/printNotification.js +6 -2
- package/dist/request/submissionIdentity.d.ts +37 -0
- package/dist/request/submissionIdentity.js +65 -0
- package/dist/request/taskRequest.d.ts +33 -4
- package/dist/request/taskRequest.js +341 -156
- package/dist/resultFrameKeys.d.ts +1 -0
- package/dist/resultFrameKeys.js +4 -1
- package/dist/retryStatus.d.ts +8 -0
- package/dist/retryStatus.js +57 -9
- package/dist/rewindArchiveCapability.js +2 -2
- package/dist/rewindEngineAction.d.ts +2 -0
- package/dist/rewindEngineAction.js +23 -1
- package/dist/rowKind.d.ts +36 -0
- package/dist/rowKind.js +97 -0
- package/dist/ruleCompileVerdict.d.ts +18 -0
- package/dist/ruleCompileVerdict.js +67 -2
- package/dist/ruleReadings.d.ts +58 -0
- package/dist/ruleReadings.js +132 -0
- package/dist/ruleRefusalSentence.d.ts +4 -0
- package/dist/ruleRefusalSentence.js +9 -3
- package/dist/runCancelContext.d.ts +0 -1
- package/dist/runCancelContext.js +1 -2
- package/dist/runTerminal.d.ts +5 -0
- package/dist/runTerminal.js +52 -17
- package/dist/sandboxWire.d.ts +1 -1
- package/dist/sandboxWire.js +4 -6
- package/dist/scenarioRefusal.js +1 -1
- package/dist/scenarioSkills.d.ts +20 -0
- package/dist/scenarioSkills.js +72 -0
- package/dist/scenarioWire.d.ts +5 -2
- package/dist/scenarioWire.js +9 -9
- package/dist/sealedKeyCapability.js +2 -2
- package/dist/seam.d.ts +2 -0
- package/dist/seam.js +3 -3
- package/dist/seatContract.d.ts +68 -7
- package/dist/seatContract.js +84 -25
- package/dist/selfOrchestrationDenial.js +1 -1
- package/dist/sessionBackground.d.ts +165 -0
- package/dist/sessionBackground.js +781 -0
- package/dist/sessionBackgroundHandoff.d.ts +54 -0
- package/dist/sessionBackgroundHandoff.js +321 -0
- package/dist/sessionMap.js +4 -1
- package/dist/sessionPolicyCapability.js +2 -2
- package/dist/sessionRulesChildrenReadLive.d.ts +6 -0
- package/dist/sessionRulesChildrenReadLive.js +5 -0
- package/dist/sessionRulesNamespaceFormsCapability.d.ts +12 -0
- package/dist/sessionRulesNamespaceFormsCapability.js +29 -0
- package/dist/sessionSyncFileHistoryCapability.js +2 -2
- package/dist/settingsCredentialKeyPaths.js +55 -15
- package/dist/settingsHooksSalvage.d.ts +1 -0
- package/dist/settingsHooksSalvage.js +7 -1
- package/dist/settingsLayerAdmission.d.ts +4 -0
- package/dist/settingsLayerAdmission.js +16 -0
- package/dist/skillToolListsCapability.js +6 -5
- package/dist/skillsWireCaps.d.ts +14 -0
- package/dist/skillsWireCaps.js +47 -16
- package/dist/slashCommandGate.d.ts +24 -0
- package/dist/slashCommandGate.js +74 -0
- package/dist/slashCommandTable.d.ts +14 -0
- package/dist/slashCommandTable.js +99 -0
- package/dist/sqlEngineCapability.js +2 -2
- package/dist/steerPriorityCapability.js +2 -2
- package/dist/storePostureCapability.js +2 -2
- package/dist/subagent/agentStateDetail.js +1 -1
- package/dist/subagent/engineDelegatedPrompt.d.ts +9 -0
- package/dist/subagent/engineDelegatedPrompt.js +38 -7
- package/dist/subagent/engineRowStopGate.js +2 -2
- package/dist/subagent/engineSubagentResume.js +3 -3
- package/dist/subagent/engineTaskHandleWire.d.ts +1 -0
- package/dist/subagent/engineTaskHandleWire.js +10 -0
- package/dist/submitFailure.d.ts +8 -0
- package/dist/submitFailure.js +17 -0
- package/dist/supportFloor.d.ts +1 -0
- package/dist/supportFloor.js +7 -0
- package/dist/terminationIntent.d.ts +55 -0
- package/dist/terminationIntent.js +352 -0
- package/dist/thinkingLatch.d.ts +69 -0
- package/dist/thinkingLatch.js +255 -0
- package/dist/thinkingLatchWords.d.ts +7 -0
- package/dist/thinkingLatchWords.js +4 -0
- package/dist/toolHistoryMismatch.d.ts +8 -0
- package/dist/toolHistoryMismatch.js +37 -6
- package/dist/toolResult.d.ts +13 -3
- package/dist/toolResult.js +159 -32
- package/dist/toolResultContent.d.ts +13 -0
- package/dist/toolResultContent.js +82 -7
- package/dist/toolRoster.d.ts +18 -0
- package/dist/toolRoster.js +64 -0
- package/dist/turnFailurePresentation.js +27 -90
- package/dist/usageLimitAutoResume.d.ts +74 -0
- package/dist/usageLimitAutoResume.js +227 -0
- package/dist/userAttachmentEnvelope.js +1 -1
- package/dist/userAttachmentSeat.js +5 -5
- package/dist/userInvokedSkillsCapability.js +2 -2
- package/dist/webSearchBackendCapability.js +2 -2
- package/dist/wireErrorTriage.js +99 -50
- package/dist/wireFailureShape.d.ts +25 -1
- package/dist/wireFailureShape.js +92 -5
- package/dist/wireRefusalCopy.d.ts +24 -1
- package/dist/wireRefusalCopy.js +253 -32
- package/dist/wiringFleetDoctor.d.ts +3 -0
- package/dist/wiringFleetDoctor.js +21 -0
- package/dist/workflow.d.ts +2 -1
- package/dist/workflow.js +38 -1
- package/dist/workflowClient.d.ts +2 -7
- package/dist/workflowsJournalCapability.js +2 -2
- package/dist/writeProtectionCapability.js +2 -2
- package/docs/INTEGRATION-CLIENTS.md +907 -182
- package/package.json +14 -3
- package/dist/argvFlagValue.d.ts +0 -8
- package/dist/argvFlagValue.js +0 -37
package/dist/displayUntrusted.js
CHANGED
|
@@ -11,7 +11,7 @@ function isMarker(v) {
|
|
|
11
11
|
return core === RETIRED_MARKER || MARKER_RE.test(core);
|
|
12
12
|
}
|
|
13
13
|
const VIEW_SEPARATOR = '\ufeff';
|
|
14
|
-
function pushEdit(edits, src, start, end, text) {
|
|
14
|
+
function pushEdit(edits, src, start, end, text, phases) {
|
|
15
15
|
let a = start;
|
|
16
16
|
let b = end;
|
|
17
17
|
while (a < b && src[a] === VIEW_SEPARATOR)
|
|
@@ -22,7 +22,7 @@ function pushEdit(edits, src, start, end, text) {
|
|
|
22
22
|
a = b = start;
|
|
23
23
|
if (src.slice(a, b) === text)
|
|
24
24
|
return;
|
|
25
|
-
edits.push({ start: a, end: b, text });
|
|
25
|
+
edits.push(phases === undefined ? { start: a, end: b, text } : { start: a, end: b, text, phases });
|
|
26
26
|
}
|
|
27
27
|
const UNIT_NONE = 0;
|
|
28
28
|
const UNIT_SEQUENCE = 1;
|
|
@@ -220,7 +220,7 @@ const isHostChar = (c) => (c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5a) |
|
|
|
220
220
|
const isIpv6Char = (c) => (c >= 0x30 && c <= 0x3a) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66) || c === 0x2e;
|
|
221
221
|
const endsSchemelessHost = (c) => Number.isNaN(c) || c === 0x2f || c === 0x3f || c === 0x23 || c === 0x22 || c === 0x3c || c === 0x3e || c === 0x60 ||
|
|
222
222
|
c === 0x7c || c === 0x5c || c === 0x5e || c === 0x7b || c === 0x7d || isRegexSpace(c);
|
|
223
|
-
function schemelessHostEnd(text, from) {
|
|
223
|
+
function schemelessHostEnd(text, from, wide = false) {
|
|
224
224
|
let k = from;
|
|
225
225
|
if (text.charCodeAt(k) === 0x5b) {
|
|
226
226
|
k++;
|
|
@@ -238,14 +238,25 @@ function schemelessHostEnd(text, from) {
|
|
|
238
238
|
}
|
|
239
239
|
if (text.charCodeAt(k) === 0x3a) {
|
|
240
240
|
let d = k + 1;
|
|
241
|
-
|
|
242
|
-
d
|
|
243
|
-
|
|
241
|
+
if (wide) {
|
|
242
|
+
while (d < text.length && isSchemelessPortChar(text.charCodeAt(d)))
|
|
243
|
+
d++;
|
|
244
244
|
k = d;
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
while (d < text.length && text.charCodeAt(d) >= 0x30 && text.charCodeAt(d) <= 0x39)
|
|
248
|
+
d++;
|
|
249
|
+
if (d > k + 1)
|
|
250
|
+
k = d;
|
|
251
|
+
}
|
|
245
252
|
}
|
|
246
253
|
const c = text.charCodeAt(k);
|
|
247
|
-
return endsSchemelessHost(c) || c === 0x27 ? k : -1;
|
|
254
|
+
return endsSchemelessHost(c) || c === 0x27 || (wide && endsSchemelessHostInProse(c)) ? k : -1;
|
|
248
255
|
}
|
|
256
|
+
const isSchemelessPortChar = (c) => (c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) || c === 0x2e || c === 0x5f || c === 0x7e || c === 0x25 || c === 0x2d;
|
|
257
|
+
const endsSchemelessHostInProse = (c) => c === 0x29 || c === 0x2c || c === 0x3b || c === 0x21 || c === 0x5d;
|
|
258
|
+
const SCHEMELESS_USERINFO_WIDE_SPAN = 64 + 1 + 256;
|
|
259
|
+
const isUserinfoWideDelimiter = (ch) => ch === '?' || ch === '#' || ch === '@';
|
|
249
260
|
const MAX_PORT = 65535;
|
|
250
261
|
function authorityIsHostPort(text, from, to) {
|
|
251
262
|
if (to <= from || schemelessHostEnd(text.slice(0, to), from) !== to)
|
|
@@ -282,32 +293,32 @@ function queryCandidates(src, base, query, edits, soft, byShape = false) {
|
|
|
282
293
|
const eq = part.indexOf('=');
|
|
283
294
|
if (eq === -1) {
|
|
284
295
|
const at = pos;
|
|
285
|
-
if (!slotIsWholeMarker(part, soft && ((i) => soft(at + i)))
|
|
286
|
-
|
|
296
|
+
if (!slotIsWholeMarker(part, soft && ((i) => soft(at + i)))) {
|
|
297
|
+
const phases = byShape ? queryPartPhases(null, part, relax) : phaseRange(0, scanUpto);
|
|
298
|
+
if (phases !== 0)
|
|
299
|
+
pushEdit(edits, src, pos, pos + part.length, REDACTED_QUERY, phasesOrAll(phases));
|
|
300
|
+
}
|
|
287
301
|
}
|
|
288
302
|
else {
|
|
289
303
|
const value = part.slice(eq + 1);
|
|
290
304
|
const at = pos + eq + 1;
|
|
291
|
-
if (value.length > 0 && !slotIsWholeMarker(value, soft && ((i) => soft(at + i)))
|
|
292
|
-
|
|
305
|
+
if (value.length > 0 && !slotIsWholeMarker(value, soft && ((i) => soft(at + i)))) {
|
|
306
|
+
const phases = byShape ? queryPartPhases(part.slice(0, eq), value, relax) : phaseRange(0, scanUpto);
|
|
307
|
+
if (phases !== 0)
|
|
308
|
+
pushEdit(edits, src, pos + eq + 1, pos + part.length, REDACTED_QUERY, phasesOrAll(phases));
|
|
293
309
|
}
|
|
294
310
|
}
|
|
295
311
|
}
|
|
296
312
|
pos += part.length + 1;
|
|
297
313
|
}
|
|
298
314
|
}
|
|
299
|
-
function pathCandidates(src, base, path, opaqueSegments, edits, soft) {
|
|
315
|
+
function pathCandidates(src, base, path, opaqueSegments, edits, soft, whole = false) {
|
|
300
316
|
let pos = base;
|
|
301
317
|
for (const segment of path.split('/')) {
|
|
302
318
|
const semi = segment.indexOf(';');
|
|
303
319
|
const head = semi === -1 ? segment : segment.slice(0, semi);
|
|
304
320
|
if (opaqueSegments) {
|
|
305
|
-
|
|
306
|
-
let b = head.length;
|
|
307
|
-
while (a < b && !isKeyWordChar(head.charCodeAt(a)) && !(head.charCodeAt(a) === 0x25 && hasNonAsciiPercentEscape(head.slice(a, a + 3))))
|
|
308
|
-
a++;
|
|
309
|
-
while (b > a && !isKeyWordChar(head.charCodeAt(b - 1)))
|
|
310
|
-
b--;
|
|
321
|
+
const [a, b] = markerAtomicCut(head, ...segmentWordCut(head));
|
|
311
322
|
if (isKnownSecretSegment(head)) {
|
|
312
323
|
if (b > a)
|
|
313
324
|
pushEdit(edits, src, pos + a, pos + b, REDACTED_SECRET);
|
|
@@ -317,6 +328,10 @@ function pathCandidates(src, base, path, opaqueSegments, edits, soft) {
|
|
|
317
328
|
if (glued > 0)
|
|
318
329
|
pushEdit(edits, src, pos + a + glued, pos + b, REDACTED_SECRET);
|
|
319
330
|
}
|
|
331
|
+
if (whole && b > a) {
|
|
332
|
+
const at = pos;
|
|
333
|
+
emitRow('path-slot', (phases) => pathSlotEdits(src, at, head, a, b, phases, edits, soft));
|
|
334
|
+
}
|
|
320
335
|
}
|
|
321
336
|
if (semi !== -1) {
|
|
322
337
|
let ppos = pos + semi + 1;
|
|
@@ -334,9 +349,76 @@ function pathCandidates(src, base, path, opaqueSegments, edits, soft) {
|
|
|
334
349
|
pos += segment.length + 1;
|
|
335
350
|
}
|
|
336
351
|
}
|
|
337
|
-
function
|
|
352
|
+
function segmentWordCut(head) {
|
|
353
|
+
let a = 0;
|
|
354
|
+
let b = head.length;
|
|
355
|
+
while (a < b && !isKeyWordChar(head.charCodeAt(a)) && !(head.charCodeAt(a) === 0x25 && hasNonAsciiPercentEscape(head.slice(a, a + 3))))
|
|
356
|
+
a++;
|
|
357
|
+
while (b > a && !isKeyWordChar(head.charCodeAt(b - 1)))
|
|
358
|
+
b--;
|
|
359
|
+
return [a, b];
|
|
360
|
+
}
|
|
361
|
+
function markerAtomicCut(head, a, b) {
|
|
362
|
+
if (!head.includes(REDACTION_MARKER_PREFIX))
|
|
363
|
+
return [a, b];
|
|
364
|
+
let s = a;
|
|
365
|
+
let e = b;
|
|
366
|
+
const re = new RegExp(MARKER_ANYWHERE.source, MARKER_ANYWHERE.flags);
|
|
367
|
+
for (let m = re.exec(head); m !== null; m = re.exec(head)) {
|
|
368
|
+
const ms = m.index;
|
|
369
|
+
const me = ms + m[0].length;
|
|
370
|
+
if (ms < s && s < me)
|
|
371
|
+
s = ms;
|
|
372
|
+
if (ms < e && e < me)
|
|
373
|
+
e = me;
|
|
374
|
+
}
|
|
375
|
+
return [s, e];
|
|
376
|
+
}
|
|
377
|
+
function pathSlotEdits(src, pos, head, a, b, rowPhases, edits, soft) {
|
|
378
|
+
const softFrom = (at) => (soft === undefined ? undefined : (i) => soft(pos + at + i));
|
|
379
|
+
const eq = head.indexOf('=', a);
|
|
380
|
+
let named = 0;
|
|
381
|
+
if (eq > a && eq < b) {
|
|
382
|
+
const name = head.slice(a, eq);
|
|
383
|
+
if (!slotIsWholeMarker(name, softFrom(a))) {
|
|
384
|
+
named = queryPartPhases(null, name, false) & rowPhases;
|
|
385
|
+
if (named !== 0)
|
|
386
|
+
pushEdit(edits, src, pos + a, pos + b, REDACTED_SECRET, named);
|
|
387
|
+
if (named === rowPhases)
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
const [s, e] = markerAtomicCut(head, eq !== -1 && eq < b ? eq + 1 : a, b);
|
|
392
|
+
if (s >= e)
|
|
393
|
+
return;
|
|
394
|
+
const slot = head.slice(s, e);
|
|
395
|
+
if (slotIsWholeMarker(slot, softFrom(s)))
|
|
396
|
+
return;
|
|
397
|
+
const valued = queryPartPhases(null, slot, false) & rowPhases & ~named;
|
|
398
|
+
if (valued !== 0)
|
|
399
|
+
pushEdit(edits, src, pos + s, pos + e, REDACTED_SECRET, valued);
|
|
400
|
+
}
|
|
401
|
+
const anchoredFormPattern = (form) => new RegExp(`(?:https?:\/\/)?${form.host.split('.').join('\\.')}${form.trailingDot ? '\\.?' : ''}\/(?:${form.pathKinds.join('|')})\/((?:[${form.tailClass}]|${MARKER_ANYWHERE.source})+)`, 'gi');
|
|
402
|
+
function anchoredFormCandidates(text, out) {
|
|
403
|
+
for (const { id, form, probe, pattern } of ANCHORED_FORM_ROWS) {
|
|
404
|
+
if (!probe.test(text))
|
|
405
|
+
continue;
|
|
406
|
+
emitRow(id, (phases) => {
|
|
407
|
+
const re = new RegExp(pattern.source, pattern.flags);
|
|
408
|
+
for (let m = re.exec(text); m !== null; m = re.exec(text)) {
|
|
409
|
+
const tail = m[1] ?? '';
|
|
410
|
+
const end = m.index + m[0].length;
|
|
411
|
+
if (tail.length > 0 && (tail.includes(REDACTION_MARKER_PREFIX) || tail.length >= form.minTailLength))
|
|
412
|
+
out.push({ a: end - tail.length, b: end, kind: 'secret', cls: 'url', te: -1, phases });
|
|
413
|
+
if (m[0].length === 0)
|
|
414
|
+
re.lastIndex++;
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
function addressCandidates(src, from, end, opaqueSegments, edits, regions, soft, byShape = false, whole = false, hostRegion = whole, pathOnly = false) {
|
|
338
420
|
const rest = src.slice(from, end);
|
|
339
|
-
const authorityEnd = rest.search(/[/?#]/);
|
|
421
|
+
const authorityEnd = pathOnly ? 0 : rest.search(/[/?#]/);
|
|
340
422
|
const authority = authorityEnd === -1 ? rest : rest.slice(0, authorityEnd);
|
|
341
423
|
const tailStart = from + authority.length;
|
|
342
424
|
const tail = src.slice(tailStart, end);
|
|
@@ -347,7 +429,7 @@ function addressCandidates(src, from, end, opaqueSegments, edits, regions, soft,
|
|
|
347
429
|
const beforeHash = hash === -1 ? tail : tail.slice(0, hash);
|
|
348
430
|
const question = beforeHash.indexOf('?');
|
|
349
431
|
const path = question === -1 ? beforeHash : beforeHash.slice(0, question);
|
|
350
|
-
pathCandidates(src, tailStart, path, opaqueSegments, edits, soft);
|
|
432
|
+
pathCandidates(src, tailStart, path, opaqueSegments, edits, soft, whole);
|
|
351
433
|
if (whole) {
|
|
352
434
|
const cut = pathCutAfterFirstLabel(path, true);
|
|
353
435
|
if (cut !== -1 && fragmentTerminatorFrom(path, cut))
|
|
@@ -376,7 +458,8 @@ function relativeAddressCandidates(text, out, regions, unitPos, soft, hostRegion
|
|
|
376
458
|
while (p0 < text.length && (isWhitespaceOrControl(text.charAt(p0)) || text.charAt(p0) === VIEW_SEPARATOR))
|
|
377
459
|
p0++;
|
|
378
460
|
const c0 = text.charAt(p0);
|
|
379
|
-
|
|
461
|
+
const pathOnly = c0 !== '/' && c0 !== '?' && c0 !== '#' && isRelativeRequestAt(text, p0);
|
|
462
|
+
if (c0 !== '/' && c0 !== '?' && c0 !== '#' && !pathOnly)
|
|
380
463
|
return false;
|
|
381
464
|
let end = text.length;
|
|
382
465
|
while (end > p0 && (text.charAt(end - 1) === VIEW_SEPARATOR || isWhitespaceOrControl(text.charAt(end - 1)) || isUnicodeBlank(text.charCodeAt(end - 1))))
|
|
@@ -384,10 +467,19 @@ function relativeAddressCandidates(text, out, regions, unitPos, soft, hostRegion
|
|
|
384
467
|
end = trailingCloserEnd(text, p0, p0 + 1, end, unitPos);
|
|
385
468
|
const from = text.startsWith('//', p0) ? p0 + 2 : p0;
|
|
386
469
|
const tokenEdits = [];
|
|
387
|
-
addressCandidates(text, from, end, true, tokenEdits, regions, soft, false, true, hostRegion);
|
|
470
|
+
addressCandidates(text, from, end, true, tokenEdits, regions, soft, false, true, hostRegion, pathOnly);
|
|
388
471
|
editsToCandidates(tokenEdits, 'url', out, end);
|
|
389
472
|
return true;
|
|
390
473
|
}
|
|
474
|
+
function isRelativeRequestAt(text, p0) {
|
|
475
|
+
const rest = text.slice(p0);
|
|
476
|
+
if (/^[A-Za-z][A-Za-z0-9+.-]*:/.test(rest))
|
|
477
|
+
return false;
|
|
478
|
+
const q = rest.search(/[?#]/);
|
|
479
|
+
if (q <= 0)
|
|
480
|
+
return false;
|
|
481
|
+
return !/[\s=\ufeff]/.test(rest.slice(0, q)) && rest.indexOf('=', q + 1) !== -1;
|
|
482
|
+
}
|
|
391
483
|
function urlCandidates(text, out, regions, unitPos = () => false, soft, byShape = false, whole = false, hostRegion = whole) {
|
|
392
484
|
if (whole && relativeAddressCandidates(text, out, regions, unitPos, soft, hostRegion))
|
|
393
485
|
return;
|
|
@@ -457,6 +549,8 @@ function urlCandidates(text, out, regions, unitPos = () => false, soft, byShape
|
|
|
457
549
|
end = runStart;
|
|
458
550
|
end = trailingCloserEnd(text, start, mark + 3, end, unitPos);
|
|
459
551
|
const tokenEdits = [];
|
|
552
|
+
if (userinfoBoundaryAmbiguous(text.slice(start, end)))
|
|
553
|
+
pushEdit(tokenEdits, text, start, end, REDACTED_SECRET);
|
|
460
554
|
addressCandidates(text, mark + 3, end, !/^file:/i.test(text.slice(start, mark + 3)), tokenEdits, regions, soft, byShape, whole, hostRegion);
|
|
461
555
|
editsToCandidates(tokenEdits, 'url', out, end);
|
|
462
556
|
mark = text.indexOf('://', end > mark + 3 ? end : mark + 3);
|
|
@@ -635,13 +729,7 @@ function userinfoCandidates(S, out, words = true) {
|
|
|
635
729
|
return nextBareStop(from) >= at;
|
|
636
730
|
};
|
|
637
731
|
let floor = 0;
|
|
638
|
-
|
|
639
|
-
let hostEnd = schemelessHostEnd(text, at + 1);
|
|
640
|
-
const hidden = hostEnd === -1;
|
|
641
|
-
if (hidden)
|
|
642
|
-
hostEnd = hiddenHostEnd(text, at + 1, unitAt);
|
|
643
|
-
if (hostEnd === -1)
|
|
644
|
-
continue;
|
|
732
|
+
const readAt = (at, hostEnd, hidden, runStartIn) => {
|
|
645
733
|
let shaped = null;
|
|
646
734
|
const hostShaped = () => {
|
|
647
735
|
if (shaped === null) {
|
|
@@ -673,9 +761,7 @@ function userinfoCandidates(S, out, words = true) {
|
|
|
673
761
|
return hostShaped() ? 'bare' : null;
|
|
674
762
|
};
|
|
675
763
|
const refused = [];
|
|
676
|
-
let runStart =
|
|
677
|
-
while (runStart > floor && (!breaksUserinfo(text.charCodeAt(runStart - 1)) || (hidden && unitAt(runStart - 1) !== UNIT_NONE)))
|
|
678
|
-
runStart--;
|
|
764
|
+
let runStart = runStartIn;
|
|
679
765
|
if (text.charCodeAt(runStart) === 0x3a && runStart > floor && text[runStart - 1] === VIEW_SEPARATOR) {
|
|
680
766
|
while (runStart > floor && text[runStart - 1] === VIEW_SEPARATOR)
|
|
681
767
|
runStart--;
|
|
@@ -723,7 +809,7 @@ function userinfoCandidates(S, out, words = true) {
|
|
|
723
809
|
continue;
|
|
724
810
|
}
|
|
725
811
|
}
|
|
726
|
-
if (USERNAME_DELIMITERS.has(ch)) {
|
|
812
|
+
if (USERNAME_DELIMITERS.has(ch) || isUserinfoWideDelimiter(ch)) {
|
|
727
813
|
lo = colon + 1;
|
|
728
814
|
continue;
|
|
729
815
|
}
|
|
@@ -791,10 +877,50 @@ function userinfoCandidates(S, out, words = true) {
|
|
|
791
877
|
}
|
|
792
878
|
}
|
|
793
879
|
}
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
880
|
+
return found;
|
|
881
|
+
};
|
|
882
|
+
const walkFrom = (at, hidden) => {
|
|
883
|
+
let r = at;
|
|
884
|
+
while (r > floor && (!breaksUserinfo(text.charCodeAt(r - 1)) || (hidden && unitAt(r - 1) !== UNIT_NONE)))
|
|
885
|
+
r--;
|
|
886
|
+
return r;
|
|
887
|
+
};
|
|
888
|
+
const widen = (at, r) => {
|
|
889
|
+
const wideFloor = Math.max(floor, at - SCHEMELESS_USERINFO_WIDE_SPAN);
|
|
890
|
+
let w = r;
|
|
891
|
+
while (w > wideFloor && isUserinfoWideDelimiter(text.charAt(w - 1))) {
|
|
892
|
+
w--;
|
|
893
|
+
while (w > wideFloor && !breaksUserinfo(text.charCodeAt(w - 1)))
|
|
894
|
+
w--;
|
|
895
|
+
}
|
|
896
|
+
return w;
|
|
897
|
+
};
|
|
898
|
+
for (let at = text.indexOf('@'); at !== -1; at = text.indexOf('@', at + 1)) {
|
|
899
|
+
let hostEnd = schemelessHostEnd(text, at + 1);
|
|
900
|
+
const hidden = hostEnd === -1;
|
|
901
|
+
if (hidden)
|
|
902
|
+
hostEnd = hiddenHostEnd(text, at + 1, unitAt);
|
|
903
|
+
const cursor = markerFrom;
|
|
904
|
+
const runStart = hostEnd === -1 ? -1 : walkFrom(at, hidden);
|
|
905
|
+
const found = runStart === -1 ? -1 : readAt(at, hostEnd, hidden, runStart);
|
|
906
|
+
if (found !== -1)
|
|
907
|
+
out.push({ a: found, b: at, kind: 'userinfo', cls: hidden ? 'userinfo-hidden' : 'structural', te: hostEnd });
|
|
908
|
+
const wideEnd = schemelessHostEnd(text, at + 1, true);
|
|
909
|
+
const wHidden = wideEnd === -1 ? hidden : false;
|
|
910
|
+
const wHostEnd = wideEnd === -1 ? hostEnd : wideEnd;
|
|
911
|
+
if (wHostEnd !== -1) {
|
|
912
|
+
const wRunStart = widen(at, wHostEnd === hostEnd && wHidden === hidden && runStart !== -1 ? runStart : walkFrom(at, wHidden));
|
|
913
|
+
if (wHostEnd !== hostEnd || wHidden !== hidden || wRunStart !== runStart) {
|
|
914
|
+
const after = markerFrom;
|
|
915
|
+
markerFrom = cursor;
|
|
916
|
+
const wFound = readAt(at, wHostEnd, wHidden, wRunStart);
|
|
917
|
+
markerFrom = Math.max(after, markerFrom);
|
|
918
|
+
if (wFound !== -1 && (wFound !== found || wHostEnd !== hostEnd))
|
|
919
|
+
out.push({ a: wFound, b: at, kind: 'userinfo', cls: wHidden ? 'userinfo-hidden' : 'structural', te: wHostEnd });
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
if (found !== -1)
|
|
923
|
+
floor = hostEnd;
|
|
798
924
|
}
|
|
799
925
|
}
|
|
800
926
|
function labelWashedBefore(text, a, floor) {
|
|
@@ -1407,6 +1533,10 @@ function percentBoundaryDecode(text) {
|
|
|
1407
1533
|
}
|
|
1408
1534
|
return { decoded: chars.join(''), from, to };
|
|
1409
1535
|
}
|
|
1536
|
+
export function percentBoundaryReadingOf(text) {
|
|
1537
|
+
const wide = percentBoundaryDecode(text);
|
|
1538
|
+
return wide === null ? text : wide.decoded;
|
|
1539
|
+
}
|
|
1410
1540
|
const MAX_PERCENT_VIEW_LAYERS = 3;
|
|
1411
1541
|
function percentLayers(text) {
|
|
1412
1542
|
const out = [];
|
|
@@ -3911,11 +4041,12 @@ function screenSurfaces(text, o) {
|
|
|
3911
4041
|
function percentSurfaces(raw, text, base, o) {
|
|
3912
4042
|
const surfaces = [];
|
|
3913
4043
|
const contents = [];
|
|
4044
|
+
const locals = [];
|
|
3914
4045
|
for (const layer of percentLayers(text))
|
|
3915
|
-
layerSurfaces(raw, layer, base, o, surfaces, contents);
|
|
3916
|
-
return { surfaces, contents };
|
|
4046
|
+
layerSurfaces(raw, layer, base, o, surfaces, contents, true, base === null ? locals : undefined);
|
|
4047
|
+
return { surfaces, contents, locals };
|
|
3917
4048
|
}
|
|
3918
|
-
function layerSurfaces(raw, layer, base, o, surfaces, contents, decoded = true) {
|
|
4049
|
+
function layerSurfaces(raw, layer, base, o, surfaces, contents, decoded = true, locals) {
|
|
3919
4050
|
const n = layer.text.length;
|
|
3920
4051
|
const ps = new Int32Array(n);
|
|
3921
4052
|
const pe = new Int32Array(n);
|
|
@@ -3937,6 +4068,52 @@ function layerSurfaces(raw, layer, base, o, surfaces, contents, decoded = true)
|
|
|
3937
4068
|
surfaces.push(base === null ? { ...joined, rawDot: null, decoded } : { ...joined, decoded });
|
|
3938
4069
|
for (const [a, b] of VD.contents)
|
|
3939
4070
|
contents.push({ sub: layer.text.slice(a, b), rawAt: (k) => ps[a + k] ?? 0, rawEndAt: (k) => pe[a + k] ?? 0 });
|
|
4071
|
+
if (locals !== undefined && decoded && base === null && hasLineBreakAny(layer.text)) {
|
|
4072
|
+
locals.push({ text: layer.text, view: VD, ps, pe });
|
|
4073
|
+
if (layer.text.includes('+')) {
|
|
4074
|
+
const spaced = layer.text.split('+').join(' ');
|
|
4075
|
+
locals.push({ text: spaced, view: buildScanView(spaced, o), ps, pe });
|
|
4076
|
+
}
|
|
4077
|
+
}
|
|
4078
|
+
}
|
|
4079
|
+
function hasLineBreakAny(text) {
|
|
4080
|
+
for (let i = 0; i < text.length; i++) {
|
|
4081
|
+
const c = text.charCodeAt(i);
|
|
4082
|
+
if ((c === 0x0a || c === 0x0d || c === 0x5c) && lineBreakLengthAt(text, i) > 0)
|
|
4083
|
+
return true;
|
|
4084
|
+
}
|
|
4085
|
+
return false;
|
|
4086
|
+
}
|
|
4087
|
+
function decodedLayerLocalCandidates(L, o, out) {
|
|
4088
|
+
const layerSep = { ...separatedSurface(L.text, L.view), rawDot: null, decoded: true };
|
|
4089
|
+
const layerJoined = joinedSurface(L.text, L.view);
|
|
4090
|
+
const surfaces = layerJoined === null ? [layerSep] : [layerSep, { ...layerJoined, rawDot: null, decoded: true }];
|
|
4091
|
+
const blocks = { raw: L.text, view: L.view, out: [], lines: [null, null], marks: null };
|
|
4092
|
+
const found = [];
|
|
4093
|
+
for (const S of surfaces) {
|
|
4094
|
+
const cands = [];
|
|
4095
|
+
const regions = [];
|
|
4096
|
+
if (o.urls) {
|
|
4097
|
+
const unitPos = (k) => S.dropped(k) || L.view.rawUnit[S.rawStart(k)] === 1;
|
|
4098
|
+
urlCandidates(S.text, [], regions, unitPos, (k) => unitPos(k) || S.painted(k), o.queryByShape ?? false, o.wholeAddress === true, false);
|
|
4099
|
+
}
|
|
4100
|
+
runLabelPasses(S, regions, cands, blocks);
|
|
4101
|
+
for (const c of cands) {
|
|
4102
|
+
const r = toRaw(S, c);
|
|
4103
|
+
if (r !== null)
|
|
4104
|
+
found.push(r);
|
|
4105
|
+
}
|
|
4106
|
+
}
|
|
4107
|
+
for (const r of blocks.out)
|
|
4108
|
+
found.push(r);
|
|
4109
|
+
for (const r of found) {
|
|
4110
|
+
const start = L.ps[r.start];
|
|
4111
|
+
const end = L.pe[r.end - 1];
|
|
4112
|
+
if (start === undefined || end === undefined || end <= start)
|
|
4113
|
+
continue;
|
|
4114
|
+
const tokenEnd = r.tokenEnd > r.start ? (L.pe[Math.min(r.tokenEnd, L.text.length) - 1] ?? end) : end;
|
|
4115
|
+
out.push({ ...r, start, end, tokenEnd });
|
|
4116
|
+
}
|
|
3940
4117
|
}
|
|
3941
4118
|
function parserViewLayer(text) {
|
|
3942
4119
|
if (!/[\t\n\r]/.test(text))
|
|
@@ -3989,7 +4166,7 @@ function editsToCandidates(edits, cls, out, te = -1) {
|
|
|
3989
4166
|
const kind = KIND_BY_TEXT.get(e.text);
|
|
3990
4167
|
if (kind === undefined || e.end <= e.start)
|
|
3991
4168
|
continue;
|
|
3992
|
-
out.push({ a: e.start, b: e.end, kind, cls, te });
|
|
4169
|
+
out.push(e.phases === undefined ? { a: e.start, b: e.end, kind, cls, te } : { a: e.start, b: e.end, kind, cls, te, phases: e.phases });
|
|
3993
4170
|
}
|
|
3994
4171
|
}
|
|
3995
4172
|
function pemRegions(recognized) {
|
|
@@ -4207,7 +4384,15 @@ function toRaw(S, c) {
|
|
|
4207
4384
|
if (a >= b)
|
|
4208
4385
|
return null;
|
|
4209
4386
|
const te = c.te > b ? S.rawEnd(c.te - 1) : S.rawEnd(b - 1);
|
|
4210
|
-
|
|
4387
|
+
const r = { start: S.rawStart(a), end: S.rawEnd(b - 1), kind: c.kind, cls: c.cls, tokenEnd: te };
|
|
4388
|
+
return c.phases === undefined ? r : { ...r, phases: c.phases };
|
|
4389
|
+
}
|
|
4390
|
+
function runLabelPasses(S, regions, cands, blocks) {
|
|
4391
|
+
labelCandidates(S, 'scheme', regions, cands, blocks);
|
|
4392
|
+
labelCandidates(S, 'token', regions, cands, blocks);
|
|
4393
|
+
labelCandidates(S, 'label', regions, cands, blocks);
|
|
4394
|
+
labelCandidates(S, 'scheme', regions, cands, blocks, true);
|
|
4395
|
+
labelCandidates(S, 'label', regions, cands, blocks, true);
|
|
4211
4396
|
}
|
|
4212
4397
|
function collectCandidates(text, o, nested) {
|
|
4213
4398
|
const V = buildScanView(text, o);
|
|
@@ -4249,14 +4434,11 @@ function collectCandidates(text, o, nested) {
|
|
|
4249
4434
|
if (r[2] === 'host')
|
|
4250
4435
|
regions.push(r);
|
|
4251
4436
|
}
|
|
4437
|
+
anchoredFormCandidates(S.text, cands);
|
|
4252
4438
|
if (o.words) {
|
|
4253
4439
|
editsToCandidates(pemEdits(S, (blk) => { if (S === regionSurface)
|
|
4254
4440
|
pemBlocksSeen.push(pemBlockToRaw(S, blk)); }), 'pem', cands);
|
|
4255
|
-
|
|
4256
|
-
labelCandidates(S, 'token', regions, cands, blocks);
|
|
4257
|
-
labelCandidates(S, 'label', regions, cands, blocks);
|
|
4258
|
-
labelCandidates(S, 'scheme', regions, cands, blocks, true);
|
|
4259
|
-
labelCandidates(S, 'label', regions, cands, blocks, true);
|
|
4441
|
+
runLabelPasses(S, regions, cands, blocks);
|
|
4260
4442
|
editsToCandidates(authParamEdits(S.text), 'param', cands);
|
|
4261
4443
|
editsToCandidates(proseLiteralEdits(S.text), 'prose', cands);
|
|
4262
4444
|
}
|
|
@@ -4266,30 +4448,107 @@ function collectCandidates(text, o, nested) {
|
|
|
4266
4448
|
raw.push(S.rawDot !== null ? { ...r, dotted: true } : r);
|
|
4267
4449
|
}
|
|
4268
4450
|
}
|
|
4451
|
+
if (o.words)
|
|
4452
|
+
for (const L of decoded.locals)
|
|
4453
|
+
decodedLayerLocalCandidates(L, o, raw);
|
|
4269
4454
|
if (!nested) {
|
|
4270
4455
|
for (const [a, b] of V.contents) {
|
|
4271
4456
|
const sub = text.slice(a, b);
|
|
4272
4457
|
const inner = collectCandidates(sub, o, true);
|
|
4273
|
-
for (const iv of
|
|
4274
|
-
|
|
4458
|
+
for (const [iv, phases] of resolveEachPhase(sub, inner, o)) {
|
|
4459
|
+
const c = { start: a + iv.start, end: a + iv.end, kind: iv.kind, cls: 'nested', tokenEnd: a + iv.end, pretrimmed: true };
|
|
4460
|
+
raw.push(phases === undefined ? c : { ...c, phases });
|
|
4275
4461
|
}
|
|
4276
4462
|
}
|
|
4277
4463
|
for (const c of [...screen.contents, ...decodedContents]) {
|
|
4278
4464
|
const inner = collectCandidates(c.sub, o, true);
|
|
4279
|
-
for (const iv of
|
|
4465
|
+
for (const [iv, phases] of resolveEachPhase(c.sub, inner, o)) {
|
|
4280
4466
|
const start = c.rawAt(iv.start);
|
|
4281
4467
|
const end = c.rawEndAt(iv.end - 1);
|
|
4282
|
-
if (end
|
|
4283
|
-
|
|
4468
|
+
if (end <= start)
|
|
4469
|
+
continue;
|
|
4470
|
+
const r = { start, end, kind: iv.kind, cls: 'nested', tokenEnd: end, pretrimmed: true };
|
|
4471
|
+
raw.push(phases === undefined ? r : { ...r, phases });
|
|
4284
4472
|
}
|
|
4285
4473
|
}
|
|
4286
4474
|
}
|
|
4287
4475
|
return { cands: raw, rawUnit: V.rawUnit, rawDot: screen.surfaces[0]?.rawDot ?? null, rawSoft: screen.rawSoft, rawPlain: screen.rawPlain, pemBlocksSeen };
|
|
4288
4476
|
}
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4477
|
+
const RULES_BY_VERSION = {
|
|
4478
|
+
'0.102.0': [
|
|
4479
|
+
{ id: 'path-slot', ticket: 'CC-849', kind: 'generator' },
|
|
4480
|
+
{
|
|
4481
|
+
id: 'anchored-form:slack-webhook-url',
|
|
4482
|
+
ticket: 'CC-849',
|
|
4483
|
+
kind: 'generator',
|
|
4484
|
+
form: { host: 'hooks.slack.com', trailingDot: true, pathKinds: ['services', 'workflows', 'triggers'], tailClass: 'A-Za-z0-9+/_-', minTailLength: 40 },
|
|
4485
|
+
},
|
|
4486
|
+
],
|
|
4487
|
+
};
|
|
4488
|
+
const RULE_ROWS_ARE_GENERATORS = true;
|
|
4489
|
+
void RULE_ROWS_ARE_GENERATORS;
|
|
4490
|
+
function rowPhaseTable() {
|
|
4491
|
+
const m = new Map();
|
|
4492
|
+
const keys = Object.keys(RULES_BY_VERSION);
|
|
4493
|
+
keys.forEach((k, j) => {
|
|
4494
|
+
for (const row of RULES_BY_VERSION[k])
|
|
4495
|
+
m.set(row.id, j + 1);
|
|
4496
|
+
});
|
|
4497
|
+
return m;
|
|
4498
|
+
}
|
|
4499
|
+
const ROW_PHASE = rowPhaseTable();
|
|
4500
|
+
const LAST_PHASE = Object.keys(RULES_BY_VERSION).length;
|
|
4501
|
+
const ANCHORED_FORM_ROWS = Object.values(RULES_BY_VERSION)
|
|
4502
|
+
.flatMap((rows) => rows.filter((r) => 'form' in r))
|
|
4503
|
+
.map((r) => ({ id: r.id, form: r.form, probe: new RegExp(r.form.host.split('.').join('\\.'), 'i'), pattern: anchoredFormPattern(r.form) }));
|
|
4504
|
+
let scanUpto = LAST_PHASE;
|
|
4505
|
+
const phaseRange = (from, to) => (to < from ? 0 : ((1 << (to + 1)) - 1) & ~((1 << from) - 1));
|
|
4506
|
+
const phasesOrAll = (mask) => (mask === phaseRange(0, scanUpto) ? undefined : mask);
|
|
4507
|
+
const inPhase = (phases, k) => phases === undefined || ((phases >> k) & 1) === 1;
|
|
4508
|
+
function emitRow(rowId, emit) {
|
|
4509
|
+
const p = ROW_PHASE.get(rowId) ?? Number.POSITIVE_INFINITY;
|
|
4510
|
+
if (p > scanUpto)
|
|
4511
|
+
return;
|
|
4512
|
+
emit(phaseRange(p, scanUpto));
|
|
4513
|
+
}
|
|
4514
|
+
function resolveEachPhase(text, c, o) {
|
|
4515
|
+
const pems = o.words ? pemRegions(c.pemBlocksSeen) : [];
|
|
4516
|
+
const run = (cs) => resolveCandidates(text, cs, c.rawUnit, c.rawDot, pems, c.rawSoft, c.rawPlain);
|
|
4517
|
+
if (!c.cands.some((x) => x.phases !== undefined))
|
|
4518
|
+
return run(c.cands).map((iv) => [iv, undefined]);
|
|
4519
|
+
const per = [];
|
|
4520
|
+
for (let k = 0; k <= scanUpto; k++)
|
|
4521
|
+
per.push(run(c.cands.filter((x) => inPhase(x.phases, k))));
|
|
4522
|
+
const key = (ivs) => ivs.map((iv) => `${iv.start}:${iv.end}:${iv.kind}`).join(',');
|
|
4523
|
+
const k0 = key(per[0] ?? []);
|
|
4524
|
+
if (per.every((ivs) => key(ivs) === k0))
|
|
4525
|
+
return (per[0] ?? []).map((iv) => [iv, undefined]);
|
|
4526
|
+
const out = [];
|
|
4527
|
+
per.forEach((ivs, k) => {
|
|
4528
|
+
for (const iv of ivs)
|
|
4529
|
+
out.push([iv, 1 << k]);
|
|
4530
|
+
});
|
|
4531
|
+
return out;
|
|
4532
|
+
}
|
|
4533
|
+
function scanPhases(text, o, trace, upto) {
|
|
4534
|
+
const saved = scanUpto;
|
|
4535
|
+
scanUpto = upto;
|
|
4536
|
+
try {
|
|
4537
|
+
const c = collectCandidates(text, o, false);
|
|
4538
|
+
const pems = o.words ? pemRegions(c.pemBlocksSeen) : [];
|
|
4539
|
+
const run = (cs) => materialize(text, resolveCandidates(text, cs, c.rawUnit, c.rawDot, pems, c.rawSoft, c.rawPlain), trace);
|
|
4540
|
+
if (!c.cands.some((x) => x.phases !== undefined)) {
|
|
4541
|
+
const one = run(c.cands);
|
|
4542
|
+
return Array.from({ length: upto + 1 }, () => one);
|
|
4543
|
+
}
|
|
4544
|
+
const outs = [];
|
|
4545
|
+
for (let k = 0; k <= upto; k++)
|
|
4546
|
+
outs.push(run(c.cands.filter((x) => inPhase(x.phases, k))));
|
|
4547
|
+
return outs;
|
|
4548
|
+
}
|
|
4549
|
+
finally {
|
|
4550
|
+
scanUpto = saved;
|
|
4551
|
+
}
|
|
4293
4552
|
}
|
|
4294
4553
|
const MAX_WASH_REWRITES = 8;
|
|
4295
4554
|
function composeOrigin(first, second) {
|
|
@@ -4304,36 +4563,76 @@ function composeOrigin(first, second) {
|
|
|
4304
4563
|
}
|
|
4305
4564
|
return out;
|
|
4306
4565
|
}
|
|
4307
|
-
function scanAndMask(text, o, trace, stats) {
|
|
4566
|
+
function scanAndMask(text, o, trace, stats, phaseOut) {
|
|
4308
4567
|
if (!o.urls && !o.words) {
|
|
4309
4568
|
if (stats !== undefined) {
|
|
4310
4569
|
stats.passes = 0;
|
|
4311
4570
|
stats.capped = false;
|
|
4571
|
+
stats.collections = 0;
|
|
4312
4572
|
}
|
|
4573
|
+
phaseOut?.push({ text });
|
|
4313
4574
|
return { text };
|
|
4314
4575
|
}
|
|
4315
|
-
|
|
4316
|
-
let
|
|
4576
|
+
const upto = scanUpto;
|
|
4577
|
+
let memoText = null;
|
|
4578
|
+
let memo = [];
|
|
4579
|
+
let collections = 0;
|
|
4580
|
+
let passes = 0;
|
|
4581
|
+
const op = (t, k) => {
|
|
4582
|
+
if (t !== memoText) {
|
|
4583
|
+
memo = scanPhases(t, o, trace, upto);
|
|
4584
|
+
memoText = t;
|
|
4585
|
+
collections++;
|
|
4586
|
+
}
|
|
4587
|
+
passes++;
|
|
4588
|
+
return memo[k] ?? { text: t };
|
|
4589
|
+
};
|
|
4590
|
+
const advance = (cur, next) => {
|
|
4591
|
+
const origin = trace ? composeOrigin(cur.origin, next.origin) : undefined;
|
|
4592
|
+
return origin === undefined ? { text: next.text } : { text: next.text, origin };
|
|
4593
|
+
};
|
|
4594
|
+
let cur = op(text, 0);
|
|
4317
4595
|
let rewrites = cur.text !== text ? 1 : 0;
|
|
4318
4596
|
let changed = rewrites > 0;
|
|
4319
4597
|
while (changed && rewrites < MAX_WASH_REWRITES) {
|
|
4320
|
-
const next =
|
|
4321
|
-
passes++;
|
|
4598
|
+
const next = op(cur.text, 0);
|
|
4322
4599
|
changed = next.text !== cur.text;
|
|
4323
4600
|
if (!changed)
|
|
4324
4601
|
break;
|
|
4325
4602
|
rewrites++;
|
|
4326
|
-
|
|
4327
|
-
|
|
4603
|
+
cur = advance(cur, next);
|
|
4604
|
+
}
|
|
4605
|
+
const stable = [!changed];
|
|
4606
|
+
phaseOut?.push(cur);
|
|
4607
|
+
for (let j = 1; j <= upto; j++) {
|
|
4608
|
+
stable.push(false);
|
|
4609
|
+
let rw = 0;
|
|
4610
|
+
let k = j;
|
|
4611
|
+
while (rw < MAX_WASH_REWRITES && !stable.every(Boolean)) {
|
|
4612
|
+
if (stable[k] === true) {
|
|
4613
|
+
k = (k + j) % (j + 1);
|
|
4614
|
+
continue;
|
|
4615
|
+
}
|
|
4616
|
+
const next = op(cur.text, k);
|
|
4617
|
+
if (next.text === cur.text)
|
|
4618
|
+
stable[k] = true;
|
|
4619
|
+
else {
|
|
4620
|
+
rw++;
|
|
4621
|
+
cur = advance(cur, next);
|
|
4622
|
+
stable.fill(false);
|
|
4623
|
+
}
|
|
4624
|
+
k = (k + j) % (j + 1);
|
|
4625
|
+
}
|
|
4626
|
+
phaseOut?.push(cur);
|
|
4328
4627
|
}
|
|
4329
4628
|
if (stats !== undefined) {
|
|
4330
4629
|
let capped = false;
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
}
|
|
4630
|
+
for (let k = 0; k < stable.length; k++)
|
|
4631
|
+
if (stable[k] !== true && op(cur.text, k).text !== cur.text)
|
|
4632
|
+
capped = true;
|
|
4335
4633
|
stats.passes = passes;
|
|
4336
4634
|
stats.capped = capped;
|
|
4635
|
+
stats.collections = collections;
|
|
4337
4636
|
}
|
|
4338
4637
|
return cur;
|
|
4339
4638
|
}
|
|
@@ -4732,14 +5031,28 @@ function scanOptionsOf(o, face, queryByShape = false, wholeAddress = false) {
|
|
|
4732
5031
|
};
|
|
4733
5032
|
}
|
|
4734
5033
|
export function credentialWashPasses(text, opts = {}) {
|
|
4735
|
-
const input =
|
|
4736
|
-
const stats = { passes: 0, capped: false };
|
|
5034
|
+
const input = displayInputText(text);
|
|
5035
|
+
const stats = { passes: 0, capped: false, collections: 0 };
|
|
4737
5036
|
const scan = opts === null ? WASH_OPTIONS : scanOptionsOf(opts, publicFace(opts));
|
|
4738
5037
|
scanAndMask(input, scan, false, stats);
|
|
4739
|
-
return { passes: stats.passes, capped: stats.capped };
|
|
5038
|
+
return { collections: stats.collections, passes: stats.passes, capped: stats.capped };
|
|
5039
|
+
}
|
|
5040
|
+
function displayInputText(text) {
|
|
5041
|
+
switch (typeof text) {
|
|
5042
|
+
case 'string':
|
|
5043
|
+
return text;
|
|
5044
|
+
case 'number':
|
|
5045
|
+
case 'bigint':
|
|
5046
|
+
case 'boolean':
|
|
5047
|
+
return String(text);
|
|
5048
|
+
case 'undefined':
|
|
5049
|
+
return '';
|
|
5050
|
+
default:
|
|
5051
|
+
return text === null ? '' : REDACTED_SECRET;
|
|
5052
|
+
}
|
|
4740
5053
|
}
|
|
4741
5054
|
function renderUntrusted(text, opts, ledger, queryByShape = false, wholeAddress = false) {
|
|
4742
|
-
const input =
|
|
5055
|
+
const input = displayInputText(text);
|
|
4743
5056
|
const o = opts ?? {};
|
|
4744
5057
|
const face = publicFace(o);
|
|
4745
5058
|
const scan = scanOptionsOf(o, face, queryByShape, wholeAddress);
|
|
@@ -4938,51 +5251,74 @@ function hasOpaquePiece(text) {
|
|
|
4938
5251
|
}
|
|
4939
5252
|
return false;
|
|
4940
5253
|
}
|
|
4941
|
-
function
|
|
4942
|
-
const
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
if (
|
|
4946
|
-
|
|
4947
|
-
|
|
4948
|
-
|
|
5254
|
+
function carriesCredentialStructurePhases(value) {
|
|
5255
|
+
const all = phaseRange(0, scanUpto);
|
|
5256
|
+
let hit = 0;
|
|
5257
|
+
const net = (v) => {
|
|
5258
|
+
if (hasOpaquePiece(v)) {
|
|
5259
|
+
hit = all;
|
|
5260
|
+
return;
|
|
5261
|
+
}
|
|
5262
|
+
hit |= washChangesPhases(v);
|
|
5263
|
+
if (hit === all || !v.includes('+'))
|
|
5264
|
+
return;
|
|
5265
|
+
hit |= washChangesPhases(v.split('+').join(' '));
|
|
4949
5266
|
};
|
|
4950
5267
|
let view = value;
|
|
4951
5268
|
for (let layer = 0; layer < MAX_PERCENT_VIEW_LAYERS; layer++) {
|
|
4952
|
-
|
|
4953
|
-
|
|
5269
|
+
net(view);
|
|
5270
|
+
if (hit === all)
|
|
5271
|
+
return all;
|
|
4954
5272
|
const next = percentDecodeForMatching(view).decoded;
|
|
4955
5273
|
if (next === view)
|
|
4956
|
-
return
|
|
5274
|
+
return hit;
|
|
4957
5275
|
view = next;
|
|
4958
5276
|
}
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
5277
|
+
net(view);
|
|
5278
|
+
if (hit === all)
|
|
5279
|
+
return all;
|
|
5280
|
+
return percentDecodeForMatching(view).decoded !== view ? all : hit;
|
|
4962
5281
|
}
|
|
4963
|
-
function
|
|
5282
|
+
function washChangesPhases(v) {
|
|
5283
|
+
const ends = [];
|
|
5284
|
+
scanAndMask(v, WASH_OPTIONS, false, undefined, ends);
|
|
5285
|
+
let mask = 0;
|
|
5286
|
+
ends.forEach((t, k) => {
|
|
5287
|
+
if (t.text !== v)
|
|
5288
|
+
mask |= 1 << k;
|
|
5289
|
+
});
|
|
5290
|
+
return mask;
|
|
5291
|
+
}
|
|
5292
|
+
function queryPartPhases(key, value, relax) {
|
|
5293
|
+
const all = phaseRange(0, scanUpto);
|
|
4964
5294
|
if (value.length === 0 || isMarker(value))
|
|
4965
|
-
return
|
|
5295
|
+
return 0;
|
|
4966
5296
|
if (key !== null) {
|
|
4967
5297
|
if (isCredentialLabelName(key))
|
|
4968
|
-
return
|
|
5298
|
+
return all;
|
|
4969
5299
|
if (relax && isNonSecretFieldName(key) && isReadableWordChain(value))
|
|
4970
|
-
return isKnownSecretSegment(value);
|
|
5300
|
+
return isKnownSecretSegment(value) ? all : 0;
|
|
4971
5301
|
}
|
|
4972
|
-
if (isOpaqueSecretValue(value)
|
|
4973
|
-
return
|
|
5302
|
+
if (isOpaqueSecretValue(value))
|
|
5303
|
+
return all;
|
|
5304
|
+
let hit = carriesCredentialStructurePhases(value);
|
|
5305
|
+
if (hit === all)
|
|
5306
|
+
return all;
|
|
4974
5307
|
let from = 0;
|
|
4975
5308
|
for (let i = 0; i <= value.length; i++) {
|
|
4976
5309
|
if (i < value.length && !endsUrlFragmentAt(value, i))
|
|
4977
5310
|
continue;
|
|
4978
5311
|
if (i > from && (from > 0 || i < value.length)) {
|
|
4979
5312
|
const chunk = value.slice(from, i);
|
|
4980
|
-
if (isOpaqueSecretValue(chunk)
|
|
4981
|
-
return
|
|
5313
|
+
if (isOpaqueSecretValue(chunk))
|
|
5314
|
+
return all;
|
|
5315
|
+
hit |= carriesCredentialStructurePhases(chunk);
|
|
5316
|
+
if (hit === all)
|
|
5317
|
+
return all;
|
|
4982
5318
|
}
|
|
4983
5319
|
from = i + 1;
|
|
4984
5320
|
}
|
|
4985
|
-
return
|
|
5321
|
+
return hit;
|
|
4986
5322
|
}
|
|
4987
5323
|
const UPLOAD_PROBE_PREFIX = 'https://q.invalid/?';
|
|
4988
5324
|
const UPLOAD_SCAN_OPTIONS = Object.freeze({ urls: true, queryByShape: 'strict', wholeAddress: true, words: true, blanks: false, fold: false, face: null, escapeSpaces: null });
|
|
@@ -4990,27 +5326,421 @@ export function queryCarriesCredential(query) {
|
|
|
4990
5326
|
if (typeof query !== 'string' || query.length === 0)
|
|
4991
5327
|
return false;
|
|
4992
5328
|
const probe = `${UPLOAD_PROBE_PREFIX}${query}`;
|
|
4993
|
-
return
|
|
5329
|
+
return scanAndMask(probe, UPLOAD_SCAN_OPTIONS, false).text !== probe;
|
|
4994
5330
|
}
|
|
4995
5331
|
export function displayConfiguredUrl(url, opts = {}) {
|
|
4996
|
-
const
|
|
5332
|
+
const reading = typeof url === 'string' ? configuredAddressReading(url) : null;
|
|
5333
|
+
const out = renderUntrusted(reading === null ? url : reading.withheld ? REDACTED_SECRET : reading.text, opts, null, 'relaxed', true);
|
|
4997
5334
|
return typeof out === 'string' ? out : out.text;
|
|
4998
5335
|
}
|
|
4999
|
-
function
|
|
5000
|
-
|
|
5001
|
-
|
|
5002
|
-
|
|
5336
|
+
function parserViewOf(url) {
|
|
5337
|
+
return url.replace(/[\t\n\r]/g, '').replace(/^[\u0000-\u0020]+/, '');
|
|
5338
|
+
}
|
|
5339
|
+
const AMBIGUOUS_USERINFO_BOUNDARY = /^(?:[A-Za-z][A-Za-z0-9+.-]*:\/\/|(?:https?|wss?|ftp):[\\/]*)[^/\\?#@]*[?#][^@]*@/i;
|
|
5340
|
+
function userinfoBoundaryAmbiguous(view) {
|
|
5341
|
+
return AMBIGUOUS_USERINFO_BOUNDARY.test(view);
|
|
5342
|
+
}
|
|
5343
|
+
function authorityHasBackslash(view) {
|
|
5344
|
+
const scheme = /^(?:https?|wss?|ftp|file):\/\//i.exec(view);
|
|
5345
|
+
if (scheme === null)
|
|
5346
|
+
return false;
|
|
5347
|
+
const from = scheme[0].length;
|
|
5348
|
+
let end = from;
|
|
5349
|
+
while (end < view.length && !'/?#'.includes(view.charAt(end)))
|
|
5350
|
+
end++;
|
|
5351
|
+
const marks = markerSpans(view);
|
|
5352
|
+
for (let s = 0; s < marks.length; s += 2)
|
|
5353
|
+
if ((marks[s] ?? end) >= from && (marks[s] ?? end) < end)
|
|
5354
|
+
return false;
|
|
5355
|
+
let backslash = false;
|
|
5356
|
+
for (let k = from; k < end; k++) {
|
|
5357
|
+
if (view.charAt(k) !== '\\')
|
|
5358
|
+
continue;
|
|
5359
|
+
if (outletAtomEnd(view, k) > k)
|
|
5360
|
+
return false;
|
|
5361
|
+
backslash = true;
|
|
5362
|
+
}
|
|
5363
|
+
return backslash;
|
|
5364
|
+
}
|
|
5365
|
+
function outletAtomEnd(text, at) {
|
|
5366
|
+
return escapeTokenAt(text, at)?.end ?? (nameBlankTokenAt(text, at) !== -1 ? at + 6 : -1);
|
|
5367
|
+
}
|
|
5368
|
+
function rebuiltAddress(url) {
|
|
5003
5369
|
let u;
|
|
5004
5370
|
try {
|
|
5005
5371
|
u = new URL(url);
|
|
5006
5372
|
}
|
|
5007
5373
|
catch {
|
|
5008
|
-
return
|
|
5374
|
+
return null;
|
|
5009
5375
|
}
|
|
5010
5376
|
if (u.host === '')
|
|
5011
|
-
return
|
|
5377
|
+
return null;
|
|
5012
5378
|
const userinfo = u.username !== '' || u.password !== '' ? `${u.username}${u.password !== '' ? `:${u.password}` : ''}@` : '';
|
|
5013
|
-
|
|
5379
|
+
const text = `${u.protocol}//${userinfo}${u.host}${u.pathname}${u.search}${u.hash}`;
|
|
5380
|
+
const fwdA = new Int32Array(url.length).fill(-2);
|
|
5381
|
+
const fwdB = new Int32Array(url.length).fill(-2);
|
|
5382
|
+
const backA = new Int32Array(text.length).fill(-2);
|
|
5383
|
+
const backB = new Int32Array(text.length).fill(-2);
|
|
5384
|
+
const parts = new Int8Array(url.length);
|
|
5385
|
+
const out = { text, toRebuilt: [fwdA, fwdB], toOriginal: [backA, backB], parts };
|
|
5386
|
+
const encoder = new TextEncoder();
|
|
5387
|
+
const at = [];
|
|
5388
|
+
for (let i = 0; i < url.length; i++) {
|
|
5389
|
+
const c = url.charCodeAt(i);
|
|
5390
|
+
if (c === 0x09 || c === 0x0a || c === 0x0d)
|
|
5391
|
+
fwdA[i] = -1;
|
|
5392
|
+
else
|
|
5393
|
+
at.push(i);
|
|
5394
|
+
}
|
|
5395
|
+
let a = 0;
|
|
5396
|
+
let b = at.length;
|
|
5397
|
+
while (a < b && url.charCodeAt(at[a] ?? 0) <= 0x20)
|
|
5398
|
+
fwdA[at[a++] ?? 0] = -1;
|
|
5399
|
+
while (b > a && url.charCodeAt(at[b - 1] ?? 0) <= 0x20)
|
|
5400
|
+
fwdA[at[--b] ?? 0] = -1;
|
|
5401
|
+
const ch = (k) => url.charAt(at[k] ?? -1);
|
|
5402
|
+
let e = a;
|
|
5403
|
+
while (e < b && ch(e) !== ':')
|
|
5404
|
+
e++;
|
|
5405
|
+
const scheme = at.slice(a, e).map((i) => url.charAt(i)).join('');
|
|
5406
|
+
if (e === b || !/^(?:https?|wss?|ftp)$/i.test(scheme))
|
|
5407
|
+
return out;
|
|
5408
|
+
const align = (from, to, rFrom, rTo, mode, part) => {
|
|
5409
|
+
const pairs = [];
|
|
5410
|
+
let r = rFrom;
|
|
5411
|
+
for (let k = from; k < to;) {
|
|
5412
|
+
const i = at[k] ?? -1;
|
|
5413
|
+
const cp = url.codePointAt(i) ?? 0;
|
|
5414
|
+
const wide = cp > 0xffff && k + 1 < to && at[k + 1] === i + 1;
|
|
5415
|
+
const c = wide ? String.fromCodePoint(cp) : url.charAt(i);
|
|
5416
|
+
const step = c.length;
|
|
5417
|
+
let len = -1;
|
|
5418
|
+
if (text.startsWith(c, r))
|
|
5419
|
+
len = c.length;
|
|
5420
|
+
else if (mode === 'fold' && c.length === 1 && /[A-Z]/.test(c) && text.charAt(r) === c.toLowerCase())
|
|
5421
|
+
len = 1;
|
|
5422
|
+
else if (mode === 'path' && c === '\\' && text.charAt(r) === '/')
|
|
5423
|
+
len = 1;
|
|
5424
|
+
else if (mode === 'encoded' || mode === 'path') {
|
|
5425
|
+
const enc = [...encoder.encode(c)].map((x) => `%${x.toString(16).toUpperCase().padStart(2, '0')}`).join('');
|
|
5426
|
+
if (text.startsWith(enc, r))
|
|
5427
|
+
len = enc.length;
|
|
5428
|
+
}
|
|
5429
|
+
if (len < 0 || r + len > rTo)
|
|
5430
|
+
return;
|
|
5431
|
+
pairs.push(i, step, r, r + len);
|
|
5432
|
+
r += len;
|
|
5433
|
+
k += step;
|
|
5434
|
+
}
|
|
5435
|
+
if (r !== rTo)
|
|
5436
|
+
return;
|
|
5437
|
+
for (let p = 0; p < pairs.length; p += 4) {
|
|
5438
|
+
const i = pairs[p] ?? -1;
|
|
5439
|
+
const n = pairs[p + 1] ?? 1;
|
|
5440
|
+
const s = pairs[p + 2] ?? 0;
|
|
5441
|
+
const t = pairs[p + 3] ?? 0;
|
|
5442
|
+
for (let j = i; j < i + n; j++) {
|
|
5443
|
+
fwdA[j] = s;
|
|
5444
|
+
fwdB[j] = t;
|
|
5445
|
+
parts[j] = part;
|
|
5446
|
+
}
|
|
5447
|
+
backA.fill(i, s, t);
|
|
5448
|
+
backB.fill(i + n, s, t);
|
|
5449
|
+
}
|
|
5450
|
+
};
|
|
5451
|
+
const drop = (from, to) => {
|
|
5452
|
+
for (let k = from; k < to; k++)
|
|
5453
|
+
fwdA[at[k] ?? -1] = -1;
|
|
5454
|
+
};
|
|
5455
|
+
const insert = (rFrom, rTo) => {
|
|
5456
|
+
backA.fill(-1, rFrom, rTo);
|
|
5457
|
+
};
|
|
5458
|
+
align(a, e + 1, 0, u.protocol.length, 'fold', 1);
|
|
5459
|
+
let k = e + 1;
|
|
5460
|
+
while (k < b && (ch(k) === '/' || ch(k) === '\\'))
|
|
5461
|
+
k++;
|
|
5462
|
+
drop(e + 1, k);
|
|
5463
|
+
insert(u.protocol.length, u.protocol.length + 2);
|
|
5464
|
+
let r = u.protocol.length + 2;
|
|
5465
|
+
let end = k;
|
|
5466
|
+
while (end < b && !'/\\?#'.includes(ch(end)))
|
|
5467
|
+
end++;
|
|
5468
|
+
let lastAt = -1;
|
|
5469
|
+
for (let j = k; j < end; j++)
|
|
5470
|
+
if (ch(j) === '@')
|
|
5471
|
+
lastAt = j;
|
|
5472
|
+
if (lastAt >= 0) {
|
|
5473
|
+
let colon = lastAt;
|
|
5474
|
+
for (let j = k; j < lastAt; j++)
|
|
5475
|
+
if (ch(j) === ':') {
|
|
5476
|
+
colon = j;
|
|
5477
|
+
break;
|
|
5478
|
+
}
|
|
5479
|
+
align(k, colon, r, r + u.username.length, 'encoded', 2);
|
|
5480
|
+
r += u.username.length;
|
|
5481
|
+
if (colon < lastAt) {
|
|
5482
|
+
if (u.password !== '') {
|
|
5483
|
+
align(colon, colon + 1, r, r + 1, 'exact', 2);
|
|
5484
|
+
r += 1;
|
|
5485
|
+
}
|
|
5486
|
+
else
|
|
5487
|
+
drop(colon, colon + 1);
|
|
5488
|
+
align(colon + 1, lastAt, r, r + u.password.length, 'encoded', 2);
|
|
5489
|
+
r += u.password.length;
|
|
5490
|
+
}
|
|
5491
|
+
if (userinfo !== '') {
|
|
5492
|
+
align(lastAt, lastAt + 1, r, r + 1, 'exact', 3);
|
|
5493
|
+
r += 1;
|
|
5494
|
+
}
|
|
5495
|
+
else
|
|
5496
|
+
drop(lastAt, lastAt + 1);
|
|
5497
|
+
k = lastAt + 1;
|
|
5498
|
+
}
|
|
5499
|
+
let portColon = end;
|
|
5500
|
+
let bracket = false;
|
|
5501
|
+
for (let j = k; j < end; j++) {
|
|
5502
|
+
const c = ch(j);
|
|
5503
|
+
if (c === '[')
|
|
5504
|
+
bracket = true;
|
|
5505
|
+
else if (c === ']')
|
|
5506
|
+
bracket = false;
|
|
5507
|
+
else if (c === ':' && !bracket) {
|
|
5508
|
+
portColon = j;
|
|
5509
|
+
break;
|
|
5510
|
+
}
|
|
5511
|
+
}
|
|
5512
|
+
align(k, portColon, r, r + u.hostname.length, 'fold', 4);
|
|
5513
|
+
r += u.hostname.length;
|
|
5514
|
+
if (portColon < end) {
|
|
5515
|
+
if (u.port !== '') {
|
|
5516
|
+
align(portColon, end, r, r + 1 + u.port.length, 'exact', 5);
|
|
5517
|
+
r += 1 + u.port.length;
|
|
5518
|
+
}
|
|
5519
|
+
else
|
|
5520
|
+
drop(portColon, end);
|
|
5521
|
+
}
|
|
5522
|
+
let q = end;
|
|
5523
|
+
if (q < b && (ch(q) === '/' || ch(q) === '\\'))
|
|
5524
|
+
while (q < b && ch(q) !== '?' && ch(q) !== '#')
|
|
5525
|
+
q++;
|
|
5526
|
+
if (q === end)
|
|
5527
|
+
insert(r, r + u.pathname.length);
|
|
5528
|
+
else
|
|
5529
|
+
align(end, q, r, r + u.pathname.length, 'path', 6);
|
|
5530
|
+
r += u.pathname.length;
|
|
5531
|
+
let h = q;
|
|
5532
|
+
if (h < b && ch(h) === '?')
|
|
5533
|
+
while (h < b && ch(h) !== '#')
|
|
5534
|
+
h++;
|
|
5535
|
+
if (h - q === 1)
|
|
5536
|
+
drop(q, h);
|
|
5537
|
+
else if (h > q)
|
|
5538
|
+
align(q, h, r, r + u.search.length, 'encoded', 7);
|
|
5539
|
+
r += u.search.length;
|
|
5540
|
+
if (b - h === 1)
|
|
5541
|
+
drop(h, b);
|
|
5542
|
+
else if (b > h)
|
|
5543
|
+
align(h, b, r, r + u.hash.length, 'encoded', 8);
|
|
5544
|
+
return out;
|
|
5545
|
+
}
|
|
5546
|
+
function restoreAtoms(url, c) {
|
|
5547
|
+
const atoms = [];
|
|
5548
|
+
const marks = markerSpans(url);
|
|
5549
|
+
for (let s = 0; s + 1 < marks.length; s += 2)
|
|
5550
|
+
atoms.push([marks[s] ?? 0, marks[s + 1] ?? 0]);
|
|
5551
|
+
for (let i = url.indexOf('\\'); i >= 0; i = url.indexOf('\\', i + 1)) {
|
|
5552
|
+
const end = outletAtomEnd(url, i);
|
|
5553
|
+
if (end > i)
|
|
5554
|
+
atoms.push([i, end]);
|
|
5555
|
+
}
|
|
5556
|
+
atoms.sort((x, y) => x[0] - y[0]);
|
|
5557
|
+
const [fwdA, fwdB] = c.toRebuilt;
|
|
5558
|
+
const [backA, backB] = c.toOriginal;
|
|
5559
|
+
const swaps = [];
|
|
5560
|
+
for (const [from, to] of atoms) {
|
|
5561
|
+
let ok = (fwdA[from] ?? -1) >= 0;
|
|
5562
|
+
for (let i = from; ok && i + 1 < to; i++)
|
|
5563
|
+
ok = (fwdA[i + 1] ?? -1) >= 0 && fwdB[i] === fwdA[i + 1];
|
|
5564
|
+
if (ok)
|
|
5565
|
+
swaps.push(fwdA[from] ?? 0, fwdB[to - 1] ?? 0, from, to);
|
|
5566
|
+
}
|
|
5567
|
+
if (swaps.length === 0)
|
|
5568
|
+
return c;
|
|
5569
|
+
const old = c.text;
|
|
5570
|
+
const shift = new Int32Array(old.length + 1);
|
|
5571
|
+
let text = '';
|
|
5572
|
+
const nA = [];
|
|
5573
|
+
const nB = [];
|
|
5574
|
+
let w = 0;
|
|
5575
|
+
for (let k = 0; k <= old.length;) {
|
|
5576
|
+
if (w < swaps.length && k === swaps[w]) {
|
|
5577
|
+
const rTo = swaps[w + 1] ?? k;
|
|
5578
|
+
const from = swaps[w + 2] ?? 0;
|
|
5579
|
+
const to = swaps[w + 3] ?? 0;
|
|
5580
|
+
shift[k] = text.length;
|
|
5581
|
+
for (let j = k + 1; j < rTo; j++)
|
|
5582
|
+
shift[j] = -1;
|
|
5583
|
+
for (let i = from; i < to; i++) {
|
|
5584
|
+
fwdA[i] = text.length;
|
|
5585
|
+
fwdB[i] = text.length + 1;
|
|
5586
|
+
nA.push(i);
|
|
5587
|
+
nB.push(i + 1);
|
|
5588
|
+
text += url.charAt(i);
|
|
5589
|
+
}
|
|
5590
|
+
w += 4;
|
|
5591
|
+
k = rTo;
|
|
5592
|
+
continue;
|
|
5593
|
+
}
|
|
5594
|
+
shift[k] = text.length;
|
|
5595
|
+
if (k < old.length) {
|
|
5596
|
+
nA.push(backA[k] ?? -2);
|
|
5597
|
+
nB.push(backB[k] ?? -2);
|
|
5598
|
+
text += old.charAt(k);
|
|
5599
|
+
}
|
|
5600
|
+
k++;
|
|
5601
|
+
}
|
|
5602
|
+
const inSwap = new Uint8Array(url.length);
|
|
5603
|
+
for (let s = 0; s < swaps.length; s += 4)
|
|
5604
|
+
inSwap.fill(1, swaps[s + 2], swaps[s + 3]);
|
|
5605
|
+
for (let i = 0; i < url.length; i++) {
|
|
5606
|
+
if (inSwap[i] === 1 || (fwdA[i] ?? -2) < 0)
|
|
5607
|
+
continue;
|
|
5608
|
+
fwdA[i] = shift[fwdA[i] ?? 0] ?? -2;
|
|
5609
|
+
fwdB[i] = shift[fwdB[i] ?? 0] ?? -2;
|
|
5610
|
+
}
|
|
5611
|
+
return { text, toRebuilt: [fwdA, fwdB], toOriginal: [Int32Array.from(nA), Int32Array.from(nB)], parts: c.parts };
|
|
5612
|
+
}
|
|
5613
|
+
function hiddenUnits(text, queryByShape) {
|
|
5614
|
+
const r = scanAndMask(text, scanOptionsOf({}, publicFace({}), queryByShape, true), true);
|
|
5615
|
+
const hidden = new Uint8Array(text.length);
|
|
5616
|
+
if (r.text !== text) {
|
|
5617
|
+
if (r.origin === undefined)
|
|
5618
|
+
return null;
|
|
5619
|
+
hidden.fill(1);
|
|
5620
|
+
for (const k of r.origin)
|
|
5621
|
+
if (k >= 0)
|
|
5622
|
+
hidden[k] = 0;
|
|
5623
|
+
}
|
|
5624
|
+
return hidden;
|
|
5625
|
+
}
|
|
5626
|
+
function coversHidden(from, to, image) {
|
|
5627
|
+
for (let i = 0; i < from.length; i++) {
|
|
5628
|
+
if (from[i] !== 1)
|
|
5629
|
+
continue;
|
|
5630
|
+
const s = image[0][i] ?? -2;
|
|
5631
|
+
if (s === -1)
|
|
5632
|
+
continue;
|
|
5633
|
+
if (s === -2)
|
|
5634
|
+
return false;
|
|
5635
|
+
for (let k = s; k < (image[1][i] ?? s); k++)
|
|
5636
|
+
if (to[k] !== 1)
|
|
5637
|
+
return false;
|
|
5638
|
+
}
|
|
5639
|
+
return true;
|
|
5640
|
+
}
|
|
5641
|
+
const CONFIGURED_ADDRESS_WITHHELD = Object.freeze({ withheld: true });
|
|
5642
|
+
function rebuiltKeepsRuns(url, rebuilt, hidden) {
|
|
5643
|
+
const [fwdA, fwdB] = rebuilt.toRebuilt;
|
|
5644
|
+
for (let i = 0; i < url.length;) {
|
|
5645
|
+
if (hidden[i] !== 1) {
|
|
5646
|
+
i++;
|
|
5647
|
+
continue;
|
|
5648
|
+
}
|
|
5649
|
+
let j = i;
|
|
5650
|
+
while (j < url.length && hidden[j] === 1)
|
|
5651
|
+
j++;
|
|
5652
|
+
const s = fwdA[i] ?? -2;
|
|
5653
|
+
const t = fwdB[j - 1] ?? -2;
|
|
5654
|
+
if (s < 0 || t - s !== j - i || rebuilt.text.slice(s, t) !== url.slice(i, j))
|
|
5655
|
+
return false;
|
|
5656
|
+
for (let k = i; k < j; k++)
|
|
5657
|
+
if (rebuilt.parts[k] !== rebuilt.parts[i])
|
|
5658
|
+
return false;
|
|
5659
|
+
i = j;
|
|
5660
|
+
}
|
|
5661
|
+
return true;
|
|
5662
|
+
}
|
|
5663
|
+
function readingOf(url, rebuilt, n1) {
|
|
5664
|
+
if (!n1) {
|
|
5665
|
+
const hidden = hiddenUnits(url, 'strict');
|
|
5666
|
+
return hidden !== null && rebuiltKeepsRuns(url, rebuilt, hidden) ? { withheld: false, text: rebuilt.text } : CONFIGURED_ADDRESS_WITHHELD;
|
|
5667
|
+
}
|
|
5668
|
+
let original = true;
|
|
5669
|
+
let viaRebuilt = true;
|
|
5670
|
+
for (const mode of ['relaxed', 'strict']) {
|
|
5671
|
+
const hiddenOriginal = hiddenUnits(url, mode);
|
|
5672
|
+
const hiddenRebuilt = hiddenUnits(rebuilt.text, mode);
|
|
5673
|
+
if (hiddenOriginal === null || hiddenRebuilt === null)
|
|
5674
|
+
return CONFIGURED_ADDRESS_WITHHELD;
|
|
5675
|
+
original &&= coversHidden(hiddenRebuilt, hiddenOriginal, rebuilt.toOriginal);
|
|
5676
|
+
viaRebuilt &&= coversHidden(hiddenOriginal, hiddenRebuilt, rebuilt.toRebuilt);
|
|
5677
|
+
}
|
|
5678
|
+
return original ? { withheld: false, text: url } : viaRebuilt ? { withheld: false, text: rebuilt.text } : CONFIGURED_ADDRESS_WITHHELD;
|
|
5679
|
+
}
|
|
5680
|
+
function configuredAddressReading(url) {
|
|
5681
|
+
const view = parserViewOf(url);
|
|
5682
|
+
if (userinfoBoundaryAmbiguous(view))
|
|
5683
|
+
return CONFIGURED_ADDRESS_WITHHELD;
|
|
5684
|
+
if (!/^[A-Za-z][A-Za-z0-9+.-]*:/.test(view))
|
|
5685
|
+
return { withheld: false, text: url };
|
|
5686
|
+
if (/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(view)) {
|
|
5687
|
+
const n1 = authorityHasBackslash(view) ? rebuiltAddress(url) : null;
|
|
5688
|
+
return n1 === null ? { withheld: false, text: url } : readingOf(url, restoreAtoms(url, n1), true);
|
|
5689
|
+
}
|
|
5690
|
+
const rebuilt = rebuiltAddress(url);
|
|
5691
|
+
if (rebuilt !== null)
|
|
5692
|
+
return readingOf(url, rebuilt, false);
|
|
5693
|
+
if (/^(?:https?|wss?|ftp):/i.test(view) && /[@?#]/.test(view) && !schemelessUserinfoLeads(view))
|
|
5694
|
+
return CONFIGURED_ADDRESS_WITHHELD;
|
|
5695
|
+
return { withheld: false, text: url };
|
|
5696
|
+
}
|
|
5697
|
+
function schemelessUserinfoLeads(view) {
|
|
5698
|
+
const V = buildScanView(view, WASH_OPTIONS);
|
|
5699
|
+
const S = separatedSurface(view, V);
|
|
5700
|
+
const out = [];
|
|
5701
|
+
userinfoCandidates(S, out, true);
|
|
5702
|
+
return out.some((c) => c.kind === 'userinfo' && S.rawStart(c.a) === 0);
|
|
5703
|
+
}
|
|
5704
|
+
export function configuredValueCarriesCredential(value) {
|
|
5705
|
+
if (typeof value !== 'string' || value.length === 0)
|
|
5706
|
+
return false;
|
|
5707
|
+
const reading = configuredAddressReading(value);
|
|
5708
|
+
if (reading.withheld)
|
|
5709
|
+
return true;
|
|
5710
|
+
const text = reading.text;
|
|
5711
|
+
const r = scanAndMask(text, scanOptionsOf({}, publicFace({}), 'strict', true), true);
|
|
5712
|
+
const origin = r.origin;
|
|
5713
|
+
if (r.text === text || origin === undefined)
|
|
5714
|
+
return false;
|
|
5715
|
+
let prevVisible = -1;
|
|
5716
|
+
for (let k = 0; k < r.text.length;) {
|
|
5717
|
+
const o = origin[k] ?? -1;
|
|
5718
|
+
if (o >= 0) {
|
|
5719
|
+
prevVisible = o;
|
|
5720
|
+
k++;
|
|
5721
|
+
continue;
|
|
5722
|
+
}
|
|
5723
|
+
let e = k;
|
|
5724
|
+
while (e < r.text.length && (origin[e] ?? -1) < 0)
|
|
5725
|
+
e++;
|
|
5726
|
+
const hiddenStart = prevVisible + 1;
|
|
5727
|
+
const hiddenEnd = e < r.text.length ? (origin[e] ?? text.length) : text.length;
|
|
5728
|
+
const shown = r.text.slice(k, e);
|
|
5729
|
+
const re = new RegExp(MARKER_ANYWHERE.source, MARKER_ANYWHERE.flags);
|
|
5730
|
+
for (let m = re.exec(shown); m !== null; m = re.exec(shown)) {
|
|
5731
|
+
const kind = KIND_BY_TEXT.get(m[0]);
|
|
5732
|
+
if (kind === 'userinfo' || kind === 'query' || kind === 'secret')
|
|
5733
|
+
return true;
|
|
5734
|
+
if (kind === 'fragment') {
|
|
5735
|
+
if (hiddenStart === 0 || text[hiddenStart - 1] !== '#')
|
|
5736
|
+
return true;
|
|
5737
|
+
if (queryCarriesCredential(text.slice(hiddenStart, hiddenEnd)))
|
|
5738
|
+
return true;
|
|
5739
|
+
}
|
|
5740
|
+
}
|
|
5741
|
+
k = e;
|
|
5742
|
+
}
|
|
5743
|
+
return false;
|
|
5014
5744
|
}
|
|
5015
5745
|
export function quoteUntrustedForSentence(text, max) {
|
|
5016
5746
|
const shown = displayUntrusted(text, { max, blanks: true, escapeBackslashes: true });
|