Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(node) add max lineno and colno limits #12514

Merged
merged 27 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9a8bf25
ref(node): use readline for context lines
JonasBa May 25, 2024
f134e4e
test(node): contextline tests
JonasBa May 26, 2024
b768d18
test(node): contextline tests
JonasBa May 26, 2024
a5929e4
ref(node): contextlines cache attempt
JonasBa May 28, 2024
d07afc5
ref(node) exclude other contextlines extensions
JonasBa Jun 9, 2024
4e3b7ce
test(node) fix contextlines test
JonasBa Jun 10, 2024
8bc27f9
fix scoped test
JonasBa Jun 10, 2024
811d12a
lint
JonasBa Jun 10, 2024
0fd4228
fix regexp danger warning
JonasBa Jun 10, 2024
72879e1
strict undefined check
JonasBa Jun 10, 2024
c1c5dbc
reshuffle order
JonasBa Jun 10, 2024
4cdae35
test adding error handler on input stream
JonasBa Jun 10, 2024
e183e86
lint
JonasBa Jun 10, 2024
fcdbdc2
fix duplicate reads on stream error
JonasBa Jun 11, 2024
d53ff2e
fix duplicate reads on stream error
JonasBa Jun 11, 2024
8ead438
add emplace
JonasBa Jun 11, 2024
e7ca32d
fix(node) last line is not picked up as it does not include \n
JonasBa Jun 11, 2024
c961478
ref(contexlines) use ordered startsWith instead of regexp and store c…
JonasBa Jun 12, 2024
2cb1ecf
ref(node) remove all but cache set snipline occurences
JonasBa Jun 12, 2024
34ece2d
fix(contextlines) update type assertions
JonasBa Jun 17, 2024
1ee5b96
fix(contextlines) use runtime checks instead
JonasBa Jun 17, 2024
23a115e
ref(node) fix types in tests
JonasBa Jun 17, 2024
7420b8b
test(node) fix wrong type assertion
JonasBa Jun 17, 2024
a8c6a91
ref(node) add limits to contextlines
JonasBa Jun 17, 2024
d89e244
test(node) add lineno and colno limits
JonasBa Jun 17, 2024
e82c510
fix typo
JonasBa Jun 17, 2024
79626c7
format
JonasBa Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion packages/node/src/integrations/contextlines.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ const LRU_FILE_CONTENTS_CACHE = new LRUMap<string, Record<number, string>>(10);
const LRU_FILE_CONTENTS_FS_READ_FAILED = new LRUMap<string, 1>(20);
const DEFAULT_LINES_OF_CONTEXT = 7;
const INTEGRATION_NAME = 'ContextLines';
// Determines the upper bound of lineno/colno that we will attempt to read. Large colno values are likely to be
// minified code while large lineno values are likely to be bundled code.
// Exported for testing purposes.
export const MAX_CONTEXTLINES_COLNO: number = 1000;
export const MAX_CONTEXTLINES_LINENO: number = 10000;

interface ContextLinesOptions {
/**
Expand Down Expand Up @@ -58,6 +63,15 @@ function shouldSkipContextLinesForFile(path: string): boolean {
if (path.startsWith('data:')) return true;
return false;
}

/**
* Determines if we should skip contextlines based off the max lineno and colno values.
*/
function shouldSkipContextLinesForFrame(frame: StackFrame): boolean {
if (frame.lineno !== undefined && frame.lineno > MAX_CONTEXTLINES_LINENO) return true;
if (frame.colno !== undefined && frame.colno > MAX_CONTEXTLINES_COLNO) return true;
return false;
}
/**
* Checks if we have all the contents that we need in the cache.
*/
Expand Down Expand Up @@ -216,7 +230,8 @@ async function addSourceContext(event: Event, contextLines: number): Promise<Eve
!frame ||
typeof filename !== 'string' ||
typeof frame.lineno !== 'number' ||
shouldSkipContextLinesForFile(filename)
shouldSkipContextLinesForFile(filename) ||
shouldSkipContextLinesForFrame(frame)
) {
continue;
}
Expand Down
41 changes: 40 additions & 1 deletion packages/node/test/integrations/contextlines.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import * as fs from 'node:fs';
import type { StackFrame } from '@sentry/types';
import { parseStackFrames } from '@sentry/utils';

import { _contextLinesIntegration, resetFileContentCache } from '../../src/integrations/contextlines';
import {
MAX_CONTEXTLINES_COLNO,
MAX_CONTEXTLINES_LINENO,
_contextLinesIntegration,
resetFileContentCache,
} from '../../src/integrations/contextlines';
import { defaultStackParser } from '../../src/sdk/api';
import { getError } from '../helpers/error';

Expand All @@ -22,6 +27,40 @@ describe('ContextLines', () => {
jest.clearAllMocks();
});

describe('limits', () => {
test(`colno above ${MAX_CONTEXTLINES_COLNO}`, async () => {
expect.assertions(1);
const frames: StackFrame[] = [
{
colno: MAX_CONTEXTLINES_COLNO + 1,
filename: 'file:///var/task/index.js',
lineno: 1,
function: 'fxn1',
},
];

const readStreamSpy = jest.spyOn(fs, 'createReadStream');
await addContext(frames);
expect(readStreamSpy).not.toHaveBeenCalled();
});

test(`lineno above ${MAX_CONTEXTLINES_LINENO}`, async () => {
expect.assertions(1);
const frames: StackFrame[] = [
{
colno: 1,
filename: 'file:///var/task/index.js',
lineno: MAX_CONTEXTLINES_LINENO + 1,
function: 'fxn1',
},
];

const readStreamSpy = jest.spyOn(fs, 'createReadStream');
await addContext(frames);
expect(readStreamSpy).not.toHaveBeenCalled();
});
});

describe('lru file cache', () => {
test('parseStack when file does not exist', async () => {
expect.assertions(4);
Expand Down
Loading