stacktracejs / error-stack-parser

Extract meaning from JS Errors
https://www.stacktracejs.com/#!/docs/error-stack-parser
MIT License
450 stars 52 forks source link

Runaway regular expressions in stack trace parser #57

Open MartijnHols opened 3 years ago

MartijnHols commented 3 years ago

This line: https://github.com/stacktracejs/error-stack-parser/blob/a3bf972e399fd39222d97f4dc241a74cc483b4db/error-stack-parser.js#L103 freezes given the following input:

"    error("Warning: Received `%s` for a non-boolean attribute `%s`.\n\nIf you want to write it to the DOM, pass a string instead: %s=\"%s\" or %s={value.toString()}.\n\nIf you used to conditionally omit it with %s={condition && value}, pass %s={condition ? value : undefined} instead.%s", "false", "loading", "loading", "false", "loading", "loading", "loading", "\n    in button (created by Context.Consumer)\n    in StyledButton (at overrideOptional.tsx:16)\n    in Overridable(StyledButton) (at Button.tsx:108)\n    in Button (created by Context.Consumer)\n    in StyledButton (at Button.tsx:51)\n    in ButtonWithArrow (at overrideOptional.tsx:16)\n    in Overridden(Button) (created by Context.Consumer)\n    in ButtonPrimary (at overrideOptional.tsx:16)\n    in Overridden(Styled(Overridable(Button))) (at Submit.tsx:7)\n    in Submit (at AddToCartForm.tsx:98)\n    in form (created by Form)\n    in FormProvider (created by Form)\n    in Form (at AddToCartForm.tsx:97)\n    in AddToCartForm (at ProductAddToCartForm.tsx:68)\n    in ProductAddToCartForm (at ProductPageInfoSide.tsx:244)\n    in div (created by Context.Consumer)\n    in Card (at ProductPageInfoSide.tsx:153)\n    in div (created by Context.Consumer)\n    in ProductInfo (at ProductPageInfoSide.tsx:152)\n    in ProductPageInfoSide (at ProductPage.tsx:194)\n    in div (created by Context.Consumer)\n    in ProductTop (at ProductPage.tsx:173)\n    in div (created by Context.Consumer)\n    in Wrapper (at Container.tsx:114)\n    in ForwardRef(_c) (at ProductPage.tsx:166)\n    in article (at ProductPage.tsx:165)\n    in main (created by Context.Consumer)\n    in Content (at PageWrapper.tsx:74)\n    in div (created by Context.Consumer)\n    in Page (at PageWrapper.tsx:65)\n    in PortalTarget (at PageWrapper.tsx:64)\n    in PageWrapper (at ProductPage.tsx:156)\n    in ProductPage (at overrideOptional.tsx:16)\n    in Overridable(ProductPage) (at DynamicRouteResolver.tsx:54)\n    in DynamicRouteResolver (created by Context.Consumer)\n    in Route (at AppRouter.tsx:25)\n    in Switch (at AppRouter.tsx:14)\n    in AppRouter (at App.tsx:32)\n    in BreakpointsProvider (at AppProviders.tsx:38)\n    in ApolloProvider (at ApolloConnector.tsx:68)\n    in ApolloConnector (at AppProviders.tsx:30)\n    in Router (at RouterProvider.tsx:18)\n    in RouterProvider (at AppProviders.tsx:29)\n    in StoreViewProvider (at AppProviders.tsx:25)\n    in ErrorBoundary (at RootErrorBoundary.tsx:105)\n    in RootErrorBoundary (at AppProviders.tsx:24)\n    in I18nProvider (at I18nLoader.tsx:19)\n    in I18nLoader (at AppProviders.tsx:23)\n    in AppProviders (at App.tsx:28)\n    in App (at src/index.tsx:30)") at console.error (http://localhost:3340/__cypress/runner/cypress_runner.js:140661:26)"

Expected Behavior

It should not freeze the browser.

Current Behavior

The regex takes a very long time to parse the string

Steps to Reproduce (for bugs)

Paste in the browser console:

"    error("Warning: Received `%s` for a non-boolean attribute `%s`.\n\nIf you want to write it to the DOM, pass a string instead: %s=\"%s\" or %s={value.toString()}.\n\nIf you used to conditionally omit it with %s={condition && value}, pass %s={condition ? value : undefined} instead.%s", "false", "loading", "loading", "false", "loading", "loading", "loading", "\n    in button (created by Context.Consumer)\n    in StyledButton (at overrideOptional.tsx:16)\n    in Overridable(StyledButton) (at Button.tsx:108)\n    in Button (created by Context.Consumer)\n    in StyledButton (at Button.tsx:51)\n    in ButtonWithArrow (at overrideOptional.tsx:16)\n    in Overridden(Button) (created by Context.Consumer)\n    in ButtonPrimary (at overrideOptional.tsx:16)\n    in Overridden(Styled(Overridable(Button))) (at Submit.tsx:7)\n    in Submit (at AddToCartForm.tsx:98)\n    in form (created by Form)\n    in FormProvider (created by Form)\n    in Form (at AddToCartForm.tsx:97)\n    in AddToCartForm (at ProductAddToCartForm.tsx:68)\n    in ProductAddToCartForm (at ProductPageInfoSide.tsx:244)\n    in div (created by Context.Consumer)\n    in Card (at ProductPageInfoSide.tsx:153)\n    in div (created by Context.Consumer)\n    in ProductInfo (at ProductPageInfoSide.tsx:152)\n    in ProductPageInfoSide (at ProductPage.tsx:194)\n    in div (created by Context.Consumer)\n    in ProductTop (at ProductPage.tsx:173)\n    in div (created by Context.Consumer)\n    in Wrapper (at Container.tsx:114)\n    in ForwardRef(_c) (at ProductPage.tsx:166)\n    in article (at ProductPage.tsx:165)\n    in main (created by Context.Consumer)\n    in Content (at PageWrapper.tsx:74)\n    in div (created by Context.Consumer)\n    in Page (at PageWrapper.tsx:65)\n    in PortalTarget (at PageWrapper.tsx:64)\n    in PageWrapper (at ProductPage.tsx:156)\n    in ProductPage (at overrideOptional.tsx:16)\n    in Overridable(ProductPage) (at DynamicRouteResolver.tsx:54)\n    in DynamicRouteResolver (created by Context.Consumer)\n    in Route (at AppRouter.tsx:25)\n    in Switch (at AppRouter.tsx:14)\n    in AppRouter (at App.tsx:32)\n    in BreakpointsProvider (at AppProviders.tsx:38)\n    in ApolloProvider (at ApolloConnector.tsx:68)\n    in ApolloConnector (at AppProviders.tsx:30)\n    in Router (at RouterProvider.tsx:18)\n    in RouterProvider (at AppProviders.tsx:29)\n    in StoreViewProvider (at AppProviders.tsx:25)\n    in ErrorBoundary (at RootErrorBoundary.tsx:105)\n    in RootErrorBoundary (at AppProviders.tsx:24)\n    in I18nProvider (at I18nLoader.tsx:19)\n    in I18nLoader (at AppProviders.tsx:23)\n    in AppProviders (at App.tsx:28)\n    in App (at src/index.tsx:30)") at console.error (http://localhost:3340/__cypress/runner/cypress_runner.js:140661:26)".match(/((.*".+"[^@]*)?[^@]*)(?:@)/)

Context

I am running Cypress tests against a React app. React dumps the component stack in the stack trace when it throws an error or warning for a component.

Your Environment

Possible Solution

A different RegEx, or no RegEx at all.