From 3635c3a3ee6ecd553eb69b77e1e520efe2e301dc Mon Sep 17 00:00:00 2001
From: Neil <4138956+nwparker@users.noreply.github.com>
Date: Sat, 5 Sep 2026 14:07:00 -0700
Subject: [PATCH] perf(repos): avoid quadratic icon source scans
---
.../repo-icon-source-href-benchmark.mjs | 38 +++++++++++++
src/main/repo-icon-file-detection.test.ts | 56 ++++++++++++++++++-
src/main/repo-icon-file-detection.ts | 10 +---
src/main/repo-icon-source-href.test.ts | 52 +++++++++++++++++
src/main/repo-icon-source-href.ts | 26 +++++++++
5 files changed, 172 insertions(+), 10 deletions(-)
create mode 100644 config/scripts/repo-icon-source-href-benchmark.mjs
create mode 100644 src/main/repo-icon-source-href.test.ts
create mode 100644 src/main/repo-icon-source-href.ts
diff --git a/config/scripts/repo-icon-source-href-benchmark.mjs b/config/scripts/repo-icon-source-href-benchmark.mjs
new file mode 100644
index 00000000000..c408e3a84bf
--- /dev/null
+++ b/config/scripts/repo-icon-source-href-benchmark.mjs
@@ -0,0 +1,38 @@
+import assert from 'node:assert/strict'
+import { performance } from 'node:perf_hooks'
+import { extractIconHref } from '../../src/main/repo-icon-source-href.ts'
+
+// Original production expressions, preserved for the before/after measurement.
+const html =
+ /]*\brel=["'](?:icon|shortcut icon)["'])(?=[^>]*\bhref=["']([^"'?]+))[^>]*>/i
+const object =
+ /(?=[^}]*\brel\s*:\s*["'](?:icon|shortcut icon)["'])(?=[^}]*\bhref\s*:\s*["']([^"'?]+))[^}]*/i
+const original = (source) => source.match(html)?.[1] ?? source.match(object)?.[1] ?? null
+
+function measure(fn, source, repetitions) {
+ const samples = []
+ for (let run = 0; run < repetitions; run++) {
+ const started = performance.now()
+ fn(source)
+ samples.push(performance.now() - started)
+ }
+ return samples.sort((a, b) => a - b)[Math.floor(samples.length / 2)]
+}
+
+const results = []
+for (const size of [8192, 16384, 32768]) {
+ for (const shape of ['no icon', 'rel without href']) {
+ const source = 'a'.repeat(size) + (shape === 'rel without href' ? ' rel:"icon"' : '')
+ assert.equal(extractIconHref(source), original(source))
+ const beforeMs = measure(original, source, 3)
+ const afterMs = measure(extractIconHref, source, 15)
+ results.push({
+ shape,
+ bytes: Buffer.byteLength(source),
+ beforeMs,
+ afterMs,
+ speedup: beforeMs / afterMs
+ })
+ }
+}
+console.log(JSON.stringify({ node: process.version, platform: process.platform, results }, null, 2))
diff --git a/src/main/repo-icon-file-detection.test.ts b/src/main/repo-icon-file-detection.test.ts
index 820b2edddfc..19c895e6024 100644
--- a/src/main/repo-icon-file-detection.test.ts
+++ b/src/main/repo-icon-file-detection.test.ts
@@ -1,4 +1,6 @@
-import { readFile, stat } from 'node:fs/promises'
+import { join } from 'node:path'
+import { tmpdir } from 'node:os'
+import { mkdtemp, mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises'
import type * as FsPromisesModule from 'node:fs/promises'
import { describe, expect, it, vi } from 'vitest'
import type { ExecutionHostFilesystemRoute } from './providers/execution-host-provider-dispatch'
@@ -136,3 +138,55 @@ describe('detectRepoFileIcon connection boundary', () => {
expect(stat).toHaveBeenCalled()
})
})
+
+describe('declared repo icons through production filesystem routes', () => {
+ it.each([
+ ['local', false],
+ ['ssh', false],
+ ['local', true],
+ ['ssh', true]
+ ] as const)('preserves declared icon detection on %s (no icon: %s)', async (kind, noIcon) => {
+ const directory = await mkdtemp(join(tmpdir(), 'orca-icon-href-'))
+ const source = noIcon
+ ? 'a'.repeat(256 * 1024)
+ : `${'a'.repeat(32768)}{ rel: "icon", href: "/first.png", href: "/chosen.png" }`
+ try {
+ await mkdir(join(directory, 'public'))
+ await writeFile(join(directory, 'index.html'), source)
+ await writeFile(join(directory, 'public', 'chosen.png'), Buffer.from(PNG_BASE64, 'base64'))
+ const provider = remoteFilesystemProvider({
+ stat: async (path) => {
+ const info = await stat(path)
+ return {
+ type: info.isFile() ? 'file' : 'directory',
+ size: info.size,
+ mtime: info.mtimeMs
+ }
+ },
+ readFile: async (path) => {
+ const buffer = await readFile(path)
+ const isBinary = path.endsWith('.png')
+ return {
+ content: buffer.toString(isBinary ? 'base64' : 'utf8'),
+ isBinary,
+ mimeType: isBinary ? 'image/png' : 'text/html'
+ }
+ }
+ })
+ const route: ExecutionHostFilesystemRoute =
+ kind === 'local' ? { kind: 'local', hostId: 'local' } : sshRoute('icon-oracle', provider)
+ await expect(detectRepoFileIcon(directory, route)).resolves.toEqual(
+ noIcon
+ ? null
+ : {
+ type: 'image',
+ src: `data:image/png;base64,${PNG_BASE64}`,
+ source: 'file',
+ label: 'public/chosen.png'
+ }
+ )
+ } finally {
+ await rm(directory, { recursive: true, force: true })
+ }
+ })
+})
diff --git a/src/main/repo-icon-file-detection.ts b/src/main/repo-icon-file-detection.ts
index f4289924b08..831248b94b3 100644
--- a/src/main/repo-icon-file-detection.ts
+++ b/src/main/repo-icon-file-detection.ts
@@ -3,6 +3,7 @@ import { buildImageDataUri } from '../shared/image-data-uri'
import { MAX_REPO_ICON_UPLOAD_BYTES, type RepoIcon } from '../shared/repo-icon'
import type { ExecutionHostFilesystemRoute } from './providers/execution-host-provider-dispatch'
import type { IFilesystemProvider } from './providers/types'
+import { extractIconHref } from './repo-icon-source-href'
import { iconHrefCandidates } from './repo-icon-href-candidates'
import { joinWorktreeRelativePath } from './runtime/runtime-relative-paths'
@@ -49,11 +50,6 @@ const REPO_ICON_SOURCE_FILE_CANDIDATES = [
// not read large app entrypoints just to find a small favicon href.
const MAX_REPO_ICON_SOURCE_BYTES = 256 * 1024
-const LINK_ICON_HTML_RE =
- /]*\brel=["'](?:icon|shortcut icon)["'])(?=[^>]*\bhref=["']([^"'?]+))[^>]*>/i
-const LINK_ICON_OBJECT_RE =
- /(?=[^}]*\brel\s*:\s*["'](?:icon|shortcut icon)["'])(?=[^}]*\bhref\s*:\s*["']([^"'?]+))[^}]*/i
-
type DetectedImageFormat = {
mimeType: 'image/png' | 'image/webp'
}
@@ -98,10 +94,6 @@ function detectImageFormat(buffer: Buffer): DetectedImageFormat | null {
return null
}
-function extractIconHref(source: string): string | null {
- return source.match(LINK_ICON_HTML_RE)?.[1] ?? source.match(LINK_ICON_OBJECT_RE)?.[1] ?? null
-}
-
function repoIconFromImageBuffer(buffer: Buffer, relativePath: string): RepoIcon | null {
const format = detectImageFormat(buffer)
if (!format) {
diff --git a/src/main/repo-icon-source-href.test.ts b/src/main/repo-icon-source-href.test.ts
new file mode 100644
index 00000000000..f3991344e59
--- /dev/null
+++ b/src/main/repo-icon-source-href.test.ts
@@ -0,0 +1,52 @@
+import { describe, expect, it } from 'vitest'
+import { extractIconHref } from './repo-icon-source-href'
+
+// Original production expressions are the compatibility oracle.
+const HTML_RE =
+ /]*\brel=["'](?:icon|shortcut icon)["'])(?=[^>]*\bhref=["']([^"'?]+))[^>]*>/i
+const OBJECT_RE =
+ /(?=[^}]*\brel\s*:\s*["'](?:icon|shortcut icon)["'])(?=[^}]*\bhref\s*:\s*["']([^"'?]+))[^}]*/i
+
+export function originalIconHref(source: string): string | null {
+ return source.match(HTML_RE)?.[1] ?? source.match(OBJECT_RE)?.[1] ?? null
+}
+
+describe('repo icon source href compatibility', () => {
+ it.each([
+ '',
+ 'plain source without icon properties',
+ '{ rel: "icon", href: "/first.png", href: "/last.png" }',
+ '{ href: "/first.png", rel: "icon", rel: "stylesheet" }',
+ '{ rel: "icon" } { href: "/unrelated.png" }',
+ '{ rel: "icon", href: "/first.png" } { rel: "icon", href: "/last.png" }',
+ '{ rel: "icon", href: "/object.png" } ',
+ '{ rel: "ICON", href: "/UPPER.png" }',
+ '}\n\n{href: "/line.png",\nrel : "shortcut icon"}',
+ '{ rel: "icon", href: "/unterminated}after brace',
+ '{ rel: "icon", href: "?query" }',
+ '{ rel: "icon", href: "/before?query" }',
+ '',
+ ' {
+ expect(extractIconHref(source)).toBe(originalIconHref(source))
+ })
+
+ it('matches the original across generated malformed property sequences', () => {
+ const tokens = ['}', '{', ' ', 'rel:"icon"', 'href:"a"', 'href:"b"', 'rel:"other"', 'x', '\n']
+ let seed = 97
+ for (let sample = 0; sample < 3000; sample++) {
+ let source = ''
+ for (let token = 0; token < 12; token++) {
+ seed = (Math.imul(seed, 1664525) + 1013904223) >>> 0
+ source += tokens[seed % tokens.length]
+ }
+ expect(extractIconHref(source), source).toBe(originalIconHref(source))
+ }
+ })
+
+ it('handles a maximum-size icon-free entrypoint', () => {
+ expect(extractIconHref('a'.repeat(256 * 1024))).toBeNull()
+ })
+})
diff --git a/src/main/repo-icon-source-href.ts b/src/main/repo-icon-source-href.ts
new file mode 100644
index 00000000000..d07f5fa61c6
--- /dev/null
+++ b/src/main/repo-icon-source-href.ts
@@ -0,0 +1,26 @@
+const LINK_ICON_HTML_RE =
+ /]*\brel=["'](?:icon|shortcut icon)["'])(?=[^>]*\bhref=["']([^"'?]+))[^>]*>/i
+const LINK_ICON_OBJECT_RE =
+ /(?=[^}]*\brel\s*:\s*["'](?:icon|shortcut icon)["'])(?=[^}]*\bhref\s*:\s*["']([^"'?]+))[^}]*/iy
+
+export function extractIconHref(source: string): string | null {
+ const htmlHref = source.match(LINK_ICON_HTML_RE)?.[1]
+ if (htmlHref !== undefined) {
+ return htmlHref
+ }
+ let start = 0
+ while (start <= source.length) {
+ // Every suffix before the next closing brace sees the same candidate properties.
+ LINK_ICON_OBJECT_RE.lastIndex = start
+ const href = LINK_ICON_OBJECT_RE.exec(source)?.[1]
+ if (href !== undefined) {
+ return href
+ }
+ const closingBrace = source.indexOf('}', start)
+ if (closingBrace === -1) {
+ return null
+ }
+ start = closingBrace + 1
+ }
+ return null
+}