also looking at this
fix(runtime): realign ResolvedSource.Tag ids to the linked (pinned) Bun codegen
#117
2 files
+186
-235
| @@ -48,12 +48,17 @@ pub const Tag = enum(u32) { | ||
| 48 | 48 | // Built-in modules are loaded through `InternalModuleRegistry` by numerical |
| 49 | 49 | // ID; here they are represented as `(1 << 9) | id`. These values are |
| 50 | 50 | // generated by Bun's codegen (`build/*/codegen/ResolvedSourceTag.zig`) and |
| 51 | // MUST match the linked C++ objects' `InternalModuleRegistryConstants` — | |
| 51 | // MUST match the *linked* C++ objects' `InternalModuleRegistryConstants` — | |
| 52 | 52 | // the C++ module loader (ModuleLoader.cpp) masks off `InternalModuleRegistryFlag` |
| 53 | 53 | // (512) and calls `internalModuleRegistry()->requireId(... tag & 511)`. |
| 54 | // Copied verbatim from | |
| 55 | // `~/Code/bun/build/release/codegen/generated_resolved_source_tag.rs` at | |
| 56 | // Bun commit 4982b91e3702094330f3be3883354c52b8c01323. | |
| 54 | // | |
| 55 | // Copied VERBATIM from the codegen of the Bun build Home links against: | |
| 56 | // `~/Code/bun/build/release/codegen/ResolvedSourceTag.zig` at the pinned Bun | |
| 57 | // commit fd0b6f1a271fca0b8124b69f230b100f4d636af6 (1.3.14). These IDs are | |
| 58 | // ABI with the prebuilt C++ objects and MUST NOT be regenerated from a newer | |
| 59 | // Bun HEAD — doing so shifts every id (HEAD has ~21 extra internal modules), | |
| 60 | // so `require("node:path")` etc. select the wrong module and the internal | |
| 61 | // registry recurses (createInternalModuleById → createInternalModuleById). | |
| 57 | 62 | @"bun:ffi" = 512, |
| 58 | 63 | @"bun:sql" = 513, |
| 59 | 64 | @"bun:sqlite" = 514, |
| @@ -62,169 +67,149 @@ pub const Tag = enum(u32) { | ||
| 62 | 67 | @"internal:assert/calltracker" = 517, |
| 63 | 68 | @"internal:assert/myers_diff" = 518, |
| 64 | 69 | @"internal:assert/utils" = 519, |
| 65 | @"internal:async_context_frame" = 520, | |
| 66 | @"internal:async_hooks" = 521, | |
| 67 | @"internal:async_hooks_tick" = 522, | |
| 68 | @"internal:buffer" = 523, | |
| 69 | @"internal:cluster/RoundRobinHandle" = 524, | |
| 70 | @"internal:cluster/Worker" = 525, | |
| 71 | @"internal:cluster/child" = 526, | |
| 72 | @"internal:cluster/isPrimary" = 527, | |
| 73 | @"internal:cluster/primary" = 528, | |
| 74 | @"internal:crypto/x509" = 529, | |
| 75 | @"internal:debugger" = 530, | |
| 76 | @"internal:errors" = 531, | |
| 77 | @"internal:fifo" = 532, | |
| 78 | @"internal:fixed_queue" = 533, | |
| 79 | @"internal:freelist" = 534, | |
| 80 | @"internal:fs/binding" = 535, | |
| 81 | @"internal:fs/cp-sync" = 536, | |
| 82 | @"internal:fs/cp" = 537, | |
| 83 | @"internal:fs/glob" = 538, | |
| 84 | @"internal:fs/streams" = 539, | |
| 85 | @"internal:fs/watch" = 540, | |
| 86 | @"internal:fs/watchfile" = 541, | |
| 87 | @"internal:html" = 542, | |
| 88 | @"internal:http" = 543, | |
| 89 | @"internal:http/FakeSocket" = 544, | |
| 90 | @"internal:linkedlist" = 545, | |
| 91 | @"internal:net/isIP" = 546, | |
| 92 | @"internal:perf_hooks/monitorEventLoopDelay" = 547, | |
| 93 | @"internal:primordials" = 548, | |
| 94 | @"internal:promisify" = 549, | |
| 95 | @"internal:shared" = 550, | |
| 96 | @"internal:sql/errors" = 551, | |
| 97 | @"internal:sql/mysql" = 552, | |
| 98 | @"internal:sql/postgres" = 553, | |
| 99 | @"internal:sql/query" = 554, | |
| 100 | @"internal:sql/shared" = 555, | |
| 101 | @"internal:sql/sqlite" = 556, | |
| 102 | @"internal:stream/promises" = 557, | |
| 103 | @"internal:stream" = 558, | |
| 104 | @"internal:streams/add-abort-signal" = 559, | |
| 105 | @"internal:streams/compose" = 560, | |
| 106 | @"internal:streams/destroy" = 561, | |
| 107 | @"internal:streams/duplex" = 562, | |
| 108 | @"internal:streams/duplexify" = 563, | |
| 109 | @"internal:streams/duplexpair" = 564, | |
| 110 | @"internal:streams/end-of-stream" = 565, | |
| 111 | @"internal:streams/from" = 566, | |
| 112 | @"internal:streams/iter/broadcast" = 567, | |
| 113 | @"internal:streams/iter/classic" = 568, | |
| 114 | @"internal:streams/iter/consumers" = 569, | |
| 115 | @"internal:streams/iter/duplex" = 570, | |
| 116 | @"internal:streams/iter/from" = 571, | |
| 117 | @"internal:streams/iter/pull" = 572, | |
| 118 | @"internal:streams/iter/push" = 573, | |
| 119 | @"internal:streams/iter/ringbuffer" = 574, | |
| 120 | @"internal:streams/iter/share" = 575, | |
| 121 | @"internal:streams/iter/transform" = 576, | |
| 122 | @"internal:streams/iter/types" = 577, | |
| 123 | @"internal:streams/iter/utils" = 578, | |
| 124 | @"internal:streams/lazy_transform" = 579, | |
| 125 | @"internal:streams/legacy" = 580, | |
| 126 | @"internal:streams/native-readable" = 581, | |
| 127 | @"internal:streams/operators" = 582, | |
| 128 | @"internal:streams/passthrough" = 583, | |
| 129 | @"internal:streams/pipeline" = 584, | |
| 130 | @"internal:streams/readable" = 585, | |
| 131 | @"internal:streams/state" = 586, | |
| 132 | @"internal:streams/transform" = 587, | |
| 133 | @"internal:streams/utils" = 588, | |
| 134 | @"internal:streams/writable" = 589, | |
| 135 | @"internal:timers" = 590, | |
| 136 | @"internal:tls" = 591, | |
| 137 | @"internal:tty" = 592, | |
| 138 | @"internal:url" = 593, | |
| 139 | @"internal:util/colors" = 594, | |
| 140 | @"internal:util/deprecate" = 595, | |
| 141 | @"internal:util/inspect" = 596, | |
| 142 | @"internal:util/mime" = 597, | |
| 143 | @"internal:validators" = 598, | |
| 144 | @"internal:webstreams_adapters" = 599, | |
| 145 | @"node:_http2_upgrade" = 600, | |
| 146 | @"node:_http_agent" = 601, | |
| 147 | @"node:_http_client" = 602, | |
| 148 | @"node:_http_common" = 603, | |
| 149 | @"node:_http_incoming" = 604, | |
| 150 | @"node:_http_outgoing" = 605, | |
| 151 | @"node:_http_server" = 606, | |
| 152 | @"node:_stream_duplex" = 607, | |
| 153 | @"node:_stream_passthrough" = 608, | |
| 154 | @"node:_stream_readable" = 609, | |
| 155 | @"node:_stream_transform" = 610, | |
| 156 | @"node:_stream_wrap" = 611, | |
| 157 | @"node:_stream_writable" = 612, | |
| 158 | @"node:_tls_common" = 613, | |
| 159 | @"node:assert/strict" = 614, | |
| 160 | @"node:assert" = 615, | |
| 161 | @"node:async_hooks" = 616, | |
| 162 | @"node:child_process" = 617, | |
| 163 | @"node:cluster" = 618, | |
| 164 | @"node:console" = 619, | |
| 165 | @"node:crypto" = 620, | |
| 166 | @"node:dgram" = 621, | |
| 167 | @"node:diagnostics_channel" = 622, | |
| 168 | @"node:dns/promises" = 623, | |
| 169 | @"node:dns" = 624, | |
| 170 | @"node:domain" = 625, | |
| 171 | @"node:events" = 626, | |
| 172 | @"node:fs/promises" = 627, | |
| 173 | @"node:fs" = 628, | |
| 174 | @"node:http" = 629, | |
| 175 | @"node:http2" = 630, | |
| 176 | @"node:https" = 631, | |
| 177 | @"node:inspector/promises" = 632, | |
| 178 | @"node:inspector" = 633, | |
| 179 | @"node:net" = 634, | |
| 180 | @"node:os" = 635, | |
| 181 | @"node:path/posix" = 636, | |
| 182 | @"node:path" = 637, | |
| 183 | @"node:path/win32" = 638, | |
| 184 | @"node:perf_hooks" = 639, | |
| 185 | @"node:punycode" = 640, | |
| 186 | @"node:querystring" = 641, | |
| 187 | @"node:readline/promises" = 642, | |
| 188 | @"node:readline" = 643, | |
| 189 | @"node:repl" = 644, | |
| 190 | @"node:stream/consumers" = 645, | |
| 191 | @"node:stream/iter" = 646, | |
| 192 | @"node:stream/promises" = 647, | |
| 193 | @"node:stream" = 648, | |
| 194 | @"node:stream/web" = 649, | |
| 195 | @"node:test" = 650, | |
| 196 | @"node:timers/promises" = 651, | |
| 197 | @"node:timers" = 652, | |
| 198 | @"node:tls" = 653, | |
| 199 | @"node:trace_events" = 654, | |
| 200 | @"node:tty" = 655, | |
| 201 | @"node:url" = 656, | |
| 202 | @"node:util" = 657, | |
| 203 | @"node:v8" = 658, | |
| 204 | @"node:vm" = 659, | |
| 205 | @"node:wasi" = 660, | |
| 206 | @"node:worker_threads" = 661, | |
| 207 | @"node:zlib/iter" = 662, | |
| 208 | @"node:zlib" = 663, | |
| 209 | @"isomorphic-fetch" = 664, | |
| 210 | @"node-fetch" = 665, | |
| 211 | undici = 666, | |
| 212 | vercel_fetch = 667, | |
| 213 | ws = 668, | |
| 214 | @"bun:internal-for-testing" = 669, | |
| 70 | @"internal:buffer" = 520, | |
| 71 | @"internal:cluster/RoundRobinHandle" = 521, | |
| 72 | @"internal:cluster/Worker" = 522, | |
| 73 | @"internal:cluster/child" = 523, | |
| 74 | @"internal:cluster/isPrimary" = 524, | |
| 75 | @"internal:cluster/primary" = 525, | |
| 76 | @"internal:crypto/x509" = 526, | |
| 77 | @"internal:debugger" = 527, | |
| 78 | @"internal:errors" = 528, | |
| 79 | @"internal:fifo" = 529, | |
| 80 | @"internal:fixed_queue" = 530, | |
| 81 | @"internal:freelist" = 531, | |
| 82 | @"internal:fs/cp-sync" = 532, | |
| 83 | @"internal:fs/cp" = 533, | |
| 84 | @"internal:fs/glob" = 534, | |
| 85 | @"internal:fs/streams" = 535, | |
| 86 | @"internal:html" = 536, | |
| 87 | @"internal:http" = 537, | |
| 88 | @"internal:http/FakeSocket" = 538, | |
| 89 | @"internal:linkedlist" = 539, | |
| 90 | @"internal:net/isIP" = 540, | |
| 91 | @"internal:perf_hooks/monitorEventLoopDelay" = 541, | |
| 92 | @"internal:primordials" = 542, | |
| 93 | @"internal:promisify" = 543, | |
| 94 | @"internal:shared" = 544, | |
| 95 | @"internal:sql/errors" = 545, | |
| 96 | @"internal:sql/mysql" = 546, | |
| 97 | @"internal:sql/postgres" = 547, | |
| 98 | @"internal:sql/query" = 548, | |
| 99 | @"internal:sql/shared" = 549, | |
| 100 | @"internal:sql/sqlite" = 550, | |
| 101 | @"internal:stream/promises" = 551, | |
| 102 | @"internal:stream" = 552, | |
| 103 | @"internal:streams/add-abort-signal" = 553, | |
| 104 | @"internal:streams/compose" = 554, | |
| 105 | @"internal:streams/destroy" = 555, | |
| 106 | @"internal:streams/duplex" = 556, | |
| 107 | @"internal:streams/duplexify" = 557, | |
| 108 | @"internal:streams/duplexpair" = 558, | |
| 109 | @"internal:streams/end-of-stream" = 559, | |
| 110 | @"internal:streams/from" = 560, | |
| 111 | @"internal:streams/lazy_transform" = 561, | |
| 112 | @"internal:streams/legacy" = 562, | |
| 113 | @"internal:streams/native-readable" = 563, | |
| 114 | @"internal:streams/operators" = 564, | |
| 115 | @"internal:streams/passthrough" = 565, | |
| 116 | @"internal:streams/pipeline" = 566, | |
| 117 | @"internal:streams/readable" = 567, | |
| 118 | @"internal:streams/state" = 568, | |
| 119 | @"internal:streams/transform" = 569, | |
| 120 | @"internal:streams/utils" = 570, | |
| 121 | @"internal:streams/writable" = 571, | |
| 122 | @"internal:timers" = 572, | |
| 123 | @"internal:tls" = 573, | |
| 124 | @"internal:tty" = 574, | |
| 125 | @"internal:url" = 575, | |
| 126 | @"internal:util/colors" = 576, | |
| 127 | @"internal:util/deprecate" = 577, | |
| 128 | @"internal:util/inspect" = 578, | |
| 129 | @"internal:util/mime" = 579, | |
| 130 | @"internal:validators" = 580, | |
| 131 | @"internal:webstreams_adapters" = 581, | |
| 132 | @"node:_http2_upgrade" = 582, | |
| 133 | @"node:_http_agent" = 583, | |
| 134 | @"node:_http_client" = 584, | |
| 135 | @"node:_http_common" = 585, | |
| 136 | @"node:_http_incoming" = 586, | |
| 137 | @"node:_http_outgoing" = 587, | |
| 138 | @"node:_http_server" = 588, | |
| 139 | @"node:_stream_duplex" = 589, | |
| 140 | @"node:_stream_passthrough" = 590, | |
| 141 | @"node:_stream_readable" = 591, | |
| 142 | @"node:_stream_transform" = 592, | |
| 143 | @"node:_stream_wrap" = 593, | |
| 144 | @"node:_stream_writable" = 594, | |
| 145 | @"node:_tls_common" = 595, | |
| 146 | @"node:assert/strict" = 596, | |
| 147 | @"node:assert" = 597, | |
| 148 | @"node:async_hooks" = 598, | |
| 149 | @"node:child_process" = 599, | |
| 150 | @"node:cluster" = 600, | |
| 151 | @"node:console" = 601, | |
| 152 | @"node:crypto" = 602, | |
| 153 | @"node:dgram" = 603, | |
| 154 | @"node:diagnostics_channel" = 604, | |
| 155 | @"node:dns/promises" = 605, | |
| 156 | @"node:dns" = 606, | |
| 157 | @"node:domain" = 607, | |
| 158 | @"node:events" = 608, | |
| 159 | @"node:fs/promises" = 609, | |
| 160 | @"node:fs" = 610, | |
| 161 | @"node:http" = 611, | |
| 162 | @"node:http2" = 612, | |
| 163 | @"node:https" = 613, | |
| 164 | @"node:inspector/promises" = 614, | |
| 165 | @"node:inspector" = 615, | |
| 166 | @"node:net" = 616, | |
| 167 | @"node:os" = 617, | |
| 168 | @"node:path/posix" = 618, | |
| 169 | @"node:path" = 619, | |
| 170 | @"node:path/win32" = 620, | |
| 171 | @"node:perf_hooks" = 621, | |
| 172 | @"node:punycode" = 622, | |
| 173 | @"node:querystring" = 623, | |
| 174 | @"node:readline/promises" = 624, | |
| 175 | @"node:readline" = 625, | |
| 176 | @"node:repl" = 626, | |
| 177 | @"node:stream/consumers" = 627, | |
| 178 | @"node:stream/promises" = 628, | |
| 179 | @"node:stream" = 629, | |
| 180 | @"node:stream/web" = 630, | |
| 181 | @"node:test" = 631, | |
| 182 | @"node:timers/promises" = 632, | |
| 183 | @"node:timers" = 633, | |
| 184 | @"node:tls" = 634, | |
| 185 | @"node:trace_events" = 635, | |
| 186 | @"node:tty" = 636, | |
| 187 | @"node:url" = 637, | |
| 188 | @"node:util" = 638, | |
| 189 | @"node:v8" = 639, | |
| 190 | @"node:vm" = 640, | |
| 191 | @"node:wasi" = 641, | |
| 192 | @"node:worker_threads" = 642, | |
| 193 | @"node:zlib" = 643, | |
| 194 | @"isomorphic-fetch" = 644, | |
| 195 | @"node-fetch" = 645, | |
| 196 | @"undici" = 646, | |
| 197 | @"vercel_fetch" = 647, | |
| 198 | @"ws" = 648, | |
| 199 | @"bun:internal-for-testing" = 649, | |
| 215 | 200 | // Native modules come after the JS modules |
| 216 | @"bun:test" = 670, | |
| 217 | @"bun:jsc" = 671, | |
| 218 | @"bun:app" = 672, | |
| 219 | @"node:buffer" = 673, | |
| 220 | @"node:constants" = 674, | |
| 221 | @"node:string_decoder" = 675, | |
| 222 | @"node:util/types" = 676, | |
| 223 | @"utf-8-validate" = 677, | |
| 224 | @"abort-controller" = 678, | |
| 225 | @"node:module" = 679, | |
| 226 | @"node:process" = 680, | |
| 227 | bun = 681, | |
| 201 | @"bun:test" = 650, | |
| 202 | @"bun:jsc" = 651, | |
| 203 | @"bun:app" = 652, | |
| 204 | @"node:buffer" = 653, | |
| 205 | @"node:constants" = 654, | |
| 206 | @"node:string_decoder" = 655, | |
| 207 | @"node:util/types" = 656, | |
| 208 | @"utf-8-validate" = 657, | |
| 209 | @"abort-controller" = 658, | |
| 210 | @"node:module" = 659, | |
| 211 | @"node:process" = 660, | |
| 212 | @"bun" = 661, | |
| 228 | 213 | _, |
| 229 | 214 | }; |
| 230 | 215 | |
| @@ -293,13 +278,17 @@ test "Tag structural variants stay in lock-step with headers-handwritten.h" { | ||
| 293 | 278 | } |
| 294 | 279 | |
| 295 | 280 | test "Tag builtin ids stay in lock-step with linked Bun codegen" { |
| 296 | try std.testing.expectEqual(@as(u32, 520), @intFromEnum(Tag.@"internal:async_context_frame")); | |
| 297 | try std.testing.expectEqual(@as(u32, 535), @intFromEnum(Tag.@"internal:fs/binding")); | |
| 298 | try std.testing.expectEqual(@as(u32, 567), @intFromEnum(Tag.@"internal:streams/iter/broadcast")); | |
| 299 | try std.testing.expectEqual(@as(u32, 646), @intFromEnum(Tag.@"node:stream/iter")); | |
| 300 | try std.testing.expectEqual(@as(u32, 650), @intFromEnum(Tag.@"node:test")); | |
| 301 | try std.testing.expectEqual(@as(u32, 670), @intFromEnum(Tag.@"bun:test")); | |
| 302 | try std.testing.expectEqual(@as(u32, 681), @intFromEnum(Tag.bun)); | |
| 281 | // These MUST match `~/Code/bun/build/release/codegen/ResolvedSourceTag.zig` | |
| 282 | // at the pinned Bun commit (fd0b6f1a27 / 1.3.14) — i.e. the codegen of the | |
| 283 | // C++ objects Home actually links. Regenerating from a newer Bun HEAD (which | |
| 284 | // has ~21 extra internal modules) shifts every id and breaks node builtins. | |
| 285 | try std.testing.expectEqual(@as(u32, 520), @intFromEnum(Tag.@"internal:buffer")); | |
| 286 | try std.testing.expectEqual(@as(u32, 535), @intFromEnum(Tag.@"internal:fs/streams")); | |
| 287 | try std.testing.expectEqual(@as(u32, 610), @intFromEnum(Tag.@"node:fs")); | |
| 288 | try std.testing.expectEqual(@as(u32, 619), @intFromEnum(Tag.@"node:path")); | |
| 289 | try std.testing.expectEqual(@as(u32, 631), @intFromEnum(Tag.@"node:test")); | |
| 290 | try std.testing.expectEqual(@as(u32, 650), @intFromEnum(Tag.@"bun:test")); | |
| 291 | try std.testing.expectEqual(@as(u32, 661), @intFromEnum(Tag.@"bun")); | |
| 303 | 292 | } |
| 304 | 293 | |
| 305 | 294 | test "String stub size matches the upstream BunString" { |
| @@ -1003,6 +1003,10 @@ pub const FileSystemFlags = enum(c_int) { | ||
| 1003 | 1003 | |
| 1004 | 1004 | _, |
| 1005 | 1005 | |
| 1006 | // Node's stringToFlags is a case-SENSITIVE, strict-equality switch over | |
| 1007 | // exactly these 22 primitive strings (any other string throws | |
| 1008 | // ERR_INVALID_ARG_VALUE). Uppercase spellings ("W", "A+", ...) must NOT be | |
| 1009 | // accepted. Ports oven-sh/bun 459c33fa9f (#32966). | |
| 1006 | 1010 | const map = bun.ComptimeStringMap(i32, .{ |
| 1007 | 1011 | .{ "r", O.RDONLY }, |
| 1008 | 1012 | .{ "rs", O.RDONLY | O.SYNC }, |
| @@ -1011,52 +1015,25 @@ pub const FileSystemFlags = enum(c_int) { | ||
| 1011 | 1015 | .{ "rs+", O.RDWR | O.SYNC }, |
| 1012 | 1016 | .{ "sr+", O.RDWR | O.SYNC }, |
| 1013 | 1017 | |
| 1014 | .{ "R", O.RDONLY }, | |
| 1015 | .{ "RS", O.RDONLY | O.SYNC }, | |
| 1016 | .{ "SR", O.RDONLY | O.SYNC }, | |
| 1017 | .{ "R+", O.RDWR }, | |
| 1018 | .{ "RS+", O.RDWR | O.SYNC }, | |
| 1019 | .{ "SR+", O.RDWR | O.SYNC }, | |
| 1020 | ||
| 1021 | 1018 | .{ "w", O.TRUNC | O.CREAT | O.WRONLY }, |
| 1022 | 1019 | .{ "wx", O.TRUNC | O.CREAT | O.WRONLY | O.EXCL }, |
| 1023 | 1020 | .{ "xw", O.TRUNC | O.CREAT | O.WRONLY | O.EXCL }, |
| 1024 | 1021 | |
| 1025 | .{ "W", O.TRUNC | O.CREAT | O.WRONLY }, | |
| 1026 | .{ "WX", O.TRUNC | O.CREAT | O.WRONLY | O.EXCL }, | |
| 1027 | .{ "XW", O.TRUNC | O.CREAT | O.WRONLY | O.EXCL }, | |
| 1028 | ||
| 1029 | 1022 | .{ "w+", O.TRUNC | O.CREAT | O.RDWR }, |
| 1030 | 1023 | .{ "wx+", O.TRUNC | O.CREAT | O.RDWR | O.EXCL }, |
| 1031 | 1024 | .{ "xw+", O.TRUNC | O.CREAT | O.RDWR | O.EXCL }, |
| 1032 | 1025 | |
| 1033 | .{ "W+", O.TRUNC | O.CREAT | O.RDWR }, | |
| 1034 | .{ "WX+", O.TRUNC | O.CREAT | O.RDWR | O.EXCL }, | |
| 1035 | .{ "XW+", O.TRUNC | O.CREAT | O.RDWR | O.EXCL }, | |
| 1036 | ||
| 1037 | 1026 | .{ "a", O.APPEND | O.CREAT | O.WRONLY }, |
| 1038 | 1027 | .{ "ax", O.APPEND | O.CREAT | O.WRONLY | O.EXCL }, |
| 1039 | 1028 | .{ "xa", O.APPEND | O.CREAT | O.WRONLY | O.EXCL }, |
| 1040 | 1029 | .{ "as", O.APPEND | O.CREAT | O.WRONLY | O.SYNC }, |
| 1041 | 1030 | .{ "sa", O.APPEND | O.CREAT | O.WRONLY | O.SYNC }, |
| 1042 | 1031 | |
| 1043 | .{ "A", O.APPEND | O.CREAT | O.WRONLY }, | |
| 1044 | .{ "AX", O.APPEND | O.CREAT | O.WRONLY | O.EXCL }, | |
| 1045 | .{ "XA", O.APPEND | O.CREAT | O.WRONLY | O.EXCL }, | |
| 1046 | .{ "AS", O.APPEND | O.CREAT | O.WRONLY | O.SYNC }, | |
| 1047 | .{ "SA", O.APPEND | O.CREAT | O.WRONLY | O.SYNC }, | |
| 1048 | ||
| 1049 | 1032 | .{ "a+", O.APPEND | O.CREAT | O.RDWR }, |
| 1050 | 1033 | .{ "ax+", O.APPEND | O.CREAT | O.RDWR | O.EXCL }, |
| 1051 | 1034 | .{ "xa+", O.APPEND | O.CREAT | O.RDWR | O.EXCL }, |
| 1052 | 1035 | .{ "as+", O.APPEND | O.CREAT | O.RDWR | O.SYNC }, |
| 1053 | 1036 | .{ "sa+", O.APPEND | O.CREAT | O.RDWR | O.SYNC }, |
| 1054 | ||
| 1055 | .{ "A+", O.APPEND | O.CREAT | O.RDWR }, | |
| 1056 | .{ "AX+", O.APPEND | O.CREAT | O.RDWR | O.EXCL }, | |
| 1057 | .{ "XA+", O.APPEND | O.CREAT | O.RDWR | O.EXCL }, | |
| 1058 | .{ "AS+", O.APPEND | O.CREAT | O.RDWR | O.SYNC }, | |
| 1059 | .{ "SA+", O.APPEND | O.CREAT | O.RDWR | O.SYNC }, | |
| 1060 | 1037 | }); |
| 1061 | 1038 | |
| 1062 | 1039 | pub fn fromJS(ctx: *jsc.JSGlobalObject, val: jsc.JSValue) bun.JSError!?FileSystemFlags { |
| @@ -1076,45 +1053,30 @@ pub const FileSystemFlags = enum(c_int) { | ||
| 1076 | 1053 | return @as(FileSystemFlags, @enumFromInt(flags)); |
| 1077 | 1054 | } |
| 1078 | 1055 | |
| 1079 | const jsType = val.jsType(); | |
| 1080 | if (jsType.isStringLike()) { | |
| 1081 | const str = try val.getZigString(ctx); | |
| 1082 | if (str.isEmpty()) { | |
| 1083 | return ctx.throwInvalidArguments("Expected flags to be a non-empty string. Learn more at https://nodejs.org/api/fs.html#fs_file_system_flags", .{}); | |
| 1084 | } | |
| 1085 | // it's definitely wrong when the string is super long | |
| 1086 | else if (str.len > 12) { | |
| 1087 | return ctx.throwInvalidArguments("Invalid flag '{f}'. Learn more at https://nodejs.org/api/fs.html#fs_file_system_flags", .{str}); | |
| 1088 | } | |
| 1056 | if (val.isUndefinedOrNull()) { | |
| 1057 | return null; | |
| 1058 | } | |
| 1089 | 1059 | |
| 1090 | const flags: i32 = brk: { | |
| 1091 | switch (str.is16Bit()) { | |
| 1092 | inline else => |is_16bit| { | |
| 1093 | const chars = if (is_16bit) str.utf16SliceAligned() else str.slice(); | |
| 1094 | ||
| 1095 | if (std.ascii.isDigit(@as(u8, @truncate(chars[0])))) { | |
| 1096 | // node allows "0o644" as a string :( | |
| 1097 | if (is_16bit) { | |
| 1098 | const slice = str.toSlice(bun.default_allocator); | |
| 1099 | defer slice.deinit(); | |
| 1100 | ||
| 1101 | break :brk @as(i32, @intCast(std.fmt.parseInt(Mode, slice.slice(), 10) catch break :brk null)); | |
| 1102 | } else { | |
| 1103 | break :brk @as(i32, @intCast(std.fmt.parseInt(Mode, chars, 10) catch break :brk null)); | |
| 1104 | } | |
| 1105 | } | |
| 1106 | }, | |
| 1060 | // Node switches on the value with strict equality, so only primitive | |
| 1061 | // strings can match; every other value (including a `new String("w")` | |
| 1062 | // wrapper, if it reaches here) throws ERR_INVALID_ARG_VALUE (not | |
| 1063 | // ERR_INVALID_ARG_TYPE), and a leading digit is NOT parsed as a raw | |
| 1064 | // open(2) flag. Ports oven-sh/bun 459c33fa9f (#32966). NB: with the pinned | |
| 1065 | // internal `fs.ts`, a String-wrapper flag is coerced/defaulted in JS | |
| 1066 | // before reaching native, so that specific case surfaces as ENOENT until | |
| 1067 | // Home bumps Bun; all primitive-string cases are validated here. | |
| 1068 | if (val.isStringLiteral()) { | |
| 1069 | const str = try val.getZigString(ctx); | |
| 1070 | // The longest valid flag string is 3 bytes ("as+", "wx+", ...). | |
| 1071 | if (str.len >= 1 and str.len <= 3) { | |
| 1072 | if (map.getWithEql(str, jsc.ZigString.eqlComptime)) |flags| { | |
| 1073 | return @enumFromInt(flags); | |
| 1107 | 1074 | } |
| 1108 | ||
| 1109 | break :brk map.getWithEql(str, jsc.ZigString.eqlComptime) orelse break :brk null; | |
| 1110 | } orelse { | |
| 1111 | return ctx.throwInvalidArguments("Invalid flag '{f}'. Learn more at https://nodejs.org/api/fs.html#fs_file_system_flags", .{str}); | |
| 1112 | }; | |
| 1113 | ||
| 1114 | return @enumFromInt(flags); | |
| 1075 | } | |
| 1115 | 1076 | } |
| 1116 | 1077 | |
| 1117 | return null; | |
| 1078 | var formatter = jsc.ConsoleObject.Formatter{ .globalThis = ctx }; | |
| 1079 | return ctx.ERR(.INVALID_ARG_VALUE, "The argument 'flags' is invalid. Received {f}", .{val.toFmt(&formatter)}).throw(); | |
| 1118 | 1080 | } |
| 1119 | 1081 | |
| 1120 | 1082 | /// Equivalent of GetValidFileMode, which is used to implement fs.access and copyFile |