From 2da977add13abdc6300629400c02538d403c0bd4 Mon Sep 17 00:00:00 2001 From: Jake Savin Date: Tue, 11 Aug 2026 01:24:31 -0700 Subject: [PATCH] fix(odb): #881 repair LF-single-node corruption in webBrowser.openURL and string.isValidUrl Both scripts were stored as a single outline node with embedded LF (0x0A) bytes and zero CR -- the signature of a .ut import path that skipped LF->CR normalization. string.isValidUrl was hard-broken: calling it raised a script error rather than returning a value. Repair is a reinstall-once through script.newScriptObject, whose first operations normalize CRLF and LF to CR, re-splitting the body into proper outline nodes. Compile gate: script.newScriptObject wraps its own compile in try{} and returns true unconditionally, so its return value cannot verify a repair. Each install is therefore followed by a separate script.compile(@adr) call that must return true. The gate was validated against an installer-unrepairable negative control (unbalanced open paren, which auto-close-braces cannot fix): newScriptObject returned true while the independent script.compile correctly failed. Verification, both scripts, in a fresh process after save: - zero LF bytes; CR counts 15 (isValidUrl) and 26 (openURL) - script.compile returns true - isValidUrl("http://example.com") -> true - isValidUrl("file:///tmp/x.html") -> true - isValidUrl("javascript:alert(1)") -> false - isValidUrl("notaurl") -> false Before the repair the first of these was a script error, not false. The .ut mirror was re-synced from the repaired ODB via verify_virgin_root_sync.sh --rewrite. The resulting diff is one line per file: the first comment node moves from depth 2 to depth 1. The .ut files carried an illegal +2 indentation jump directly under a depth-0 handler; re-splitting produced the well-formed structure. No code lines changed and both files remain pure ASCII (no MacRoman round-trip damage, per #880). verify_virgin_root_sync.sh --full: all 3061 files match. user.prefs.firstRootRun is deliberately LEFT AT false. Flipping it was tested on a scratch copy and reproduced exactly the 9 failures #855 predicts across startup_script_execution, webserver_hello_world and webserver_inetd_e2e. Root-caused to stale pathString, not test design: Frontier.pathString in Virgin.root still points at .claude/worktrees/menu-port-phase-c-bridge/databases/, a worktree that no longer exists, so Frontier.getSubFolder() fails with "Can't create folder". That is the #859 pathString bug, which is not yet merged into this base. The same three suites pass 23/23 with these repairs and the flag left false, isolating the two variables cleanly. The flag flip should land as a follow-up once #859 is merged. Full integration suite: 2482 total, 2302 passed, 163 skipped, 0 failed (17 baselined known-failures, all pre-existing and unrelated). Per the maintainer decision of 2026-08-11, this is the last sanctioned direct binary edit of Virgin.root; subsequent shipped-root changes move to the sources/ pipeline described in planning/ROOT_BUILD_FROM_SOURCE_PLAN.md. Virgin.root: dd491bd16ccb8b3dfb478acc77375387 (17011793 bytes) -> d9dbf48121c452b31b2c41ace188e679 (18219590 bytes) Growth is ODB append-on-save; no db.compactDatabase was run (#854). Refs #881, #865, #855, #859 --- databases/Virgin.root | Bin 17011793 -> 18219590 bytes .../verbs/builtins/string/isValidUrl.ut | 2 +- .../verbs/builtins/webBrowser/openURL.ut | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/databases/Virgin.root b/databases/Virgin.root index 82b957b2c8719ccefdbd42b1843179e248f892c8..79087fe43e902bc300f6fa7a36398ade3b3be13d 100644 GIT binary patch delta 2383 zcmZwHdt8iJ7zgmq%-dX$wwjWOj6x-qE^d($?UHm+t!0aG34^U+(6ZufS+6^>>)1BZ zqIK;;Iuw!+ySc6VWzkx8$t9%8BKw* z%Jk!(hh?=0mGTYMSshiG+WlIxY!F$wFEd8Yu@{3$2R#{rK*llW!{n@tRSu1kb979s zRwlfxChTRkq|Y;!*RTwOyGo?3gwS#+3oYkT*Ra|{G7Lt&Z5=5z$5?|5t-yxm%3J5xvpqwt<2Ygc+tzITTU%Ehi`(HUUfE8l z(R~7@qdho)3LL=++JG~w(Y4JO$SOP9BBR*iw&#a`C^kQgM4a8YlRNCTO^!KIgUUD!Dp0-@080_~tZxIzceKu2(6 zg+}*>Ls;bnXH%jPouD&x0T1v5FX#&1&<%XR7yO_*__N%IfMY2nk@nfC6T5m)Qi<7bwiQndj#3DrSX9m!x%Z4_+enyhCo|S;%!;C@pzz}Co7KT zK1^5F2Nng8Q_O#Qn3`j2J%VuZB};TDKIpnPxh^gh3Kj-I4_2_Sr%QX%Y_5)Qerr$Y z1-+pU1Vdlw2O-d(o!=U&ts!>>`~?hva2N=KAOb#x&tNbNfk+q%Q7{afi7p|eqa}mp z+0ooEQe}x;PDO9?CpRq7^>@+3+mV~%jSFy%xusxPg+90ij@~iM(L2^?AWq`G9k#>@ z4qM`2IK)E&B*Nz~0=|HeFbck84qK9vPh0M1x;|M**N=uVpoOt84#vX-NP&qk2`002 zy)NH_*&QU(!x5-v9 z7~XmQXlqi+io4E_X-W2)2dQtyrYIpkcs?v(@xlC)Qp-lAhL0Q7+n!+w&-tn57o`8k z3I5{=`1FW<%N!Pnu_aq%YMBqDBaAL1D4*P3&K%xXci{x#HP3|CnH?5$#4hWkuyet; zun-o(cd!@)SOQC787zktuo70mYFGnVuol+A_wWO(2MQbDN63bsAcyT-u+ir!E18{& z@5$}yn}*26zJQuQE^KDL8F|4|7}wkM39Qe}bD~YVl=cFx%Y&a`3v7jLkPpAWcGv+s zVHfO%Jx~CJPz1%W7xqC3?1xfdZ~zWM8I;2zI1ERi0**o@9D^!24kzFwRKqDa4Zp%~ zPy=V+ES!V$Z~=aYi*N}p!xgv+*WfzbfSYg&{(#$X2kt^G{0aBqFSrj6;BWW`9>OE2 zgU9d$p29Pzhv)DDUP1%Bf<`bx6TF6h;SIcnchC&)m(x138b}4LlaR9Qf<{sX%Kz=I4<^JIcyR5+XjGVtfC7c$}&CVDoaq@*WPb z;nqJ-l~Y@lUT*K_7w8w@?-$ThGj5J1G9unaN&Qs%5UGt)NvEsygUp>WmA=2qMyZ>q zG3e%|q)pU#8oV?iA)4;A*cj(zYtW2OOPx7Zmuk?sCAqoLJekaaYExu#+9xRAfo`su zs-U?|u`*(y^$|&J>28@!A5rg}Rir=83G1d7fb9KH3Jeag0oe!dO!^O&7XQQm delta 2391 zcmZ|P30#w990zcoF*Y_89H(q5V}Jv3T*HfnphAjrDR^WaAP$`x42B}w5Yl|}2t~_R z3wPA_e8ys*90 zQEVr)GyTchW|fJf?PcwnG9R~+^aJT+MJ!phza&}6rw>OGZ#@}_M8Ky#j*{~NN^(aD z`RufmbOH0Ij?hPSyulAhig^UPtH!=76J2XhqigxuYiL}D(-=O}nd|@p5P~D^OcpWY zNQY(4RXapoC(%}=O2}t8p%}VASLjALp;J}Men}I$5}rEIgs0B4bhPA-5X&Q%F!j3b zVET3eS8xM&@BmNfLF;v1#^F@*Bm##?srG7^Oca)dl`c|FN+w$NZ8{BY43$!E;$i77 zOOyIah`^H6>ZEJ$6162sn;?^J;_;4AeVc5ceOaiGq%(WlWzZ9PL2vK|IrxBr?rrzI z8&6wLdYeue=Li1K2b2&1fzTI%pdY9p7(yTv!YCIPeo{-)XjmV04?bPEH#|W>PmE5$ z%P3MtxX>Gy!pEdg$suBEi0`Xb`ct3F8e7BiRCQwvt=`JBHO$+fb`BtYtut;qrIrNH zjJ7CScU_BmUpT3wVYx9iH@CpQ?Z07GFI42M{VgO_0hjD&a?1*0JW60w)08bajO z19Z+$;wRFI+wryo$j&5f3nN#o-BQ|n#!{BEAvDyhr&EI@{3heCYEoXfKp~tIv zO+5ByZK8w!_>8%_8RPQi$^#66@`lk7}}V2mzHZqO~%=46?tiHeekn&uMaY4hjhWy=GyGUghzfkusGpgc1tJ3m90 zZICM_D-3$Db6I4rxA1U2xcgsnL9sk zo@Ecu?MmE@m8a*s)A=6yeiFW&-uWC;rPM<%$FN~EcT?g zwD>(x)o^3)>!i|hcgFe`O?4m#Xm#JB-W`;p4H?L)o2biy` zNRgP4nVf36MQmA&#*;gX=QUFE?i3Sr*@OElObeRAq%`xW)^!nXoNA+lcnZv`h}e?m zVmFRMiw|eSXBP+a)BiU6x*Cl}akpY~Wh@_#DyHOdF)evq;=hb|Fc?EPX{duUa2CFRFQFdJ z!Fl)!8sGwa4UKRSF2Of&8JgeB{0Kk6&u|xhfoAv> v?!kR{04>l858)BC!Ef+8v_l6xh9~d`JcU1@6aHGsHj~vrjq diff --git a/usertalk_scripts/Frontier.root/system/verbs/builtins/string/isValidUrl.ut b/usertalk_scripts/Frontier.root/system/verbs/builtins/string/isValidUrl.ut index 81e9076eb..74f3295e8 100644 --- a/usertalk_scripts/Frontier.root/system/verbs/builtins/string/isValidUrl.ut +++ b/usertalk_scripts/Frontier.root/system/verbs/builtins/string/isValidUrl.ut @@ -1,5 +1,5 @@ on isValidUrl (s) { //3/21/26 by JES - //Validates that s is a well-formed URL with an allowed scheme. + //Validates that s is a well-formed URL with an allowed scheme. //Rejects javascript:, data:, and other potentially dangerous schemes. //file:// is allowed for opening local HTML files and documents. if sizeof (s) == 0 { diff --git a/usertalk_scripts/Frontier.root/system/verbs/builtins/webBrowser/openURL.ut b/usertalk_scripts/Frontier.root/system/verbs/builtins/webBrowser/openURL.ut index fc2e2c257..07994a308 100644 --- a/usertalk_scripts/Frontier.root/system/verbs/builtins/webBrowser/openURL.ut +++ b/usertalk_scripts/Frontier.root/system/verbs/builtins/webBrowser/openURL.ut @@ -1,6 +1,6 @@ on openURL (s, openURLIn=nil) { //3/21/26 by JES - //Modernized for three runtime modes: - //GUI mode (isHeadless=false): use legacy AppleEvent path + //Modernized for three runtime modes: + //GUI mode (isHeadless=false): use legacy AppleEvent path //CLI mode (isHeadless=true, macOS with display): use "open" command //Headless (isHeadless=true, no display): log URL to console //2/15/26; 12:40:28 AM by JES