diff options
| author | cirakg <cirakg@cirakg.xyz> | 2026-10-27 01:08:30 +0100 |
|---|---|---|
| committer | cirakg <cirakg@cirakg.xyz> | 2026-10-27 01:08:30 +0100 |
| commit | 86c11634379ab87238d794f8f9e8bbc991041e4d (patch) | |
| tree | 4cf3943528c84205a85a33011d8361f17c2c7638 /source/import | |
| parent | bc4cc19df5f53519ca1aabd3cf161b6d78ffc16c (diff) | |
fix(import): splitting pasted otpauth:// links runs no character loop
OtpAuth.splitUris/firstWord looped over every character in one event, so
pasting about 100 links tripped the watchdog (the UI fixture imports Aegis
JSON, so it never ran this path). They now use native searches only. New
make watchdog case uris_100 (13,576 characters, twice per event) trips on
the old code and passes now. fr70: make lint, make test, make watchdog pass.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'source/import')
| -rw-r--r-- | source/import/OtpAuth.mc | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/source/import/OtpAuth.mc b/source/import/OtpAuth.mc index cdf0f9c..f5c487b 100644 --- a/source/import/OtpAuth.mc +++ b/source/import/OtpAuth.mc @@ -21,28 +21,35 @@ module OtpAuth { const MIGRATION_PREFIX = "otpauth-migration://"; // The URIs in text, split at every "otpauth://". Text before the first - // one is ignored here; the importer reports it. + // one is ignored here; the importer reports it. Runs in one event, so + // it uses only native searches: a VM loop over every character of 100 + // pasted links tripped the watchdog. function splitUris(text as String) as Array<String> { var uris = [] as Array<String>; - var at = Text.findIgnoreCase(text, PREFIX, 0); - while (at >= 0) { - var next = Text.findIgnoreCase(text, PREFIX, at + PREFIX.length()); - var end = next >= 0 ? next : text.length(); - uris.add(firstWord(text.substring(at, end) as String)); + var lower = text.toLower(); + var at = lower.find(PREFIX); + while (at != null) { + var from = at + PREFIX.length(); + var found = (lower.substring(from, lower.length()) as String).find(PREFIX); + var next = found != null ? from + found : null; + uris.add(firstWord(text.substring(at, next != null ? next : text.length()) as String)); at = next; } return uris; } // Text up to the first whitespace (a pasted URI never contains any). + // Native searches, no loop over the characters (see splitUris). function firstWord(text as String) as String { - var chars = text.toCharArray(); - for (var i = 0; i < chars.size(); i++) { - if (Text.isSpace(chars[i])) { - return text.substring(0, i) as String; + var end = text.length(); + var spaces = [" ", "\t", "\n", "\r"]; + for (var i = 0; i < spaces.size(); i++) { + var found = text.find(spaces[i]); + if (found != null && found < end) { + end = found; } } - return text; + return end == text.length() ? text : text.substring(0, end) as String; } // One URI as an import item (entry, problem or skip). |
