From e539e7d0bed4fef42f458f28d06100ae23f52cb7 Mon Sep 17 00:00:00 2001 From: Martin Sherburn Date: Mon, 14 Jun 2021 02:55:55 -0700 Subject: [PATCH] Fix bug in parseHermesStack.js Summary: If function name is an empty string then it would fail to parse the line. And not only that, it would cause the entire stack to be lost. This fixes the issue by replacing `.+?` with `.*?`. For example this line fails to parse: ``` at global (:2:4) ``` Changelog: [General][Fixed] - Fixed bug parsing hermes call stacks when the file name is empty Reviewed By: yungsters Differential Revision: D29063192 fbshipit-source-id: 604e457af51f852fe547e6424283631ae148897d --- .../parseHermesStack-test.js.snap | 28 +++++++++++++++++++ .../__tests__/parseHermesStack-test.js | 12 ++++++++ Libraries/Core/Devtools/parseHermesStack.js | 2 +- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Libraries/Core/Devtools/__tests__/__snapshots__/parseHermesStack-test.js.snap b/Libraries/Core/Devtools/__tests__/__snapshots__/parseHermesStack-test.js.snap index c3ff6f79a652a5..99798d8b6132b4 100644 --- a/Libraries/Core/Devtools/__tests__/__snapshots__/parseHermesStack-test.js.snap +++ b/Libraries/Core/Devtools/__tests__/__snapshots__/parseHermesStack-test.js.snap @@ -107,3 +107,31 @@ Object { "message": "TypeError: undefined is not a function", } `; + +exports[`parseHermesStack tolerate empty filename 1`] = ` +Object { + "entries": Array [ + Object { + "functionName": "global", + "location": Object { + "column1Based": 9, + "line1Based": 1, + "sourceUrl": "unknown", + "type": "SOURCE", + }, + "type": "FRAME", + }, + Object { + "functionName": "foo$bar", + "location": Object { + "column1Based": 1234, + "line1Based": 10, + "sourceUrl": "", + "type": "SOURCE", + }, + "type": "FRAME", + }, + ], + "message": "TypeError: undefined is not a function", +} +`; diff --git a/Libraries/Core/Devtools/__tests__/parseHermesStack-test.js b/Libraries/Core/Devtools/__tests__/parseHermesStack-test.js index 3a299df8f47785..8b24b97294659a 100644 --- a/Libraries/Core/Devtools/__tests__/parseHermesStack-test.js +++ b/Libraries/Core/Devtools/__tests__/parseHermesStack-test.js @@ -38,6 +38,18 @@ describe('parseHermesStack', () => { ).toMatchSnapshot(); }); + test('tolerate empty filename', () => { + expect( + parseHermesStack( + [ + 'TypeError: undefined is not a function', + ' at global (unknown:1:9)', + ' at foo$bar (:10:1234)', + ].join('\n'), + ), + ).toMatchSnapshot(); + }); + test('skipped frames', () => { expect( parseHermesStack( diff --git a/Libraries/Core/Devtools/parseHermesStack.js b/Libraries/Core/Devtools/parseHermesStack.js index 9d3ba2f9284f2f..70d47a0991d538 100644 --- a/Libraries/Core/Devtools/parseHermesStack.js +++ b/Libraries/Core/Devtools/parseHermesStack.js @@ -58,7 +58,7 @@ export type HermesParsedStack = {| // 4. source URL (filename) // 5. line number (1 based) // 6. column number (1 based) or virtual offset (0 based) -const RE_FRAME = /^ {4}at (.+?)(?: \((native)\)?| \((address at )?(.+?):(\d+):(\d+)\))$/; +const RE_FRAME = /^ {4}at (.+?)(?: \((native)\)?| \((address at )?(.*?):(\d+):(\d+)\))$/; // Capturing groups: // 1. count of skipped frames