Socket
Socket
Sign inDemoInstall

metro-symbolicate

Package Overview
Dependencies
Maintainers
2
Versions
86
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

metro-symbolicate - npm Package Compare versions

Comparing version 0.54.0 to 0.54.1

src.real/__tests__/__fixtures__/testfile.node.stack

2

package.json
{
"name": "metro-symbolicate",
"version": "0.54.0",
"version": "0.54.1",
"description": "A tool to find the source location from JS bundles and stack traces.",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -60,2 +60,28 @@ /**

});
it('accepts metadata blob with null function map', () => {
const consumer = new SourceMetadataMapConsumer({
version: 3,
mappings: 'AAAA',
sources: ['foo'],
names: [],
x_facebook_sources: [[null]],
});
expect(consumer.functionNameFor({line: 1, column: 0, source: 'foo'})).toBe(
null,
);
});
it('accepts null metadata blob', () => {
const consumer = new SourceMetadataMapConsumer({
version: 3,
mappings: 'AAAA',
sources: ['foo'],
names: [],
x_facebook_sources: [null],
});
expect(consumer.functionNameFor({line: 1, column: 0, source: 'foo'})).toBe(
null,
);
});
});

@@ -65,2 +65,7 @@ /**

test('symbolicating a stack trace in Node format', async () =>
await expect(
execute([TESTFILE_MAP], read('testfile.node.stack')),
).resolves.toMatchSnapshot());
test('symbolicating a single entry', async () =>

@@ -71,2 +76,17 @@ await expect(execute([TESTFILE_MAP, '1', '161'])).resolves.toEqual(

test('symbolicating a single entry with 0-based line output', async () =>
await expect(
execute([TESTFILE_MAP, '1', '161', '--output-line-start', '0']),
).resolves.toEqual('thrower.js:17:null\n'));
test('symbolicating a single entry with 1-based column input', async () =>
await expect(
execute([TESTFILE_MAP, '1', '161', '--input-column-start', '1']),
).resolves.toEqual('thrower.js:18:Error\n'));
test('symbolicating a single entry with 0-based line input', async () =>
await expect(
execute([TESTFILE_MAP, '0', '161', '--input-line-start', '0']),
).resolves.toEqual('thrower.js:18:null\n'));
test('symbolicating a single entry with an out of range column', async () =>

@@ -100,2 +120,10 @@ await expect(execute([TESTFILE_MAP, '1', '1000000'])).resolves.toEqual(

test('symbolicating an attribution file with 1-based column output', async () =>
await expect(
execute(
[TESTFILE_MAP, '--attribution', '--output-column-start', '1'],
read('testfile.attribution.input'),
),
).resolves.toMatchSnapshot());
describe('symbolicating an attribution file specifying unmapped offsets', () => {

@@ -228,5 +256,20 @@ const attribute = async obj =>

expect(read('testfile.temp.cpuprofile')).toMatchSnapshot();
expect(JSON.parse(read('testfile.temp.cpuprofile'))).toMatchSnapshot();
});
test('symbolicating with a cpuprofile ignoring a function map', async () => {
fs.copyFileSync(
resolve('testfile.cpuprofile'),
resolve('testfile.temp.cpuprofile'),
);
await execute([
'--no-function-names',
resolve('testfile.cpuprofile.map'),
resolve('testfile.temp.cpuprofile'),
]);
expect(JSON.parse(read('testfile.temp.cpuprofile'))).toMatchSnapshot();
});
test('symbolicating a stack trace with a function map', async () =>

@@ -233,0 +276,0 @@ await expect(

@@ -61,3 +61,3 @@ /**

type SourceNameNormalizer = (string, BabelSourceMap) => string;
type MetadataMap = {[source: string]: FBSourceMetadata};
type MetadataMap = {[source: string]: ?FBSourceMetadata};
*/

@@ -163,3 +163,3 @@

if (Object.prototype.hasOwnProperty.call(metadataBySource, source)) {
const metadata = metadataBySource[source];
const metadata = metadataBySource[source] || [];
parsedFunctionMap = decodeFunctionMap(metadata[METADATA_FIELD_FUNCTIONS]);

@@ -166,0 +166,0 @@ }

@@ -31,12 +31,34 @@ #!/usr/bin/env node

function checkAndRemoveArg(arg) {
let value = false;
function checkAndRemoveArg(arg, valuesPerArg = 0) {
let values = null;
for (let idx = argv.indexOf(arg); idx !== -1; idx = argv.indexOf(arg)) {
argv.splice(idx, 1);
value = true;
values = (values || []);
values.push(argv.splice(idx, valuesPerArg));
}
return value;
return values;
}
function checkAndRemoveArgWithValue(arg) {
const values = checkAndRemoveArg(arg, 1);
return values ? values[0][0] : null;
}
const noFunctionNames = checkAndRemoveArg('--no-function-names');
const inputLineStart = Number.parseInt(
checkAndRemoveArgWithValue('--input-line-start') || '1',
10,
);
const inputColumnStart = Number.parseInt(
checkAndRemoveArgWithValue('--input-column-start') || '0',
10,
);
const outputLineStart = Number.parseInt(
checkAndRemoveArgWithValue('--output-line-start') || '1',
10,
);
const outputColumnStart = Number.parseInt(
checkAndRemoveArgWithValue('--output-column-start') || '0',
10,
);

@@ -47,17 +69,16 @@ if (argv.length < 1 || argv.length > 4) {

const usages = [
'Usage: ' + __filename + ' <source-map-file> [--no-function-names]',
' ' +
__filename +
' <source-map-file> <line> [column] [--no-function-names]',
' ' +
__filename +
' <source-map-file> <moduleId>.js <line> [column] [--no-function-names]',
' ' +
__filename +
' <source-map-file> <mapfile>.profmap [--no-function-names]',
' ' +
__filename +
' <source-map-file> --attribution [--no-function-names] < attribution.jsonl ' +
'Usage: ' + __filename + ' <source-map-file>',
' ' + __filename + ' <source-map-file> <line> [column]',
' ' + __filename + ' <source-map-file> <moduleId>.js <line> [column]',
' ' + __filename + ' <source-map-file> <mapfile>.profmap',
' ' + __filename +
' <source-map-file> --attribution < attribution.jsonl ' +
' > symbolicated.jsonl',
' ' + __filename + ' <source-map-file> <tracefile>.cpuprofile',
' Optional flags:',
' --no-function-names',
' --input-line-start <line> (default: 1)',
' --input-column-start <column> (default: 0)',
' --output-line-start <line> (default: 1)',
' --output-column-start <column> (default: 0)',
];

@@ -73,2 +94,6 @@ console.error(usages.join('\n'));

nameSource: noFunctionNames ? 'identifier_names' : 'function_names',
inputLineStart,
inputColumnStart,
outputLineStart,
outputColumnStart,
});

@@ -75,0 +100,0 @@

@@ -53,2 +53,34 @@ /**

function getOriginalPositionFor(lineNumber, columnNumber, moduleIds, context) {
const position = getOriginalPositionDetailsFor(
lineNumber,
columnNumber,
moduleIds,
context,
);
if (position.functionName) {
position.name = position.functionName;
}
delete position.functionName;
return position;
}
/*
* An internal helper function similar to getOriginalPositionFor. This one
* returns both `name` and `functionName` fields so callers can distinguish the
* source of the name.
*/
function getOriginalPositionDetailsFor(
lineNumber,
columnNumber,
moduleIds,
context,
) {
// Adjust arguments to source-map's input coordinates
lineNumber =
lineNumber != null ? lineNumber - context.inputLineStart + 1 : lineNumber;
columnNumber =
columnNumber != null
? columnNumber - context.inputColumnStart + 0
: columnNumber;
var moduleLineOffset = 0;

@@ -75,10 +107,18 @@ var metadata = context.segments[moduleIds.segmentId];

if (metadata.sourceFunctionsConsumer) {
const functionName = metadata.sourceFunctionsConsumer.functionNameFor(
original,
);
if (functionName) {
return {...original, name: functionName};
}
original.functionName =
metadata.sourceFunctionsConsumer.functionNameFor(original) || null;
} else {
original.functionName = null;
}
return original;
return {
...original,
line:
original.line != null
? original.line - 1 + context.outputLineStart
: original.line,
column:
original.column != null
? original.column - 0 + context.outputColumnStart
: original.column,
};
}

@@ -89,4 +129,28 @@

sourceMapContent,
options /*: {nameSource?: 'function_names' | 'identifier_names'} */ = {},
options /*: {
nameSource?: 'function_names' | 'identifier_names',
inputLineStart?: number,
inputColumnStart?: number,
outputLineStart?: number,
outputColumnStart?: number,
} */ = {},
) {
const context = {
inputLineStart: 1,
inputColumnStart: 0,
outputLineStart: 1,
outputColumnStart: 0,
};
if (options) {
for (const option of [
'inputLineStart',
'inputColumnStart',
'outputLineStart',
'outputColumnStart',
]) {
if (options[option] != null) {
context[option] = options[option];
}
}
}
const useFunctionNames =

@@ -99,2 +163,3 @@ !options ||

return {
...context,
segments: Object.entries(sourceMapJson.x_facebook_segments || {}).reduce(

@@ -136,3 +201,3 @@ (acc, [key, map]) => {

return stackTrace.replace(
/(?:([^@: \n]+)(@|:))?(?:(?:([^@: \n]+):)?(\d+):(\d+)|\[native code\])/g,
/(?:([^@: \n(]+)(@|:))?(?:(?:([^@: \n(]+):)?(\d+):(\d+)|\[native code\])/g,
function(match, func, delimiter, fileName, line, column) {

@@ -179,3 +244,3 @@ if (delimiter === ':' && func && !fileName) {

var original = getOriginalPositionFor(
1,
context.inputLineStart,
offset,

@@ -199,4 +264,4 @@ UNKNOWN_MODULE_IDS,

var loc = obj.location;
var line = loc.line || 1;
var column = loc.column || loc.virtualOffset;
var line = loc.line != null ? loc.line : context.inputLineStart;
var column = loc.column != null ? loc.column : loc.virtualOffset;
var file = loc.filename ? parseFileName(loc.filename) : UNKNOWN_MODULE_IDS;

@@ -250,3 +315,4 @@ var original = getOriginalPositionFor(line, column, file, context);

// Function entrypoint line/column; used for symbolicating function name.
// Function entrypoint line/column; used for symbolicating function name
// with legacy source maps (or when --no-function-names is set).
let funcLine;

@@ -261,5 +327,5 @@ let funcColumn;

// TODO: support multiple bundle/module.
line = 1;
line = context.inputLineStart;
column = funcVirtAddr + offsetInFunction;
funcLine = 1;
funcLine = context.inputLineStart;
funcColumn = funcVirtAddr;

@@ -282,3 +348,3 @@ } else if (entry.line != null && entry.column != null) {

// Symbolicate original file/line/column.
const addressOriginal = getOriginalPositionFor(
const addressOriginal = getOriginalPositionDetailsFor(
line,

@@ -290,19 +356,24 @@ column,

let frameName = entry.name;
// Symbolicate function name.
if (funcLine != null && funcColumn != null) {
const funcOriginal = getOriginalPositionFor(
funcLine,
funcColumn,
UNKNOWN_MODULE_IDS,
context,
);
if (funcOriginal.name != null) {
frameName = funcOriginal.name;
let frameName;
if (addressOriginal.functionName) {
frameName = addressOriginal.functionName;
} else {
frameName = entry.name;
// Symbolicate function name.
if (funcLine != null && funcColumn != null) {
const funcOriginal = getOriginalPositionFor(
funcLine,
funcColumn,
UNKNOWN_MODULE_IDS,
context,
);
if (funcOriginal.name != null) {
frameName = funcOriginal.name;
}
} else {
// No function line/column info.
console.warn(
'Warning: no function prolog line/column info; name may be wrong',
);
}
} else {
// No function line/column info.
console.warn(
'Warning: no function prolog line/column info; name may be wrong',
);
}

@@ -309,0 +380,0 @@

@@ -128,3 +128,3 @@ /**

type SourceNameNormalizer = (string, BabelSourceMap) => string;
type MetadataMap = {[source: string]: FBSourceMetadata};
type MetadataMap = {[source: string]: ?FBSourceMetadata};
*/

@@ -259,3 +259,3 @@

if (Object.prototype.hasOwnProperty.call(metadataBySource, source)) {
const metadata = metadataBySource[source];
const metadata = metadataBySource[source] || [];
parsedFunctionMap = decodeFunctionMap(metadata[METADATA_FIELD_FUNCTIONS]);

@@ -262,0 +262,0 @@ }

@@ -66,13 +66,37 @@ #!/usr/bin/env node

function checkAndRemoveArg(arg) {
let value = false;
let valuesPerArg =
arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
let values = null;
for (let idx = argv.indexOf(arg); idx !== -1; idx = argv.indexOf(arg)) {
argv.splice(idx, 1);
value = true;
values = values || [];
values.push(argv.splice(idx, valuesPerArg));
}
return value;
return values;
}
function checkAndRemoveArgWithValue(arg) {
const values = checkAndRemoveArg(arg, 1);
return values ? values[0][0] : null;
}
const noFunctionNames = checkAndRemoveArg("--no-function-names");
const inputLineStart = Number.parseInt(
checkAndRemoveArgWithValue("--input-line-start") || "1",
10
);
const inputColumnStart = Number.parseInt(
checkAndRemoveArgWithValue("--input-column-start") || "0",
10
);
const outputLineStart = Number.parseInt(
checkAndRemoveArgWithValue("--output-line-start") || "1",
10
);
const outputColumnStart = Number.parseInt(
checkAndRemoveArgWithValue("--output-column-start") || "0",
10
);

@@ -82,17 +106,17 @@ if (argv.length < 1 || argv.length > 4) {

const usages = [
"Usage: " + __filename + " <source-map-file> [--no-function-names]",
"Usage: " + __filename + " <source-map-file>",
" " + __filename + " <source-map-file> <line> [column]",
" " + __filename + " <source-map-file> <moduleId>.js <line> [column]",
" " + __filename + " <source-map-file> <mapfile>.profmap",
" " +
__filename +
" <source-map-file> <line> [column] [--no-function-names]",
" " +
__filename +
" <source-map-file> <moduleId>.js <line> [column] [--no-function-names]",
" " +
__filename +
" <source-map-file> <mapfile>.profmap [--no-function-names]",
" " +
__filename +
" <source-map-file> --attribution [--no-function-names] < attribution.jsonl " +
" <source-map-file> --attribution < attribution.jsonl " +
" > symbolicated.jsonl",
" " + __filename + " <source-map-file> <tracefile>.cpuprofile"
" " + __filename + " <source-map-file> <tracefile>.cpuprofile",
" Optional flags:",
" --no-function-names",
" --input-line-start <line> (default: 1)",
" --input-column-start <column> (default: 0)",
" --output-line-start <line> (default: 1)",
" --output-column-start <column> (default: 0)"
];

@@ -106,3 +130,7 @@ console.error(usages.join("\n"));

const context = Symbolication.createContext(SourceMapConsumer, content, {
nameSource: noFunctionNames ? "identifier_names" : "function_names"
nameSource: noFunctionNames ? "identifier_names" : "function_names",
inputLineStart,
inputColumnStart,
outputLineStart,
outputColumnStart
});

@@ -109,0 +137,0 @@

@@ -131,2 +131,35 @@ /**

function getOriginalPositionFor(lineNumber, columnNumber, moduleIds, context) {
const position = getOriginalPositionDetailsFor(
lineNumber,
columnNumber,
moduleIds,
context
);
if (position.functionName) {
position.name = position.functionName;
}
delete position.functionName;
return position;
}
/*
* An internal helper function similar to getOriginalPositionFor. This one
* returns both `name` and `functionName` fields so callers can distinguish the
* source of the name.
*/
function getOriginalPositionDetailsFor(
lineNumber,
columnNumber,
moduleIds,
context
) {
// Adjust arguments to source-map's input coordinates
lineNumber =
lineNumber != null ? lineNumber - context.inputLineStart + 1 : lineNumber;
columnNumber =
columnNumber != null
? columnNumber - context.inputColumnStart + 0
: columnNumber;
var moduleLineOffset = 0;

@@ -159,14 +192,18 @@ var metadata = context.segments[moduleIds.segmentId];

if (metadata.sourceFunctionsConsumer) {
const functionName = metadata.sourceFunctionsConsumer.functionNameFor(
original
);
if (functionName) {
return _objectSpread({}, original, {
name: functionName
});
}
original.functionName =
metadata.sourceFunctionsConsumer.functionNameFor(original) || null;
} else {
original.functionName = null;
}
return original;
return _objectSpread({}, original, {
line:
original.line != null
? original.line - 1 + context.outputLineStart
: original.line,
column:
original.column != null
? original.column - 0 + context.outputColumnStart
: original.column
});
}

@@ -176,4 +213,30 @@

let options =
/*: {nameSource?: 'function_names' | 'identifier_names'} */
/*: {
nameSource?: 'function_names' | 'identifier_names',
inputLineStart?: number,
inputColumnStart?: number,
outputLineStart?: number,
outputColumnStart?: number,
} */
arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
const context = {
inputLineStart: 1,
inputColumnStart: 0,
outputLineStart: 1,
outputColumnStart: 0
};
if (options) {
for (const option of [
"inputLineStart",
"inputColumnStart",
"outputLineStart",
"outputColumnStart"
]) {
if (options[option] != null) {
context[option] = options[option];
}
}
}
const useFunctionNames =

@@ -185,3 +248,3 @@ !options ||

var sourceMapJson = JSON.parse(sourceMapContent.replace(/^\)\]\}'/, ""));
return {
return _objectSpread({}, context, {
segments: Object.entries(sourceMapJson.x_facebook_segments || {}).reduce(

@@ -212,3 +275,3 @@ (acc, _ref) => {

)
};
});
} // parse stack trace with String.replace

@@ -227,3 +290,3 @@ // replace the matched part of stack trace to symbolicated result

return stackTrace.replace(
/(?:([^@: \n]+)(@|:))?(?:(?:([^@: \n]+):)?(\d+):(\d+)|\[native code\])/g,
/(?:([^@: \n(]+)(@|:))?(?:(?:([^@: \n(]+):)?(\d+):(\d+)|\[native code\])/g,
function(match, func, delimiter, fileName, line, column) {

@@ -269,3 +332,3 @@ if (delimiter === ":" && func && !fileName) {

var original = getOriginalPositionFor(
1,
context.inputLineStart,
offset,

@@ -288,4 +351,4 @@ UNKNOWN_MODULE_IDS,

var loc = obj.location;
var line = loc.line || 1;
var column = loc.column || loc.virtualOffset;
var line = loc.line != null ? loc.line : context.inputLineStart;
var column = loc.column != null ? loc.column : loc.virtualOffset;
var file = loc.filename ? parseFileName(loc.filename) : UNKNOWN_MODULE_IDS;

@@ -336,3 +399,4 @@ var original = getOriginalPositionFor(line, column, file, context);

let line;
let column; // Function entrypoint line/column; used for symbolicating function name.
let column; // Function entrypoint line/column; used for symbolicating function name
// with legacy source maps (or when --no-function-names is set).

@@ -348,5 +412,5 @@ let funcLine;

line = 1;
line = context.inputLineStart;
column = funcVirtAddr + offsetInFunction;
funcLine = 1;
funcLine = context.inputLineStart;
funcColumn = funcVirtAddr;

@@ -367,3 +431,3 @@ } else if (entry.line != null && entry.column != null) {

const addressOriginal = getOriginalPositionFor(
const addressOriginal = getOriginalPositionDetailsFor(
line,

@@ -374,20 +438,26 @@ column,

);
let frameName = entry.name; // Symbolicate function name.
let frameName;
if (funcLine != null && funcColumn != null) {
const funcOriginal = getOriginalPositionFor(
funcLine,
funcColumn,
UNKNOWN_MODULE_IDS,
context
);
if (addressOriginal.functionName) {
frameName = addressOriginal.functionName;
} else {
frameName = entry.name; // Symbolicate function name.
if (funcOriginal.name != null) {
frameName = funcOriginal.name;
if (funcLine != null && funcColumn != null) {
const funcOriginal = getOriginalPositionFor(
funcLine,
funcColumn,
UNKNOWN_MODULE_IDS,
context
);
if (funcOriginal.name != null) {
frameName = funcOriginal.name;
}
} else {
// No function line/column info.
console.warn(
"Warning: no function prolog line/column info; name may be wrong"
);
}
} else {
// No function line/column info.
console.warn(
"Warning: no function prolog line/column info; name may be wrong"
);
} // Output format is: funcName(file:line:column)

@@ -394,0 +464,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc