From ad3dafa76825804f48c52a27f8a3df56147436e7 Mon Sep 17 00:00:00 2001 From: Mihail Stoykov Date: Fri, 27 Sep 2024 17:25:14 +0300 Subject: [PATCH] Make certain readyState is actually a number when returned for some reason - likely a bug in goja/Sobek returning a type that is uint8 under the hood (or int) doesn't actually get to be a number in js. The current fix casts the ReadyState type to uint8 so that Sobek handles it correctly. Fixes #79 --- websockets/websockets.go | 4 ++-- websockets/websockets_test.go | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/websockets/websockets.go b/websockets/websockets.go index af24426..359f70c 100644 --- a/websockets/websockets.go +++ b/websockets/websockets.go @@ -187,8 +187,8 @@ func defineWebsocket(rt *sobek.Runtime, w *webSocket) { must(rt, w.obj.DefineDataProperty( "url", rt.ToValue(w.url.String()), sobek.FLAG_FALSE, sobek.FLAG_FALSE, sobek.FLAG_TRUE)) must(rt, w.obj.DefineAccessorProperty( // this needs to be with an accessor as we change the value - "readyState", rt.ToValue(func() ReadyState { - return w.readyState + "readyState", rt.ToValue(func() sobek.Value { + return rt.ToValue((uint)(w.readyState)) }), nil, sobek.FLAG_FALSE, sobek.FLAG_TRUE)) must(rt, w.obj.DefineAccessorProperty( "bufferedAmount", rt.ToValue(func() sobek.Value { return rt.ToValue(w.bufferedAmount) }), nil, diff --git a/websockets/websockets_test.go b/websockets/websockets_test.go index 9b653dc..bac0e8d 100644 --- a/websockets/websockets_test.go +++ b/websockets/websockets_test.go @@ -1527,3 +1527,26 @@ func testArrayBufferViewSupport(t *testing.T, viewName string) { logs := hook.Drain() require.Len(t, logs, 0) } + +func TestReadyStateSwitch(t *testing.T) { + t.Parallel() + ts := newTestState(t) + logger, hook := testutils.NewLoggerWithHook(t, logrus.WarnLevel) + ts.runtime.VU.StateField.Logger = logger + _, err := ts.runtime.RunOnEventLoop(ts.tb.Replacer.Replace(` + var ws = new WebSocket("WSBIN_URL/ws-echo") + try { + switch (ws.readyState) { + case 0: + break; + default: + throw "ws.readyState doesn't get correct value in switch" + } + } finally { + ws.close() + } + `)) + require.NoError(t, err) + logs := hook.Drain() + require.Len(t, logs, 0) +}