From 7293760d944b5e4ee674bc2f45fa940f0b38712c Mon Sep 17 00:00:00 2001
From: Ben Noordhuis <info@bnoordhuis.nl>
Date: Mon, 30 Sep 2024 21:48:13 +0200
Subject: [PATCH] Fix regexp split with zero-length capture group

The expected result of `"ab".split(/(c)*/)[1]` is `undefined` but
was in fact `"undefined"` due to unintentional stringification.

Fixes: https://github.com/quickjs-ng/quickjs/issues/565
---
 quickjs.c             | 7 ++++++-
 tests/test_builtin.js | 2 ++
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/quickjs.c b/quickjs.c
index 646766705..6774f8494 100644
--- a/quickjs.c
+++ b/quickjs.c
@@ -43835,9 +43835,14 @@ static JSValue js_regexp_Symbol_split(JSContext *ctx, JSValue this_val,
                 if (js_get_length64(ctx, &numberOfCaptures, z))
                     goto exception;
                 for(i = 1; i < numberOfCaptures; i++) {
-                    sub = JS_ToStringFree(ctx, JS_GetPropertyInt64(ctx, z, i));
+                    sub = JS_GetPropertyInt64(ctx, z, i);
                     if (JS_IsException(sub))
                         goto exception;
+                    if (!JS_IsUndefined(sub)) {
+                        sub = JS_ToStringFree(ctx, sub);
+                        if (JS_IsException(sub))
+                            goto exception;
+                    }
                     if (JS_DefinePropertyValueInt64(ctx, A, lengthA++, sub, JS_PROP_C_W_E | JS_PROP_THROW) < 0)
                         goto exception;
                     if (lengthA == lim)
diff --git a/tests/test_builtin.js b/tests/test_builtin.js
index 411784e57..e02a0f707 100644
--- a/tests/test_builtin.js
+++ b/tests/test_builtin.js
@@ -783,6 +783,8 @@ function test_regexp()
     assert(a, ["a", undefined]);
     a = /(?:|[\w])+([0-9])/.exec("123a23");
     assert(a, ["123a23", "3"]);
+    a = "ab".split(/(c)*/);
+    assert(a, ["a", undefined, "b"]);
 }
 
 function test_symbol()