Skip to content

Commit

Permalink
fixes str.split() error with compileDebug
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tmont committed Jun 18, 2020
1 parent 76348c0 commit 7ea9f36
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 25 deletions.
18 changes: 12 additions & 6 deletions packages/pug-runtime/index.js
Expand Up @@ -247,18 +247,24 @@ function pug_rethrow(err, filename, lineno, str) {
err.message += ' on line ' + lineno;
throw err;
}
var context, lines, start, end;
try {
str = str || require('fs').readFileSync(filename, 'utf8');
var encoding = 'utf8';
str = str || require('fs').readFileSync(filename, {encoding: encoding});
if (str.type === 'Buffer') {
str = Buffer.from(str.data).toString(encoding);
}
context = 3;
lines = str.split('\n');
start = Math.max(lineno - context, 0);
end = Math.min(lines.length, lineno + context);
} catch (ex) {
pug_rethrow(err, null, lineno);
return;
}
var context = 3,
lines = str.split('\n'),
start = Math.max(lineno - context, 0),
end = Math.min(lines.length, lineno + context);

// Error context
var context = lines
context = lines
.slice(start, end)
.map(function(line, i) {
var curr = i + start + 1;
Expand Down
49 changes: 49 additions & 0 deletions packages/pug-runtime/test/index.test.js
Expand Up @@ -221,3 +221,52 @@ addTest('style', function(style) {
expect(style({foo: 'bar'})).toBe('foo:bar;');
expect(style({foo: 'bar', baz: 'bash'})).toBe('foo:bar;baz:bash;');
});

describe('rethrow', () => {
it('should rethrow error', () => {
const err = new Error();
try {
runtime.rethrow(err, 'foo.pug', 3);
} catch (e) {
expect(e).toBe(err);
return;
}

throw new Error('expected rethrow to throw');
});

it('should rethrow error with str', () => {
const err = new Error();
try {
runtime.rethrow(err, 'foo.pug', 3, 'hello world');
} catch (e) {
expect(e).toBe(err);
expect(e.message.trim()).toBe(
`
foo.pug:3
1| hello world`.trim()
);
return;
}

throw new Error('expected rethrow to throw');
});

it("should rethrow error with toJSON()'d Buffer", () => {
const err = new Error();
const str = Buffer.from('hello world').toJSON();
try {
runtime.rethrow(err, 'foo.pug', 3, str);
} catch (e) {
expect(e).toBe(err);
expect(e.message.trim()).toBe(
`
foo.pug:3
1| hello world`.trim()
);
return;
}

throw new Error('expected rethrow to throw');
});
});
40 changes: 21 additions & 19 deletions packages/pug/test/__snapshots__/pug.test.js.snap
Expand Up @@ -56,29 +56,31 @@ exports[`pug .compileClient() should support module syntax in pug.compileClient(
return c !== r ? s + a.substring(c, r) : s;
}
var pug_match_html = /[\\"&<>]/;
function pug_rethrow(n, e, t, r) {
function pug_rethrow(n, t, e, r) {
if (!(n instanceof Error)) throw n;
if (!((\\"undefined\\" == typeof window && e) || r))
throw ((n.message += \\" on line \\" + t), n);
if (!((\\"undefined\\" == typeof window && t) || r))
throw ((n.message += \\" on line \\" + e), n);
var i, o, a, f;
try {
r = r || require(\\"fs\\").readFileSync(e, \\"utf8\\");
} catch (e) {
pug_rethrow(n, null, t);
(r = r || require(\\"fs\\").readFileSync(t, { encoding: \\"utf8\\" })),
\\"Buffer\\" === r.type && (r = Buffer.from(r.data).toString(\\"utf8\\")),
(i = 3),
(o = r.split(\\"\\\\n\\")),
(a = Math.max(e - i, 0)),
(f = Math.min(o.length, e + i));
} catch (t) {
return void pug_rethrow(n, null, e);
}
var a = 3,
i = r.split(\\"\\\\n\\"),
o = Math.max(t - a, 0),
h = Math.min(i.length, t + a),
a = i
.slice(o, h)
.map(function(n, e) {
var r = e + o + 1;
return (r == t ? \\" > \\" : \\" \\") + r + \\"| \\" + n;
})
.join(\\"\\\\n\\");
n.path = e;
(i = o
.slice(a, f)
.map(function(n, t) {
var r = t + a + 1;
return (r == e ? \\" > \\" : \\" \\") + r + \\"| \\" + n;
})
.join(\\"\\\\n\\")),
(n.path = t);
try {
n.message = (e || \\"Pug\\") + \\":\\" + t + \\"\\\\n\\" + a + \\"\\\\n\\\\n\\" + n.message;
n.message = (t || \\"Pug\\") + \\":\\" + e + \\"\\\\n\\" + i + \\"\\\\n\\\\n\\" + n.message;
} catch (n) {}
throw n;
}
Expand Down
12 changes: 12 additions & 0 deletions packages/pug/test/error.reporting.test.js
Expand Up @@ -80,7 +80,19 @@ describe('error reporting', function() {
expect(err.message).toMatch(/[\\\/]include.locals.error.pug:2/);
expect(err.message).toMatch(/foo\(/);
});

it('handles compileDebug option properly', function() {
var err = getFileError(
__dirname + '/fixtures/compile.with.include.locals.error.pug',
{
compileDebug: true,
}
);
expect(err.message).toMatch(/[\\\/]include.locals.error.pug:2/);
expect(err.message).toMatch(/foo is not a function/);
});
});

describe('with a layout (without block) with an include (syntax)', function() {
it('includes detail of where the error was thrown including the filename', function() {
var err = getFileError(
Expand Down

0 comments on commit 7ea9f36

Please sign in to comment.