Skip to content

Commit 7ea9f36

Browse files
committed
fixes str.split() error with compileDebug
If compileDebug is enabled, a Buffer would be serialized and then pug-runtime would try to split() it assuming it would always be a string.
1 parent 76348c0 commit 7ea9f36

File tree

4 files changed

+94
-25
lines changed

4 files changed

+94
-25
lines changed

packages/pug-runtime/index.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,18 +247,24 @@ function pug_rethrow(err, filename, lineno, str) {
247247
err.message += ' on line ' + lineno;
248248
throw err;
249249
}
250+
var context, lines, start, end;
250251
try {
251-
str = str || require('fs').readFileSync(filename, 'utf8');
252+
var encoding = 'utf8';
253+
str = str || require('fs').readFileSync(filename, {encoding: encoding});
254+
if (str.type === 'Buffer') {
255+
str = Buffer.from(str.data).toString(encoding);
256+
}
257+
context = 3;
258+
lines = str.split('\n');
259+
start = Math.max(lineno - context, 0);
260+
end = Math.min(lines.length, lineno + context);
252261
} catch (ex) {
253262
pug_rethrow(err, null, lineno);
263+
return;
254264
}
255-
var context = 3,
256-
lines = str.split('\n'),
257-
start = Math.max(lineno - context, 0),
258-
end = Math.min(lines.length, lineno + context);
259265

260266
// Error context
261-
var context = lines
267+
context = lines
262268
.slice(start, end)
263269
.map(function(line, i) {
264270
var curr = i + start + 1;

packages/pug-runtime/test/index.test.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,52 @@ addTest('style', function(style) {
221221
expect(style({foo: 'bar'})).toBe('foo:bar;');
222222
expect(style({foo: 'bar', baz: 'bash'})).toBe('foo:bar;baz:bash;');
223223
});
224+
225+
describe('rethrow', () => {
226+
it('should rethrow error', () => {
227+
const err = new Error();
228+
try {
229+
runtime.rethrow(err, 'foo.pug', 3);
230+
} catch (e) {
231+
expect(e).toBe(err);
232+
return;
233+
}
234+
235+
throw new Error('expected rethrow to throw');
236+
});
237+
238+
it('should rethrow error with str', () => {
239+
const err = new Error();
240+
try {
241+
runtime.rethrow(err, 'foo.pug', 3, 'hello world');
242+
} catch (e) {
243+
expect(e).toBe(err);
244+
expect(e.message.trim()).toBe(
245+
`
246+
foo.pug:3
247+
1| hello world`.trim()
248+
);
249+
return;
250+
}
251+
252+
throw new Error('expected rethrow to throw');
253+
});
254+
255+
it("should rethrow error with toJSON()'d Buffer", () => {
256+
const err = new Error();
257+
const str = Buffer.from('hello world').toJSON();
258+
try {
259+
runtime.rethrow(err, 'foo.pug', 3, str);
260+
} catch (e) {
261+
expect(e).toBe(err);
262+
expect(e.message.trim()).toBe(
263+
`
264+
foo.pug:3
265+
1| hello world`.trim()
266+
);
267+
return;
268+
}
269+
270+
throw new Error('expected rethrow to throw');
271+
});
272+
});

packages/pug/test/__snapshots__/pug.test.js.snap

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -56,29 +56,31 @@ exports[`pug .compileClient() should support module syntax in pug.compileClient(
5656
return c !== r ? s + a.substring(c, r) : s;
5757
}
5858
var pug_match_html = /[\\"&<>]/;
59-
function pug_rethrow(n, e, t, r) {
59+
function pug_rethrow(n, t, e, r) {
6060
if (!(n instanceof Error)) throw n;
61-
if (!((\\"undefined\\" == typeof window && e) || r))
62-
throw ((n.message += \\" on line \\" + t), n);
61+
if (!((\\"undefined\\" == typeof window && t) || r))
62+
throw ((n.message += \\" on line \\" + e), n);
63+
var i, o, a, f;
6364
try {
64-
r = r || require(\\"fs\\").readFileSync(e, \\"utf8\\");
65-
} catch (e) {
66-
pug_rethrow(n, null, t);
65+
(r = r || require(\\"fs\\").readFileSync(t, { encoding: \\"utf8\\" })),
66+
\\"Buffer\\" === r.type && (r = Buffer.from(r.data).toString(\\"utf8\\")),
67+
(i = 3),
68+
(o = r.split(\\"\\\\n\\")),
69+
(a = Math.max(e - i, 0)),
70+
(f = Math.min(o.length, e + i));
71+
} catch (t) {
72+
return void pug_rethrow(n, null, e);
6773
}
68-
var a = 3,
69-
i = r.split(\\"\\\\n\\"),
70-
o = Math.max(t - a, 0),
71-
h = Math.min(i.length, t + a),
72-
a = i
73-
.slice(o, h)
74-
.map(function(n, e) {
75-
var r = e + o + 1;
76-
return (r == t ? \\" > \\" : \\" \\") + r + \\"| \\" + n;
77-
})
78-
.join(\\"\\\\n\\");
79-
n.path = e;
74+
(i = o
75+
.slice(a, f)
76+
.map(function(n, t) {
77+
var r = t + a + 1;
78+
return (r == e ? \\" > \\" : \\" \\") + r + \\"| \\" + n;
79+
})
80+
.join(\\"\\\\n\\")),
81+
(n.path = t);
8082
try {
81-
n.message = (e || \\"Pug\\") + \\":\\" + t + \\"\\\\n\\" + a + \\"\\\\n\\\\n\\" + n.message;
83+
n.message = (t || \\"Pug\\") + \\":\\" + e + \\"\\\\n\\" + i + \\"\\\\n\\\\n\\" + n.message;
8284
} catch (n) {}
8385
throw n;
8486
}

packages/pug/test/error.reporting.test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,19 @@ describe('error reporting', function() {
8080
expect(err.message).toMatch(/[\\\/]include.locals.error.pug:2/);
8181
expect(err.message).toMatch(/foo\(/);
8282
});
83+
84+
it('handles compileDebug option properly', function() {
85+
var err = getFileError(
86+
__dirname + '/fixtures/compile.with.include.locals.error.pug',
87+
{
88+
compileDebug: true,
89+
}
90+
);
91+
expect(err.message).toMatch(/[\\\/]include.locals.error.pug:2/);
92+
expect(err.message).toMatch(/foo is not a function/);
93+
});
8394
});
95+
8496
describe('with a layout (without block) with an include (syntax)', function() {
8597
it('includes detail of where the error was thrown including the filename', function() {
8698
var err = getFileError(

0 commit comments

Comments
 (0)