Skip to content

Commit 100d3d9

Browse files
authored
Merge pull request #1113 from OpenFn/expose-buffer
Runtime: expose Buffer
2 parents 836433d + 69496ac commit 100d3d9

3 files changed

Lines changed: 43 additions & 0 deletions

File tree

.changeset/pretty-spoons-share.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@openfn/runtime': patch
3+
---
4+
5+
Expose Buffer to runtime context. Quite safe in node 20+

packages/runtime/src/execute/context.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,19 @@ export default (
2121
) => {
2222
const logger = options.jobLogger ?? console;
2323
const globals = options.globals || {};
24+
25+
// Workaround for https://github.com/nodejs/node/issues/4660
26+
// The Buffer class we share directly with users will throw if used
27+
// All _internal_ Buffer references use the original nodejs interface
28+
class SafeBuffer extends Buffer {
29+
constructor(x: any) {
30+
throw new Error(
31+
'Do not call Buffer() constructor directly. Use Buffer.from() instead.'
32+
);
33+
super(x); // keeps types happy
34+
}
35+
}
36+
2437
const context = vm.createContext(
2538
freezeAll(
2639
{
@@ -34,6 +47,7 @@ export default (
3447
setInterval,
3548
setTimeout,
3649
state, // TODO will be dropped as a global one day, see https://github.com/OpenFn/kit/issues/17
50+
Buffer: SafeBuffer,
3751
},
3852
{ state: true }
3953
),

packages/runtime/test/context.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,27 @@ test("doesn't allow eval inside a job", async (t) => {
6060
message: /Illegal eval statement detected/,
6161
});
6262
});
63+
64+
test('Buffer.from() works inside a job', async (t) => {
65+
const expression = `
66+
export default [
67+
(s) => { s.data = Buffer.from('6a6f65', 'hex').toString(); return s; }
68+
];`;
69+
const input = {};
70+
71+
const result = await run(expression, input);
72+
t.is(result.data as any, 'joe');
73+
});
74+
75+
test('Buffer constructor throws inside a job', async (t) => {
76+
const expression = `
77+
export default [
78+
(s) => { s.data = new Buffer('6a6f65', 'hex').toString(); return s; }
79+
];`;
80+
const input = {};
81+
82+
const result = await run(expression, input);
83+
const err = result.errors!['job-1'];
84+
t.is(err.name, 'JobError');
85+
t.regex(err.message, /do not call Buffer\(\) constructor/i);
86+
});

0 commit comments

Comments
 (0)