|
10 | 10 |
|
11 | 11 | 'use strict'; |
12 | 12 |
|
| 13 | +import fs from 'fs'; |
| 14 | +import os from 'os'; |
| 15 | +import path from 'path'; |
13 | 16 | import {patchSetImmediate} from '../../../../scripts/jest/patchSetImmediate'; |
14 | 17 |
|
15 | | -global.ReadableStream = |
16 | | - require('web-streams-polyfill/ponyfill/es6').ReadableStream; |
17 | | - |
18 | 18 | let clientExports; |
19 | 19 | let webpackMap; |
20 | 20 | let webpackModules; |
@@ -1136,4 +1136,37 @@ describe('ReactFlightDOMNode', () => { |
1136 | 1136 | 'Switched to client rendering because the server rendering errored:\n\nssr-throw', |
1137 | 1137 | ); |
1138 | 1138 | }); |
| 1139 | + |
| 1140 | + // This is a regression test for a specific issue where byte Web Streams are |
| 1141 | + // detaching ArrayBuffers, which caused downstream issues (e.g. "Cannot |
| 1142 | + // perform Construct on a detached ArrayBuffer") for chunks that are using |
| 1143 | + // Node's internal Buffer pool. |
| 1144 | + it('should not corrupt the Node.js Buffer pool by detaching ArrayBuffers when using Web Streams', async () => { |
| 1145 | + // Create a temp file smaller than 4KB to ensure it uses the Buffer pool. |
| 1146 | + const file = path.join(os.tmpdir(), 'test.bin'); |
| 1147 | + fs.writeFileSync(file, Buffer.alloc(4095)); |
| 1148 | + const fileChunk = fs.readFileSync(file); |
| 1149 | + fs.unlinkSync(file); |
| 1150 | + |
| 1151 | + // Verify this chunk uses the Buffer pool (8192 bytes for files < 4KB). |
| 1152 | + expect(fileChunk.buffer.byteLength).toBe(8192); |
| 1153 | + |
| 1154 | + const readable = await serverAct(() => |
| 1155 | + ReactServerDOMServer.renderToReadableStream(fileChunk, webpackMap), |
| 1156 | + ); |
| 1157 | + |
| 1158 | + // Create a Web Streams WritableStream that tries to use Buffer operations. |
| 1159 | + const writable = new WritableStream({ |
| 1160 | + write(chunk) { |
| 1161 | + // Only write one byte to ensure Node.js is not creating a new Buffer |
| 1162 | + // pool. Typically, library code (e.g. a compression middleware) would |
| 1163 | + // call Buffer.from(chunk) or similar, instead of allocating a new |
| 1164 | + // Buffer directly. With that, the test file could only be ~2600 bytes. |
| 1165 | + Buffer.allocUnsafe(1); |
| 1166 | + }, |
| 1167 | + }); |
| 1168 | + |
| 1169 | + // Must not throw an error. |
| 1170 | + await readable.pipeTo(writable); |
| 1171 | + }); |
1139 | 1172 | }); |
0 commit comments