diff --git a/package/utils/ucode/Makefile b/package/utils/ucode/Makefile index d046782de79..eb6abd6adb6 100644 --- a/package/utils/ucode/Makefile +++ b/package/utils/ucode/Makefile @@ -12,9 +12,9 @@ PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=https://github.com/jow-/ucode.git -PKG_SOURCE_DATE:=2026-06-03 -PKG_SOURCE_VERSION:=3ec4e5c238353067e4b58fb9bb9938d85d59e7c2 -PKG_MIRROR_HASH:=bc0ccef8b34defd524705c73982b39ba9e86fab588e531eba1915eecc57a8351 +PKG_SOURCE_DATE:=2026-07-09 +PKG_SOURCE_VERSION:=b885dd0fe1e974551fb1233ca5f3aa74d80b74d9 +PKG_MIRROR_HASH:=654ba9dc8714aa8caf75ef422962fb465c2b21c8fbe4518a47f9de391cce6e71 PKG_MAINTAINER:=Jo-Philipp Wich PKG_LICENSE:=ISC diff --git a/package/utils/ucode/patches/100-compiler-scope-named-function-expression-names-to-th.patch b/package/utils/ucode/patches/100-compiler-scope-named-function-expression-names-to-th.patch deleted file mode 100644 index d788a7c7685..00000000000 --- a/package/utils/ucode/patches/100-compiler-scope-named-function-expression-names-to-th.patch +++ /dev/null @@ -1,80 +0,0 @@ -From: Felix Fietkau -Date: Mon, 6 Jul 2026 18:23:08 +0200 -Subject: [PATCH] compiler: scope named function expression names to their own - body - -A named function expression (e.g. `!function e(){...}()`) shares its parsing -path with function declarations, and declared its name in the enclosing scope -just as a declaration does. For an expression this is wrong: the name is only -meant to be visible inside its own body for self-reference. Binding it in the -enclosing scope leaked the name and, by pushing an extra local, shifted the -slot count so the initialize_local for a let/const initialised by the -expression marked the wrong slot -- the real variable stayed uninitialised and -its first use raised "Can't access lexical declaration 'x' before -initialization". Self-recursion was likewise broken. - -Bind the name in the enclosing scope only for declarations. For a named -expression, rename the function's own callee slot to the name after -initialising its compiler, so the body can reference itself while the enclosing -scope is left untouched. - -Signed-off-by: Felix Fietkau ---- - ---- a/compiler.c -+++ b/compiler.c -@@ -1949,20 +1949,27 @@ uc_compiler_compile_funcexpr_common(uc_c - return; - } - -- slot = uc_compiler_resolve_funcstub(compiler, name); -+ /* A function declaration binds its name in the enclosing scope. A named -+ * function expression must not: its name is only visible inside its own -+ * body (for self-reference), and declaring it in the enclosing scope -+ * would both leak it and shift the local slots, corrupting the -+ * initialisation state of a `let`/`const` the expression initialises. */ -+ if (require_name) { -+ slot = uc_compiler_resolve_funcstub(compiler, name); - -- if (slot > -1) { -- compiler->locals.entries[slot].funcstub = false; -- } -- else { -- slot = uc_compiler_declare_local(compiler, name, false); -+ if (slot > -1) { -+ compiler->locals.entries[slot].funcstub = false; -+ } -+ else { -+ slot = uc_compiler_declare_local(compiler, name, false); - -- if (slot == -1) -- uc_compiler_initialize_local(compiler); -- else if (compiler->locals.entries[slot].constant) -- uc_compiler_syntax_error(compiler, compiler->parser->prev.pos, -- "Redeclaration of constant '%s'", -- ucv_string_get(name)); -+ if (slot == -1) -+ uc_compiler_initialize_local(compiler); -+ else if (compiler->locals.entries[slot].constant) -+ uc_compiler_syntax_error(compiler, compiler->parser->prev.pos, -+ "Redeclaration of constant '%s'", -+ ucv_string_get(name)); -+ } - } - } - else if (require_name) { -@@ -1976,6 +1983,14 @@ uc_compiler_compile_funcexpr_common(uc_c - compiler->program, - uc_compiler_is_strict(compiler)); - -+ /* Bind a named function expression's name to its own callee slot so the -+ * body can reference itself for recursion, without touching the enclosing -+ * scope. Declarations keep the name in the enclosing scope (handled above). */ -+ if (name && !require_name) { -+ ucv_put(fncompiler.locals.entries[0].name); -+ fncompiler.locals.entries[0].name = ucv_get(name); -+ } -+ - fncompiler.parent = compiler; - fncompiler.parser = compiler->parser; - fncompiler.exprstack = compiler->exprstack; diff --git a/package/utils/ucode/patches/101-lib-avoid-allocating-print-buffer-before-NULL-check-.patch b/package/utils/ucode/patches/101-lib-avoid-allocating-print-buffer-before-NULL-check-.patch deleted file mode 100644 index 1902006cdbb..00000000000 --- a/package/utils/ucode/patches/101-lib-avoid-allocating-print-buffer-before-NULL-check-.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Felix Fietkau -Date: Tue, 7 Jul 2026 09:34:16 +0200 -Subject: [PATCH] lib: avoid allocating print buffer before NULL check in - uc_error_message_indent - -Move the print buffer allocation after the guard that returns early on a -NULL message, so no buffer is allocated on that path. This keeps the -function leak-free when callers invoke it without having produced an error -string. - -Signed-off-by: Felix Fietkau ---- - ---- a/lib.c -+++ b/lib.c -@@ -220,13 +220,14 @@ uc_error_context_format(uc_stringbuf_t * - - void - uc_error_message_indent(char **msg) { -- uc_stringbuf_t *buf = xprintbuf_new(); -+ uc_stringbuf_t *buf; - char *s, *p, *nl; - size_t len; - - if (!msg || !*msg) - return; - -+ buf = xprintbuf_new(); - s = *msg; - len = strlen(s); - diff --git a/package/utils/ucode/patches/102-compiler-prevent-unbounded-recompilation-on-failed-m.patch b/package/utils/ucode/patches/102-compiler-prevent-unbounded-recompilation-on-failed-m.patch deleted file mode 100644 index 02590f6a36f..00000000000 --- a/package/utils/ucode/patches/102-compiler-prevent-unbounded-recompilation-on-failed-m.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: Felix Fietkau -Date: Mon, 6 Jul 2026 11:12:32 +0200 -Subject: [PATCH] compiler: prevent unbounded recompilation on failed - module imports - -A source's exports.offset of -1 marks a module whose compilation has been -entered but not completed. When a module failed to compile, uc_compiler_finish -freed its function and the error cascaded up through the importers via error -recovery, leaving each involved source at offset -1 with its function gone. The -re-entry guard only recognised an in-progress module by finding its function, so -those freed modules were recompiled again on every subsequent import. Across a -wide import graph this recompilation multiplies and the compiler appears to hang. - -Detect the offset -1 marker directly instead of relying on the presence of a -function: report a circular dependency when the function is still around, and -propagate the failure otherwise, rather than recursing into the module again. - -Signed-off-by: Felix Fietkau ---- - ---- a/compiler.c -+++ b/compiler.c -@@ -3479,15 +3479,26 @@ uc_compiler_compile_module_source(uc_com - - uc_program_function_foreach(compiler->program, fn) { - if (uc_program_function_source(fn) == source) { -- if (source->exports.offset == (size_t)-1) -- uc_compiler_syntax_error(compiler, compiler->parser->prev.pos, -- "Circular dependency"); -- - loaded = true; - break; - } - } - -+ /* An offset of -1 marks a source whose compilation was entered but not yet -+ * completed. Re-entering it is either a circular dependency (its function is -+ * still present) or a module whose earlier compilation failed and freed its -+ * function. Recompiling in either case recurses without bound across a large -+ * import graph, so report the cycle and propagate the failure instead. */ -+ if (source->exports.offset == (size_t)-1) { -+ if (loaded) -+ uc_compiler_syntax_error(compiler, compiler->parser->prev.pos, -+ "Circular dependency"); -+ else if (errp) -+ xasprintf(errp, "Module previously failed to compile\n"); -+ -+ return false; -+ } -+ - if (!loaded) { - /* We do not yet support linking precompiled modules at compile time, - turn static import operation into dynamic load one. */ diff --git a/package/utils/ucode/patches/110-uloop-allow-reusing-the-existing-environment.patch b/package/utils/ucode/patches/110-uloop-allow-reusing-the-existing-environment.patch index 33b0261a71d..018410493dc 100644 --- a/package/utils/ucode/patches/110-uloop-allow-reusing-the-existing-environment.patch +++ b/package/utils/ucode/patches/110-uloop-allow-reusing-the-existing-environment.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/lib/uloop.c +++ b/lib/uloop.c -@@ -1023,7 +1023,22 @@ uc_uloop_process(uc_vm_t *vm, size_t nar +@@ -1028,7 +1028,22 @@ uc_uloop_process(uc_vm_t *vm, size_t nar if (pid == 0) { argp = calloc(ucv_array_length(arguments) + 2, sizeof(char *)); @@ -35,7 +35,7 @@ Signed-off-by: Felix Fietkau if (!argp || !envp) _exit(-1); -@@ -1033,19 +1048,6 @@ uc_uloop_process(uc_vm_t *vm, size_t nar +@@ -1038,19 +1053,6 @@ uc_uloop_process(uc_vm_t *vm, size_t nar for (i = 0; i < ucv_array_length(arguments); i++) argp[i+1] = ucv_to_string(vm, ucv_array_get(arguments, i)); diff --git a/package/utils/ucode/patches/111-uloop-add-optional-setup-callback-to-process.patch b/package/utils/ucode/patches/111-uloop-add-optional-setup-callback-to-process.patch index e8f597ade7c..e6accabe38a 100644 --- a/package/utils/ucode/patches/111-uloop-add-optional-setup-callback-to-process.patch +++ b/package/utils/ucode/patches/111-uloop-add-optional-setup-callback-to-process.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- a/lib/uloop.c +++ b/lib/uloop.c -@@ -968,8 +968,9 @@ uc_uloop_process_cb(struct uloop_process +@@ -973,8 +973,9 @@ uc_uloop_process_cb(struct uloop_process * * This function creates a process instance for executing external programs. * It takes the executable path string, an optional string array as the argument @@ -22,7 +22,7 @@ Signed-off-by: Felix Fietkau * * @function module:uloop#process * -@@ -986,6 +987,11 @@ uc_uloop_process_cb(struct uloop_process +@@ -991,6 +992,11 @@ uc_uloop_process_cb(struct uloop_process * @param {Function} callback * The callback function to be invoked when the invoked process ends. * @@ -34,7 +34,7 @@ Signed-off-by: Felix Fietkau * @returns {?module:uloop.process} * Returns a process instance for executing external programs. * Returns `null` on error, e.g. due to `exec()` failure or invalid arguments. -@@ -995,6 +1001,16 @@ uc_uloop_process_cb(struct uloop_process +@@ -1000,6 +1006,16 @@ uc_uloop_process_cb(struct uloop_process * const myProcess = uloop.process("/bin/ls", ["-l", "/tmp"], null, (code) => { * printf(`Process exited with code ${code}\n`); * }); @@ -51,7 +51,7 @@ Signed-off-by: Felix Fietkau */ static uc_value_t * uc_uloop_process(uc_vm_t *vm, size_t nargs) -@@ -1003,6 +1019,7 @@ uc_uloop_process(uc_vm_t *vm, size_t nar +@@ -1008,6 +1024,7 @@ uc_uloop_process(uc_vm_t *vm, size_t nar uc_value_t *arguments = uc_fn_arg(1); uc_value_t *env_arg = uc_fn_arg(2); uc_value_t *callback = uc_fn_arg(3); @@ -59,7 +59,7 @@ Signed-off-by: Felix Fietkau uc_uloop_process_t *process; uc_stringbuf_t *buf; char **argp, **envp; -@@ -1012,7 +1029,8 @@ uc_uloop_process(uc_vm_t *vm, size_t nar +@@ -1017,7 +1034,8 @@ uc_uloop_process(uc_vm_t *vm, size_t nar if (ucv_type(executable) != UC_STRING || (arguments && ucv_type(arguments) != UC_ARRAY) || (env_arg && ucv_type(env_arg) != UC_OBJECT) || @@ -69,7 +69,7 @@ Signed-off-by: Felix Fietkau err_return(EINVAL); } -@@ -1022,6 +1040,13 @@ uc_uloop_process(uc_vm_t *vm, size_t nar +@@ -1027,6 +1045,13 @@ uc_uloop_process(uc_vm_t *vm, size_t nar err_return(errno); if (pid == 0) {