FortAwesome / Font-Awesome

The iconic SVG, font, and CSS toolkit
https://fontawesome.com
Other
73.63k stars 12.19k forks source link

Bug: Missing Array.isArray() validation #19625

Open uisam00 opened 1 year ago

uisam00 commented 1 year ago

Bug description

I'm trying to implement a React application for legacy browsers using the @fortawesome/fontawesome-svg-core and @fortawesome/react-fontawesome libraries. However, I came across the following error: 'Unhandled promise rejection TypeError: _hooks[hook].push is not a function'.

While debugging the issue, I traced it back to an attempt to use Array.push() without validating if the object is actually an array. This issue is causing my application to break when I try to run it in older browsers.

The problematic code block is as follows:

  if (plugin.hooks) {
    var hooks = plugin.hooks();
    Object.keys(hooks).forEach(function (hook) {
      if (!_hooks[hook]) {
        _hooks[hook] = [];
      }

      _hooks[hook].push(hooks[hook]);
    });
  }

The solution could be to add a validation:

if(Array.isArray(_hooks[hook])){
   _hooks[hook].push(hooks[hook]);
};

It is present in the following files:


js/all.js, line 4070:1
js-packages@fortawesome\fontawesome-free\js\fontawesome.js, line 1237:1
js-packages@fortawesome\fontawesome-free\js\all.js, line 4070:1
js-packages@fortawesome\fontawesome-free\js\fontawesome.js, line 1237:1
js-packages@fortawesome\fontawesome-svg-core\index.js, line 1237:1
js-packages@fortawesome\fontawesome-svg-core\index.mjs, line 1216:1
js-packages@fortawesome\fontawesome-svg-core\plugins.mjs, line 266:1

Example of error reproduction:

  1. Download Firefox 47.0.2;
  2. Clone the following repository: vite-react-legacy and open the project;
  3. Install the dependencies using the command yarn;
  4. Build the project using the command yarn build;
  5. Preview the project using the command yarn preview;
  6. Open the project in Firefox 47 and you will see the error in the console;
  7. Go back to the project and open the file dist\assets\fontawesome-svg-core-legacy-{some random identifier}.js;
  8. Add Array validation on line 998:1:
    if(Array.isArray(_hooks[hook])){
    _hooks[hook].push(hooks[hook]);
    };
  9. Run the command yarn preview again and see the project working.

Reproducible test case

https://github.com/uisam00/vite-react-legacy

Screenshots

This is the error:

image

when i put the validation in the builded file


  if (plugin.hooks) {
    var hooks = plugin.hooks();
    Object.keys(hooks).forEach(function (hook) {
      if (!_hooks[hook]) {
        _hooks[hook] = [];
      }
      if(Array.isArray(_hooks[hook])){
        _hooks[hook].push(hooks[hook]);
      }
    });
  }

The error disappears:

image

Font Awesome version

6.3.0

Serving

Self-hosted

Implementation

SVG+JS

Browser and Operating System

Web bug report checklist

tagliala commented 1 year ago

Hi!

Thanks for being part of the Font Awesome Community and for this excellent bug report.

I should start by clarifying that Firefox 47 is not supported, as per https://fontawesome.com/v6/docs/web/dig-deeper/browser-support

However, if this is the only issue and that is the solution, I hope that this can be considered.

Question:

  1. if _hooks[hook] is not an array, what it is?
  2. If it is pre-initialized as an array, why that code is not executed?
danielrosendos commented 1 year ago
  1. in this logic if (!_hooks[hook]) 1.1. _hooks[hook] in firefox 47 return undefined. So this logic them we have ìf(!undefined), theoretically (!false) should enter, but in firefox 47 not enter in this logic. So when trying _hooks[hook].push(hooks[hook]) broken. Because in firefox 47 _hooks[hook] not is array, he is a function.

    By switching to Array.isArray(_hooks[hook]), it worked both in firefox 47 and in more modern browsers. Thus doing a functional validation for older browsers

uisam00 commented 1 year ago

Hello, sorry for the delay. here are the answers to the questions presented:

  1. in the irefox 47 and firefox 56 the _hooks[hook] is function when the error occurs.
  2. it's impossible to execute the push method on an function.

as @danielrosendos answered, changing from if (!_hooks[hook]) toif(!Array.isArray(_hooks[hook])) will solve this problem in legacy browsers and will continue to work in most current browsers

uisam00 commented 1 year ago

I accidentally closed the issue then reopened it

uisam00 commented 1 year ago

Here is a screenshot of the error that appears in the console when I try to access _hooks[hook].push, first i check _hooks[hook] with console.log( _hooks[hook]) and it returns function watch(). Note that the error occurs because this is trying to access .push() from a function object.

image