Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package mujs for openSUSE:Factory checked in 
at 2023-01-14 20:32:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mujs (Old)
 and      /work/SRC/openSUSE:Factory/.mujs.new.32243 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mujs"

Sat Jan 14 20:32:33 2023 rev:8 rq:1058365 version:1.3.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/mujs/mujs.changes        2022-05-19 
22:49:29.962348682 +0200
+++ /work/SRC/openSUSE:Factory/.mujs.new.32243/mujs.changes     2023-01-14 
20:32:35.613523214 +0100
@@ -1,0 +2,32 @@
+Sat Jan 14 11:41:55 UTC 2023 - ecsos <ec...@opensuse.org>
+
+- Update to 1.3.2
+  * https://git.ghostscript.com/?p=mujs.git;a=log;h=refs/tags/1.3.2
+  * 1.3.2 patch release for UAF bug fix.
+  * Bug 706057: Fix use-after-free in getOwnPropertyDescriptor.
+  * Set length of output array Array.prototype.map.
+- Update to 1.3.1
+  * https://git.ghostscript.com/?p=mujs.git;a=log;h=refs/tags/1.3.1
+  * Make a patch release for important iterator bug fix.
+  * Issue #166: Use special iterator for string and array indices.
+  * Enable choice of library version for shell
+  * Use $(@D) instead of $(dir $@)
+- Update to 1.3.0
+  * https://git.ghostscript.com/?p=mujs.git;a=log;h=refs/tags/1.3.0
+  * Avoid freeing buffer twice in case of error.
+  * Fast path for "simple" arrays.
+  * Bug 705775: Fix double fclose in pretty-printing tool.
+  * Makefile: fix parallel builds
+  * Guard state initialization with try to avoid panic in 
initialization.
+  * Add js_isbooleanobject and js_isdateobject functions.
+  * Issue #161: Cope with empty programs in mujs-pp.
+  * Issue #161: Don't fclose a FILE that is NULL.
+  * Issue #162: Check stack overflow during regexp compilation.
+  * Bug 705052: Don't use private STACK/TOP macros in jsstate.c
+  * Add "console" object to mujs shell.
+  * Issue #156: Fix check for duplicate formal parameters when strict.
+  * Some minor optimizations to Ap_join.
+  * array join: avoid strcat, speedup from O(N^2) to O(N)
+- Drop mujs-1.2.0-stack-exhaustion.patch because now in upstream.
+
+-------------------------------------------------------------------

Old:
----
  mujs-1.2.0-stack-exhaustion.patch
  mujs-1.2.0.tar.xz

New:
----
  mujs-1.3.2.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mujs.spec ++++++
--- /var/tmp/diff_new_pack.FvMk0m/_old  2023-01-14 20:32:37.809536183 +0100
+++ /var/tmp/diff_new_pack.FvMk0m/_new  2023-01-14 20:32:37.813536206 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package mujs
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,14 +17,13 @@
 
 
 Name:           mujs
-Version:        1.2.0
+Version:        1.3.2
 Release:        0
 Summary:        An embeddable Javascript interpreter
 License:        AGPL-3.0-or-later
 Group:          Development/Languages/C and C++
 URL:            https://mujs.com
 Source0:        https://mujs.com/downloads/%{name}-%{version}.tar.xz
-Patch0:         %{name}-1.2.0-stack-exhaustion.patch
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(readline)
 

++++++ mujs-1.2.0.tar.xz -> mujs-1.3.2.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/Makefile new/mujs-1.3.2/Makefile
--- old/mujs-1.2.0/Makefile     2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/Makefile     2022-11-07 16:24:56.000000000 +0100
@@ -12,7 +12,7 @@
 ifeq "$(wildcard .git)" ".git"
   VERSION := $(shell git describe --tags --always)
 else
-  VERSION := $(shell basename $$PWD | sed -e s,^mujs-,,)
+  VERSION := $(patsubst mujs-%,%,$(notdir $(CURDIR)))
 endif
 
 ifeq ($(shell uname),Darwin)
@@ -75,31 +75,34 @@
 jsdump.c: astnames.h opnames.h
 
 $(OUT)/%.o: %.c $(HDRS)
-       @ mkdir -p $(dir $@)
+       @ mkdir -p $(@D)
        $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
 
 $(OUT)/libmujs.o: one.c $(HDRS)
-       @ mkdir -p $(dir $@)
+       @ mkdir -p $(@D)
        $(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
 
 $(OUT)/libmujs.a: $(OUT)/libmujs.o
-       @ mkdir -p $(dir $@)
+       @ mkdir -p $(@D)
        $(AR) cr $@ $^
 
 $(OUT)/libmujs.$(SO_EXT): one.c $(HDRS)
-       @ mkdir -p $(dir $@)
+       @ mkdir -p $(@D)
        $(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -shared $(LDFLAGS) -o $@ $< -lm
 
-$(OUT)/mujs: $(OUT)/libmujs.o $(OUT)/main.o
-       @ mkdir -p $(dir $@)
-       $(CC) $(LDFLAGS) -o $@ $^ $(LIBREADLINE) -lm
+libmujs ?= libmujs.a
 
-$(OUT)/mujs-pp: $(OUT)/libmujs.o $(OUT)/pp.o
-       @ mkdir -p $(dir $@)
-       $(CC) $(LDFLAGS) -o $@ $^ -lm
+$(OUT)/mujs: $(OUT)/main.o $(OUT)/$(libmujs)
+       @ mkdir -p $(@D)
+       $(CC) $(LDFLAGS) -o $@ $< -L$(OUT) -l:$(libmujs) $(LIBREADLINE) -lm
+
+$(OUT)/mujs-pp: $(OUT)/pp.o $(OUT)/$(libmujs)
+       @ mkdir -p $(@D)
+       $(CC) $(LDFLAGS) -o $@ $< -L$(OUT) -l:$(libmujs) -lm
 
 .PHONY: $(OUT)/mujs.pc
 $(OUT)/mujs.pc:
+       @ mkdir -p $(dir $@)
        @ echo Creating $@
        @ echo > $@ Name: mujs
        @ echo >> $@ Description: MuJS embeddable Javascript interpreter
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/jsarray.c new/mujs-1.3.2/jsarray.c
--- old/mujs-1.2.0/jsarray.c    2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/jsarray.c    2022-11-07 16:24:56.000000000 +0100
@@ -17,30 +17,6 @@
        js_setproperty(J, idx < 0 ? idx - 1 : idx, "length");
 }
 
-int js_hasindex(js_State *J, int idx, int i)
-{
-       char buf[32];
-       return js_hasproperty(J, idx, js_itoa(buf, i));
-}
-
-void js_getindex(js_State *J, int idx, int i)
-{
-       char buf[32];
-       js_getproperty(J, idx, js_itoa(buf, i));
-}
-
-void js_setindex(js_State *J, int idx, int i)
-{
-       char buf[32];
-       js_setproperty(J, idx, js_itoa(buf, i));
-}
-
-void js_delindex(js_State *J, int idx, int i)
-{
-       char buf[32];
-       js_delproperty(J, idx, js_itoa(buf, i));
-}
-
 static void jsB_new_Array(js_State *J)
 {
        int i, top = js_gettop(J);
@@ -91,7 +67,7 @@
        const char *sep;
        const char *r;
        int seplen;
-       int k, n, len;
+       int k, n, len, rlen;
 
        len = js_getlength(J, 0);
 
@@ -113,33 +89,40 @@
                js_throw(J);
        }
 
-       n = 1;
+       n = 0;
        for (k = 0; k < len; ++k) {
                js_getindex(J, 0, k);
-               if (js_isundefined(J, -1) || js_isnull(J, -1))
-                       r = "";
-               else
+               if (js_iscoercible(J, -1)) {
                        r = js_tostring(J, -1);
-               n += strlen(r);
+                       rlen = strlen(r);
+               } else {
+                       rlen = 0;
+               }
 
                if (k == 0) {
-                       if (n > JS_STRLIMIT)
-                               js_rangeerror(J, "invalid string length");
-                       out = js_malloc(J, (int)n);
-                       strcpy(out, r);
+                       out = js_malloc(J, rlen + 1);
+                       if (rlen > 0) {
+                               memcpy(out, r, rlen);
+                               n += rlen;
+                       }
                } else {
-                       n += seplen;
-                       if (n > JS_STRLIMIT)
+                       if (n + seplen + rlen > JS_STRLIMIT)
                                js_rangeerror(J, "invalid string length");
-                       out = js_realloc(J, out, (int)n);
-                       strcat(out, sep);
-                       strcat(out, r);
+                       out = js_realloc(J, out, n + seplen + rlen + 1);
+                       if (seplen > 0) {
+                               memcpy(out + n, sep, seplen);
+                               n += seplen;
+                       }
+                       if (rlen > 0) {
+                               memcpy(out + n, r, rlen);
+                               n += rlen;
+                       }
                }
 
                js_pop(J, 1);
        }
 
-       js_pushstring(J, out);
+       js_pushlstring(J, out, n);
        js_endtry(J);
        js_free(J, out);
 }
@@ -600,6 +583,7 @@
                        js_pop(J, 1);
                }
        }
+       js_setlength(J, -1, len);
 }
 
 static void Ap_filter(js_State *J)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/jscompile.c new/mujs-1.3.2/jscompile.c
--- old/mujs-1.2.0/jscompile.c  2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/jscompile.c  2022-11-07 16:24:56.000000000 +0100
@@ -1366,7 +1366,7 @@
                        emitfunction(J, F, newfun(J, stm->line, stm->a, stm->b, 
stm->c, 0, F->strict));
                        emitline(J, F, stm);
                        emit(J, F, OP_SETLOCAL);
-                       emitarg(J, F, addlocal(J, F, stm->a, 0));
+                       emitarg(J, F, addlocal(J, F, stm->a, 1));
                        emit(J, F, OP_POP);
                }
                list = list->b;
@@ -1400,7 +1400,7 @@
                if (findlocal(J, F, name->string) < 0) {
                        emit(J, F, OP_CURRENT);
                        emit(J, F, OP_SETLOCAL);
-                       emitarg(J, F, addlocal(J, F, name, 0));
+                       emitarg(J, F, addlocal(J, F, name, 1));
                        emit(J, F, OP_POP);
                }
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/jsdump.c new/mujs-1.3.2/jsdump.c
--- old/mujs-1.2.0/jsdump.c     2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/jsdump.c     2022-11-07 16:24:56.000000000 +0100
@@ -682,11 +682,13 @@
 void jsP_dumpsyntax(js_State *J, js_Ast *prog, int dominify)
 {
        minify = dominify;
-       if (prog->type == AST_LIST)
-               pstmlist(-1, prog);
-       else {
-               pstm(0, prog);
-               nl();
+       if (prog) {
+               if (prog->type == AST_LIST)
+                       pstmlist(-1, prog);
+               else {
+                       pstm(0, prog);
+                       nl();
+               }
        }
        if (minify > 1)
                putchar('\n');
@@ -768,11 +770,13 @@
 void jsP_dumplist(js_State *J, js_Ast *prog)
 {
        minify = 0;
-       if (prog->type == AST_LIST)
-               sblock(0, prog);
-       else
-               snode(0, prog);
-       nl();
+       if (prog) {
+               if (prog->type == AST_LIST)
+                       sblock(0, prog);
+               else
+                       snode(0, prog);
+               nl();
+       }
 }
 
 /* Compiled code */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/jsgc.c new/mujs-1.3.2/jsgc.c
--- old/mujs-1.2.0/jsgc.c       2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/jsgc.c       2022-11-07 16:24:56.000000000 +0100
@@ -42,6 +42,8 @@
                js_free(J, obj->u.r.source);
                js_regfreex(J->alloc, J->actx, obj->u.r.prog);
        }
+       if (obj->type == JS_CARRAY && obj->u.a.simple)
+               js_free(J, obj->u.a.array);
        if (obj->type == JS_CITERATOR)
                jsG_freeiterator(J, obj->u.iter.head);
        if (obj->type == JS_CUSERDATA && obj->u.user.finalize)
@@ -100,6 +102,16 @@
                jsG_markproperty(J, mark, obj->properties);
        if (obj->prototype && obj->prototype->gcmark != mark)
                jsG_markobject(J, mark, obj->prototype);
+       if (obj->type == JS_CARRAY && obj->u.a.simple) {
+               int i;
+               for (i = 0; i < obj->u.a.length; ++i) {
+                       js_Value *v = &obj->u.a.array[i];
+                       if (v->type == JS_TMEMSTR && v->u.memstr->gcmark != 
mark)
+                               v->u.memstr->gcmark = mark;
+                       if (v->type == JS_TOBJECT && v->u.object->gcmark != 
mark)
+                               jsG_markobject(J, mark, v->u.object);
+               }
+       }
        if (obj->type == JS_CITERATOR && obj->u.iter.target->gcmark != mark) {
                jsG_markobject(J, mark, obj->u.iter.target);
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/jsi.h new/mujs-1.3.2/jsi.h
--- old/mujs-1.2.0/jsi.h        2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/jsi.h        2022-11-07 16:24:56.000000000 +0100
@@ -86,6 +86,9 @@
 #ifndef JS_TRYLIMIT
 #define JS_TRYLIMIT 64         /* exception stack size */
 #endif
+#ifndef JS_ARRAYLIMIT
+#define JS_ARRAYLIMIT (1<<26)  /* limit arrays to 64M entries (1G of flat 
array data) */
+#endif
 #ifndef JS_GCFACTOR
 /*
  * GC will try to trigger when memory usage is this value times the minimum
@@ -241,6 +244,8 @@
 
        unsigned int seed; /* Math.random seed */
 
+       char scratch[12]; /* scratch buffer for iterating over array indices */
+
        int nextref; /* for js_ref use */
        js_Object *R; /* registry of hidden values */
        js_Object *G; /* the global object */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/jsobject.c new/mujs-1.3.2/jsobject.c
--- old/mujs-1.2.0/jsobject.c   2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/jsobject.c   2022-11-07 16:24:56.000000000 +0100
@@ -62,7 +62,24 @@
 {
        js_Object *self = js_toobject(J, 0);
        const char *name = js_tostring(J, 1);
-       js_Property *ref = jsV_getownproperty(J, self, name);
+       js_Property *ref;
+       int k;
+
+       if (self->type == JS_CSTRING) {
+               if (js_isarrayindex(J, name, &k) && k >= 0 && k < 
self->u.s.length) {
+                       js_pushboolean(J, 1);
+                       return;
+               }
+       }
+
+       if (self->type == JS_CARRAY && self->u.a.simple) {
+               if (js_isarrayindex(J, name, &k) && k >= 0 && k < 
self->u.a.length) {
+                       js_pushboolean(J, 1);
+                       return;
+               }
+       }
+
+       ref = jsV_getownproperty(J, self, name);
        js_pushboolean(J, ref != NULL);
 }
 
@@ -110,31 +127,32 @@
                js_typeerror(J, "not an object");
        obj = js_toobject(J, 1);
        ref = jsV_getproperty(J, obj, js_tostring(J, 2));
-       if (!ref)
+       if (!ref) {
+               // TODO: builtin properties (string and array index and length, 
regexp flags, etc)
                js_pushundefined(J);
-       else {
+       } else {
                js_newobject(J);
                if (!ref->getter && !ref->setter) {
                        js_pushvalue(J, ref->value);
-                       js_setproperty(J, -2, "value");
+                       js_defproperty(J, -2, "value", 0);
                        js_pushboolean(J, !(ref->atts & JS_READONLY));
-                       js_setproperty(J, -2, "writable");
+                       js_defproperty(J, -2, "writable", 0);
                } else {
                        if (ref->getter)
                                js_pushobject(J, ref->getter);
                        else
                                js_pushundefined(J);
-                       js_setproperty(J, -2, "get");
+                       js_defproperty(J, -2, "get", 0);
                        if (ref->setter)
                                js_pushobject(J, ref->setter);
                        else
                                js_pushundefined(J);
-                       js_setproperty(J, -2, "set");
+                       js_defproperty(J, -2, "set", 0);
                }
                js_pushboolean(J, !(ref->atts & JS_DONTENUM));
-               js_setproperty(J, -2, "enumerable");
+               js_defproperty(J, -2, "enumerable", 0);
                js_pushboolean(J, !(ref->atts & JS_DONTCONF));
-               js_setproperty(J, -2, "configurable");
+               js_defproperty(J, -2, "configurable", 0);
        }
 }
 
@@ -152,6 +170,7 @@
 static void O_getOwnPropertyNames(js_State *J)
 {
        js_Object *obj;
+       char name[32];
        int k;
        int i;
 
@@ -169,13 +188,21 @@
        if (obj->type == JS_CARRAY) {
                js_pushliteral(J, "length");
                js_setindex(J, -2, i++);
+               if (obj->u.a.simple) {
+                       for (k = 0; k < obj->u.a.length; ++k) {
+                               js_itoa(name, k);
+                               js_pushstring(J, name);
+                               js_setindex(J, -2, i++);
+                       }
+               }
        }
 
        if (obj->type == JS_CSTRING) {
                js_pushliteral(J, "length");
                js_setindex(J, -2, i++);
                for (k = 0; k < obj->u.s.length; ++k) {
-                       js_pushnumber(J, k);
+                       js_itoa(name, k);
+                       js_pushstring(J, name);
                        js_setindex(J, -2, i++);
                }
        }
@@ -221,7 +248,7 @@
        }
        if (js_hasproperty(J, -1, "value")) {
                hasvalue = 1;
-               js_setproperty(J, -3, name);
+               js_defproperty(J, -3, name, 0);
        }
 
        if (!writable) atts |= JS_READONLY;
@@ -359,9 +386,12 @@
 
 static void O_preventExtensions(js_State *J)
 {
+       js_Object *obj;
        if (!js_isobject(J, 1))
                js_typeerror(J, "not an object");
-       js_toobject(J, 1)->extensible = 0;
+       obj = js_toobject(J, 1);
+       jsR_unflattenarray(J, obj);
+       obj->extensible = 0;
        js_copy(J, 1);
 }
 
@@ -389,6 +419,7 @@
                js_typeerror(J, "not an object");
 
        obj = js_toobject(J, 1);
+       jsR_unflattenarray(J, obj);
        obj->extensible = 0;
 
        if (obj->properties->level)
@@ -446,6 +477,7 @@
                js_typeerror(J, "not an object");
 
        obj = js_toobject(J, 1);
+       jsR_unflattenarray(J, obj);
        obj->extensible = 0;
 
        if (obj->properties->level)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/json.c new/mujs-1.3.2/json.c
--- old/mujs-1.2.0/json.c       2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/json.c       2022-11-07 16:24:56.000000000 +0100
@@ -15,6 +15,16 @@
        return js_isobject(J, idx) && js_toobject(J, idx)->type == JS_CSTRING;
 }
 
+int js_isbooleanobject(js_State *J, int idx)
+{
+       return js_isobject(J, idx) && js_toobject(J, idx)->type == JS_CBOOLEAN;
+}
+
+int js_isdateobject(js_State *J, int idx)
+{
+       return js_isobject(J, idx) && js_toobject(J, idx)->type == JS_CDATE;
+}
+
 static void jsonnext(js_State *J)
 {
        J->lookahead = jsY_lexjson(J);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/jsproperty.c new/mujs-1.3.2/jsproperty.c
--- old/mujs-1.2.0/jsproperty.c 2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/jsproperty.c 2022-11-07 16:24:56.000000000 +0100
@@ -1,6 +1,8 @@
 #include "jsi.h"
 #include "jsvalue.h"
 
+#include <assert.h>
+
 /*
        Use an AA-tree to quickly look up properties in objects:
 
@@ -226,16 +228,20 @@
 
 /* Flatten hierarchy of enumerable properties into an iterator object */
 
+static js_Iterator *itnewnode(js_State *J, const char *name, js_Iterator 
*next) {
+       js_Iterator *node = js_malloc(J, sizeof(js_Iterator));
+       node->name = name;
+       node->next = next;
+       return node;
+}
+
 static js_Iterator *itwalk(js_State *J, js_Iterator *iter, js_Property *prop, 
js_Object *seen)
 {
        if (prop->right != &sentinel)
                iter = itwalk(J, iter, prop->right, seen);
        if (!(prop->atts & JS_DONTENUM)) {
                if (!seen || !jsV_getenumproperty(J, seen, prop->name)) {
-                       js_Iterator *head = js_malloc(J, sizeof *head);
-                       head->name = prop->name;
-                       head->next = iter;
-                       iter = head;
+                       iter = itnewnode(J, prop->name, iter);
                }
        }
        if (prop->left != &sentinel)
@@ -255,10 +261,10 @@
 
 js_Object *jsV_newiterator(js_State *J, js_Object *obj, int own)
 {
-       char buf[32];
-       int k;
        js_Object *io = jsV_newobject(J, JS_CITERATOR, NULL);
        io->u.iter.target = obj;
+       io->u.iter.i = 0;
+       io->u.iter.n = 0;
        if (own) {
                io->u.iter.head = NULL;
                if (obj->properties != &sentinel)
@@ -266,26 +272,13 @@
        } else {
                io->u.iter.head = itflatten(J, obj);
        }
-       if (obj->type == JS_CSTRING) {
-               js_Iterator *tail = io->u.iter.head;
-               if (tail)
-                       while (tail->next)
-                               tail = tail->next;
-               for (k = 0; k < obj->u.s.length; ++k) {
-                       js_itoa(buf, k);
-                       if (!jsV_getenumproperty(J, obj, buf)) {
-                               js_Iterator *node = js_malloc(J, sizeof *node);
-                               node->name = js_intern(J, js_itoa(buf, k));
-                               node->next = NULL;
-                               if (!tail)
-                                       io->u.iter.head = tail = node;
-                               else {
-                                       tail->next = node;
-                                       tail = node;
-                               }
-                       }
-               }
-       }
+
+       if (obj->type == JS_CSTRING)
+               io->u.iter.n = obj->u.s.length;
+
+       if (obj->type == JS_CARRAY && obj->u.a.simple)
+               io->u.iter.n = obj->u.a.length;
+
        return io;
 }
 
@@ -294,6 +287,11 @@
        int k;
        if (io->type != JS_CITERATOR)
                js_typeerror(J, "not an iterator");
+       if (io->u.iter.i < io->u.iter.n) {
+               js_itoa(J->scratch, io->u.iter.i);
+               io->u.iter.i++;
+               return J->scratch;
+       }
        while (io->u.iter.head) {
                js_Iterator *next = io->u.iter.head->next;
                const char *name = io->u.iter.head->name;
@@ -304,6 +302,9 @@
                if (io->u.iter.target->type == JS_CSTRING)
                        if (js_isarrayindex(J, name, &k) && k < 
io->u.iter.target->u.s.length)
                                return name;
+               if (io->u.iter.target->type == JS_CARRAY && 
io->u.iter.target->u.a.simple)
+                       if (js_isarrayindex(J, name, &k) && k < 
io->u.iter.target->u.a.length)
+                               return name;
        }
        return NULL;
 }
@@ -315,6 +316,7 @@
        char buf[32];
        const char *s;
        int k;
+       assert(!obj->u.a.simple);
        if (newlen < obj->u.a.length) {
                if (obj->u.a.length > obj->count * 2) {
                        js_Object *it = jsV_newiterator(J, obj, 1);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/jsrun.c new/mujs-1.3.2/jsrun.c
--- old/mujs-1.2.0/jsrun.c      2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/jsrun.c      2022-11-07 16:24:56.000000000 +0100
@@ -5,6 +5,8 @@
 
 #include "utf.h"
 
+#include <assert.h>
+
 static void jsR_run(js_State *J, js_Function *F);
 
 /* Push values on stack */
@@ -517,6 +519,28 @@
        }
 }
 
+void jsR_unflattenarray(js_State *J, js_Object *obj) {
+       if (obj->type == JS_CARRAY && obj->u.a.simple) {
+               js_Property *ref;
+               int i;
+               char name[32];
+               if (js_try(J)) {
+                       obj->properties = NULL;
+                       js_throw(J);
+               }
+               for (i = 0; i < obj->u.a.length; ++i) {
+                       js_itoa(name, i);
+                       ref = jsV_setproperty(J, obj, name);
+                       ref->value = obj->u.a.array[i];
+               }
+               js_free(J, obj->u.a.array);
+               obj->u.a.simple = 0;
+               obj->u.a.capacity = 0;
+               obj->u.a.array = NULL;
+               js_endtry(J);
+       }
+}
+
 static int jsR_hasproperty(js_State *J, js_Object *obj, const char *name)
 {
        js_Property *ref;
@@ -527,6 +551,14 @@
                        js_pushnumber(J, obj->u.a.length);
                        return 1;
                }
+               if (obj->u.a.simple) {
+                       if (js_isarrayindex(J, name, &k)) {
+                               if (k >= 0 && k < obj->u.a.length) {
+                                       js_pushvalue(J, obj->u.a.array[k]);
+                                       return 1;
+                               }
+                       }
+               }
        }
 
        else if (obj->type == JS_CSTRING) {
@@ -591,6 +623,45 @@
                js_pushundefined(J);
 }
 
+static int jsR_hasindex(js_State *J, js_Object *obj, int k)
+{
+       char buf[32];
+       if (obj->type == JS_CARRAY && obj->u.a.simple && k >= 0 && k < 
obj->u.a.length) {
+               js_pushvalue(J, obj->u.a.array[k]);
+               return 1;
+       }
+       return jsR_hasproperty(J, obj, js_itoa(buf, k));
+}
+
+static void jsR_getindex(js_State *J, js_Object *obj, int k)
+{
+       if (!jsR_hasindex(J, obj, k))
+               js_pushundefined(J);
+}
+
+static void jsR_setarrayindex(js_State *J, js_Object *obj, int k, js_Value 
*value)
+{
+       int newlen = k + 1;
+       assert(obj->u.a.simple);
+       assert(k >= 0);
+       if (newlen > JS_ARRAYLIMIT)
+               js_rangeerror(J, "array too large");
+       if (newlen > obj->u.a.length) {
+               assert(newlen == obj->u.a.length + 1);
+               if (newlen > obj->u.a.capacity) {
+                       int newcap = obj->u.a.capacity;
+                       if (newcap == 0)
+                               newcap = 8;
+                       while (newcap < newlen)
+                               newcap <<= 1;
+                       obj->u.a.array = js_realloc(J, obj->u.a.array, newcap * 
sizeof(js_Value));
+                       obj->u.a.capacity = newcap;
+               }
+               obj->u.a.length = newlen;
+       }
+       obj->u.a.array[k] = *value;
+}
+
 static void jsR_setproperty(js_State *J, js_Object *obj, const char *name, int 
transient)
 {
        js_Value *value = stackidx(J, -1);
@@ -604,12 +675,30 @@
                        int newlen = jsV_numbertointeger(rawlen);
                        if (newlen != rawlen || newlen < 0)
                                js_rangeerror(J, "invalid array length");
+                       if (newlen > JS_ARRAYLIMIT)
+                               js_rangeerror(J, "array too large");
+                       if (obj->u.a.simple) {
+                               if (newlen <= obj->u.a.length) {
+                                       obj->u.a.length = newlen;
+                                       return;
+                               }
+                               jsR_unflattenarray(J, obj);
+                       }
                        jsV_resizearray(J, obj, newlen);
                        return;
                }
-               if (js_isarrayindex(J, name, &k))
-                       if (k >= obj->u.a.length)
+
+               if (js_isarrayindex(J, name, &k)) {
+                       if (obj->u.a.simple) {
+                               if (k >= 0 && k <= obj->u.a.length) {
+                                       jsR_setarrayindex(J, obj, k, value);
+                                       return;
+                               }
+                               jsR_unflattenarray(J, obj);
+                       }
+                       if (k + 1 > obj->u.a.length)
                                obj->u.a.length = k + 1;
+               }
        }
 
        else if (obj->type == JS_CSTRING) {
@@ -679,6 +768,16 @@
                js_typeerror(J, "'%s' is read-only", name);
 }
 
+static void jsR_setindex(js_State *J, js_Object *obj, int k, int transient)
+{
+       char buf[32];
+       if (obj->type == JS_CARRAY && obj->u.a.simple && k >= 0 && k <= 
obj->u.a.length) {
+               jsR_setarrayindex(J, obj, k, stackidx(J, -1));
+       } else {
+               jsR_setproperty(J, obj, js_itoa(buf, k), transient);
+       }
+}
+
 static void jsR_defproperty(js_State *J, js_Object *obj, const char *name,
        int atts, js_Value *value, js_Object *getter, js_Object *setter,
        int throw)
@@ -689,6 +788,8 @@
        if (obj->type == JS_CARRAY) {
                if (!strcmp(name, "length"))
                        goto readonly;
+               if (obj->u.a.simple)
+                       jsR_unflattenarray(J, obj);
        }
 
        else if (obj->type == JS_CSTRING) {
@@ -750,6 +851,8 @@
        if (obj->type == JS_CARRAY) {
                if (!strcmp(name, "length"))
                        goto dontconf;
+               if (obj->u.a.simple)
+                       jsR_unflattenarray(J, obj);
        }
 
        else if (obj->type == JS_CSTRING) {
@@ -889,6 +992,28 @@
        return jsR_hasproperty(J, js_toobject(J, idx), name);
 }
 
+void js_getindex(js_State *J, int idx, int i)
+{
+       jsR_getindex(J, js_toobject(J, idx), i);
+}
+
+int js_hasindex(js_State *J, int idx, int i)
+{
+       return jsR_hasindex(J, js_toobject(J, idx), i);
+}
+
+void js_setindex(js_State *J, int idx, int i)
+{
+       jsR_setindex(J, js_toobject(J, idx), i, !js_isobject(J, idx));
+       js_pop(J, 1);
+}
+
+void js_delindex(js_State *J, int idx, int i)
+{
+       char buf[32];
+       js_delproperty(J, idx, js_itoa(buf, i));
+}
+
 /* Iterator */
 
 void js_pushiterator(js_State *J, int idx, int own)
@@ -1360,6 +1485,16 @@
        js_stacktrace(J);
 }
 
+static int jsR_isindex(js_State *J, int idx, int *k)
+{
+       js_Value *v = stackidx(J, idx);
+       if (v->type == JS_TNUMBER) {
+               *k = v->u.number;
+               return *k == v->u.number && *k >= 0;
+       }
+       return 0;
+}
+
 static void jsR_run(js_State *J, js_Function *F)
 {
        js_Function **FT = F->funtab;
@@ -1532,9 +1667,14 @@
                        break;
 
                case OP_GETPROP:
-                       str = js_tostring(J, -1);
-                       obj = js_toobject(J, -2);
-                       jsR_getproperty(J, obj, str);
+                       if (jsR_isindex(J, -1, &ix)) {
+                               obj = js_toobject(J, -2);
+                               jsR_getindex(J, obj, ix);
+                       } else {
+                               str = js_tostring(J, -1);
+                               obj = js_toobject(J, -2);
+                               jsR_getproperty(J, obj, str);
+                       }
                        js_rot3pop2(J);
                        break;
 
@@ -1546,10 +1686,16 @@
                        break;
 
                case OP_SETPROP:
-                       str = js_tostring(J, -2);
-                       obj = js_toobject(J, -3);
-                       transient = !js_isobject(J, -3);
-                       jsR_setproperty(J, obj, str, transient);
+                       if (jsR_isindex(J, -2, &ix)) {
+                               obj = js_toobject(J, -3);
+                               transient = !js_isobject(J, -3);
+                               jsR_setindex(J, obj, ix, transient);
+                       } else {
+                               str = js_tostring(J, -2);
+                               obj = js_toobject(J, -3);
+                               transient = !js_isobject(J, -3);
+                               jsR_setproperty(J, obj, str, transient);
+                       }
                        js_rot3pop2(J);
                        break;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/jsstate.c new/mujs-1.3.2/jsstate.c
--- old/mujs-1.2.0/jsstate.c    2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/jsstate.c    2022-11-07 16:24:56.000000000 +0100
@@ -10,9 +10,9 @@
 
 static int js_ptry(js_State *J) {
        if (J->trytop == JS_TRYLIMIT) {
-               STACK[TOP].type = JS_TLITSTR;
-               STACK[TOP].u.litstr = "exception stack overflow";
-               ++TOP;
+               J->stack[J->top].type = JS_TLITSTR;
+               J->stack[J->top].u.litstr = "exception stack overflow";
+               ++J->top;
                return 1;
        }
        return 0;
@@ -322,6 +322,11 @@
        J->nextref = 0;
        J->gcthresh = 0; /* reaches stability within ~ 2-5 GC cycles */
 
+       if (js_try(J)) {
+               js_freestate(J);
+               return NULL;
+       }
+
        J->R = jsV_newobject(J, JS_COBJECT, NULL);
        J->G = jsV_newobject(J, JS_COBJECT, NULL);
        J->E = jsR_newenvironment(J, J->G, NULL);
@@ -329,5 +334,6 @@
 
        jsB_init(J);
 
+       js_endtry(J);
        return J;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/jsvalue.c new/mujs-1.3.2/jsvalue.c
--- old/mujs-1.2.0/jsvalue.c    2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/jsvalue.c    2022-11-07 16:24:56.000000000 +0100
@@ -423,7 +423,9 @@
 
 void js_newarray(js_State *J)
 {
-       js_pushobject(J, jsV_newobject(J, JS_CARRAY, J->Array_prototype));
+       js_Object *obj = jsV_newobject(J, JS_CARRAY, J->Array_prototype);
+       obj->u.a.simple = 1;
+       js_pushobject(J, obj);
 }
 
 void js_newboolean(js_State *J, int v)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/jsvalue.h new/mujs-1.3.2/jsvalue.h
--- old/mujs-1.2.0/jsvalue.h    2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/jsvalue.h    2022-11-07 16:24:56.000000000 +0100
@@ -93,6 +93,9 @@
                } s;
                struct {
                        int length;
+                       int simple; /* true if array has only non-sparse array 
properties */
+                       int capacity;
+                       js_Value *array;
                } a;
                struct {
                        js_Function *function;
@@ -109,7 +112,8 @@
                js_Regexp r;
                struct {
                        js_Object *target;
-                       js_Iterator *head;
+                       int i, n; /* for array part */
+                       js_Iterator *head; /* for object part */
                } iter;
                struct {
                        const char *tag;
@@ -149,6 +153,7 @@
 js_Object *js_toobject(js_State *J, int idx);
 void js_pushvalue(js_State *J, js_Value v);
 void js_pushobject(js_State *J, js_Object *v);
+void jsR_unflattenarray(js_State *J, js_Object *obj);
 
 /* jsvalue.c */
 int jsV_toboolean(js_State *J, js_Value *v);
@@ -158,7 +163,7 @@
 js_Object *jsV_toobject(js_State *J, js_Value *v);
 void jsV_toprimitive(js_State *J, js_Value *v, int preferred);
 
-const char *js_itoa(char buf[32], int a);
+const char *js_itoa(char *buf, int a);
 double js_stringtofloat(const char *s, char **ep);
 int jsV_numbertointeger(double n);
 int jsV_numbertoint32(double n);
@@ -182,6 +187,9 @@
 
 void jsV_resizearray(js_State *J, js_Object *obj, int newlen);
 
+void jsV_unflattenarray(js_State *J, js_Object *obj);
+void jsV_growarray(js_State *J, js_Object *obj);
+
 /* jsdump.c */
 void js_dumpobject(js_State *J, js_Object *obj);
 void js_dumpvalue(js_State *J, js_Value v);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/main.c new/mujs-1.3.2/main.c
--- old/mujs-1.2.0/main.c       2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/main.c       2022-11-07 16:24:56.000000000 +0100
@@ -230,6 +230,10 @@
        "};\n"
 ;
 
+static const char *console_js =
+       "var console = { log: print, debug: print, warn: print, error: print };"
+;
+
 static int eval_print(js_State *J, const char *source)
 {
        if (js_ploadstring(J, "[stdin]", source)) {
@@ -307,6 +311,10 @@
        }
 
        J = js_newstate(NULL, NULL, strict ? JS_STRICT : 0);
+       if (!J) {
+               fprintf(stderr, "Could not initialize MuJS.\n");
+               exit(1);
+       }
 
        js_newcfunction(J, jsB_gc, "gc", 0);
        js_setglobal(J, "gc");
@@ -337,6 +345,7 @@
 
        js_dostring(J, require_js);
        js_dostring(J, stacktrace_js);
+       js_dostring(J, console_js);
 
        if (xoptind == argc) {
                interactive = 1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/mujs.h new/mujs-1.3.2/mujs.h
--- old/mujs-1.2.0/mujs.h       2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/mujs.h       2022-11-07 16:24:56.000000000 +0100
@@ -8,8 +8,8 @@
 #endif
 
 #define JS_VERSION_MAJOR 1
-#define JS_VERSION_MINOR 2
-#define JS_VERSION_PATCH 0
+#define JS_VERSION_MINOR 3
+#define JS_VERSION_PATCH 2
 
 #define JS_VERSION (JS_VERSION_MAJOR * 10000 + JS_VERSION_MINOR * 100 + 
JS_VERSION_PATCH)
 #define JS_CHECKVERSION(x,y,z) (JS_VERSION >= ((x) * 10000 + (y) * 100 + (z)))
@@ -198,6 +198,8 @@
 int js_iserror(js_State *J, int idx);
 int js_isnumberobject(js_State *J, int idx);
 int js_isstringobject(js_State *J, int idx);
+int js_isbooleanobject(js_State *J, int idx);
+int js_isdateobject(js_State *J, int idx);
 
 int js_toboolean(js_State *J, int idx);
 double js_tonumber(js_State *J, int idx);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/pp.c new/mujs-1.3.2/pp.c
--- old/mujs-1.2.0/pp.c 2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/pp.c 2022-11-07 16:24:56.000000000 +0100
@@ -34,7 +34,7 @@
 
        if (js_try(J)) {
                js_free(J, s);
-               fclose(f);
+               if (f) fclose(f);
                js_throw(J);
        }
 
@@ -44,31 +44,25 @@
        }
 
        if (fseek(f, 0, SEEK_END) < 0) {
-               fclose(f);
                js_error(J, "cannot seek in file: '%s'", filename);
        }
 
        n = ftell(f);
        if (n < 0) {
-               fclose(f);
                js_error(J, "cannot tell in file: '%s'", filename);
        }
 
        if (fseek(f, 0, SEEK_SET) < 0) {
-               fclose(f);
                js_error(J, "cannot seek in file: '%s'", filename);
        }
 
        s = js_malloc(J, n + 1); /* add space for string terminator */
        if (!s) {
-               fclose(f);
                js_error(J, "cannot allocate storage for file contents: '%s'", 
filename);
        }
 
        t = fread(s, 1, (size_t)n, f);
        if (t != n) {
-               js_free(J, s);
-               fclose(f);
                js_error(J, "cannot read data from file: '%s'", filename);
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mujs-1.2.0/regexp.c new/mujs-1.3.2/regexp.c
--- old/mujs-1.2.0/regexp.c     2021-12-08 12:56:12.000000000 +0100
+++ new/mujs-1.3.2/regexp.c     2022-11-07 16:24:56.000000000 +0100
@@ -622,25 +622,26 @@
        Reinst *y;
 };
 
-static int count(struct cstate *g, Renode *node)
+static int count(struct cstate *g, Renode *node, int depth)
 {
        int min, max, n;
        if (!node) return 0;
+       if (++depth > REG_MAXREC) die(g, "stack overflow");
        switch (node->type) {
        default: return 1;
-       case P_CAT: return count(g, node->x) + count(g, node->y);
-       case P_ALT: return count(g, node->x) + count(g, node->y) + 2;
+       case P_CAT: return count(g, node->x, depth) + count(g, node->y, depth);
+       case P_ALT: return count(g, node->x, depth) + count(g, node->y, depth) 
+ 2;
        case P_REP:
                min = node->m;
                max = node->n;
-               if (min == max) n = count(g, node->x) * min;
-               else if (max < REPINF) n = count(g, node->x) * max + (max - 
min);
-               else n = count(g, node->x) * (min + 1) + 2;
+               if (min == max) n = count(g, node->x, depth) * min;
+               else if (max < REPINF) n = count(g, node->x, depth) * max + 
(max - min);
+               else n = count(g, node->x, depth) * (min + 1) + 2;
                if (n < 0 || n > REG_MAXPROG) die(g, "program too large");
                return n;
-       case P_PAR: return count(g, node->x) + 2;
-       case P_PLA: return count(g, node->x) + 2;
-       case P_NLA: return count(g, node->x) + 2;
+       case P_PAR: return count(g, node->x, depth) + 2;
+       case P_PLA: return count(g, node->x, depth) + 2;
+       case P_NLA: return count(g, node->x, depth) + 2;
        }
 }
 
@@ -903,7 +904,7 @@
        putchar('\n');
 #endif
 
-       n = 6 + count(&g, node);
+       n = 6 + count(&g, node, 0);
        if (n < 0 || n > REG_MAXPROG)
                die(&g, "program too large");
 

Reply via email to