From c4fa1e38dcc459fa2a73d3e2316888c06290f1af Mon Sep 17 00:00:00 2001 From: rcaselles Date: Tue, 7 May 2024 23:51:02 +0200 Subject: [PATCH] Fix confirm is never true in windows (#10802) Co-authored-by: rcaselles --- src/bun.js/webcore.zig | 19 ++++++++++++++++- test/js/web/web-globals.test.js | 36 +++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/bun.js/webcore.zig b/src/bun.js/webcore.zig index 2e4b9ff711..be2c26a022 100644 --- a/src/bun.js/webcore.zig +++ b/src/bun.js/webcore.zig @@ -122,6 +122,15 @@ fn confirm(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callcon switch (first_byte) { '\n' => return .false, + '\r' => { + const next_byte = reader.readByte() catch { + // They may have said yes, but the stdin is invalid. + return .false; + }; + if(next_byte == '\n'){ + return .false; + } + }, 'y', 'Y' => { const next_byte = reader.readByte() catch { // They may have said yes, but the stdin is invalid. @@ -133,13 +142,21 @@ fn confirm(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callcon // 8. If the user responded positively, return true; // otherwise, the user responded negatively: return false. return .true; + }else if(next_byte == '\r'){ + //Check Windows style + const second_byte = reader.readByte() catch { + return .false; + }; + if (second_byte == '\n') { + return .true; + } } }, else => {}, } while (reader.readByte()) |b| { - if (b == '\n') break; + if (b == '\n' or b == '\r') break; } else |_| {} // 8. If the user responded positively, return true; otherwise, the user diff --git a/test/js/web/web-globals.test.js b/test/js/web/web-globals.test.js index 8f2ea8aca3..6cc96812e2 100644 --- a/test/js/web/web-globals.test.js +++ b/test/js/web/web-globals.test.js @@ -240,7 +240,7 @@ test("navigator", () => { } }); -test("confirm (yes)", async () => { +test("confirm (yes) unix newline", async () => { const proc = spawn({ cmd: [bunExe(), require("path").join(import.meta.dir, "./confirm-fixture.js")], stdio: ["pipe", "pipe", "pipe"], @@ -258,7 +258,25 @@ test("confirm (yes)", async () => { expect(await new Response(proc.stderr).text()).toBe("Yes\n"); }); -test("confirm (no)", async () => { +test("confirm (yes) windows newline", async () => { + const proc = spawn({ + cmd: [bunExe(), require("path").join(import.meta.dir, "./confirm-fixture.js")], + stdio: ["pipe", "pipe", "pipe"], + env: bunEnv, + }); + + proc.stdin.write("Y"); + await proc.stdin.flush(); + + proc.stdin.write("\r\n"); // Windows-style newline + await proc.stdin.flush(); + + await proc.exited; + + expect(await new Response(proc.stderr).text()).toBe("Yes\n"); +}); + +test("confirm (no) unix newline", async () => { const proc = spawn({ cmd: [bunExe(), require("path").join(import.meta.dir, "./confirm-fixture.js")], stdio: ["pipe", "pipe", "pipe"], @@ -272,6 +290,20 @@ test("confirm (no)", async () => { expect(await new Response(proc.stderr).text()).toBe("No\n"); }); +test("confirm (no) windows newline", async () => { + const proc = spawn({ + cmd: [bunExe(), require("path").join(import.meta.dir, "./confirm-fixture.js")], + stdio: ["pipe", "pipe", "pipe"], + env: bunEnv, + }); + + proc.stdin.write("poask\r\n"); + await proc.stdin.flush(); + await proc.exited; + + expect(await new Response(proc.stderr).text()).toBe("No\n"); +}); + test("globalThis.self = 123 works", () => { expect(Object.getOwnPropertyDescriptor(globalThis, "self")).toMatchObject({ configurable: true,