VYPR
High severityNVD Advisory· Published Jun 12, 2023· Updated Jan 6, 2025

CVE-2023-26133

CVE-2023-26133

Description

All versions of progressbar.js are vulnerable to Prototype Pollution via the extend() function in utils.js, allowing potential denial of service or remote code execution.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

All versions of progressbar.js are vulnerable to Prototype Pollution via the extend() function in utils.js, allowing potential denial of service or remote code execution.

Overview

CVE-2023-26133 describes a Prototype Pollution vulnerability in the progressbar.js package affecting all versions. The flaw resides in the extend() function within src/utils.js (line 18). The function performs an unsafe recursive merge of objects without properly filtering dangerous properties such as __proto__, constructor, or prototype, allowing an attacker to inject arbitrary properties into the global Object prototype [1][2][3].

Exploitation

Prototype Pollution occurs when the extend() function merges a source object into a target object. If the source object contains a property named __proto__, the recursive merge logic will traverse into the target's prototype chain, ultimately writing properties onto Object.prototype. An attacker can control the source object via user-supplied input, such as JSON payloads or URL parameters, depending on how the library is integrated. The attack requires no authentication and can be triggered remotely if the application processes attacker-controlled data through the vulnerable extend() call [2].

Impact

Successful exploitation can lead to a denial of service by throwing JavaScript exceptions when polluted properties interfere with regular object operations. More critically, by polluting base object properties, an attacker may alter the application's control flow, potentially leading to remote code execution (RCE) if the polluted properties affect security-sensitive code paths. The impact is application-specific but follows the typical Prototype Pollution pattern seen in libraries like lodash and Hoek [2].

Mitigation

No fixed version has been released as of the publication date. The project appears to be maintained sporadically. Developers using progressbar.js should sanitize user input before passing it to any function that internally calls extend(), or consider replacing the library with an alternative that does not perform unsafe recursive merges. The vulnerability is publicly documented and has a Snyk advisory [2].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
progressbar.jsnpm
< 1.1.11.1.1

Affected products

2

Patches

1
97fe68ef4bec

Use lodash.merge over custom extend

https://github.com/kimmobrunfeldt/progressbar.jsKimmo BrunfeldtOct 9, 2023via ghsa
12 files changed · +22527 5473
  • Gruntfile.js+0 16 modified
    @@ -1,7 +1,5 @@
    -var fs = require('fs');
     var _ = require('lodash');
     
    -
     // Split array to smaller arrays containing n elements at max
     function groupToElements(array, n) {
       var lists = _.groupBy(array, function(element, index){
    @@ -11,10 +9,6 @@ function groupToElements(array, n) {
       return _.toArray(lists);
     }
     
    -function endsWith(str, suffix) {
    -  return str.indexOf(suffix, str.length - suffix.length) !== -1;
    -}
    -
     // Setup karma configuration dynamically to run browsers sequentially
     // https://github.com/karma-runner/karma-sauce-launcher/issues/8
     var MAXIMUM_CONCURRENT_SAUCE = 3;
    @@ -82,13 +76,6 @@ module.exports = function(grunt) {
             // This will run tests in Sauce Lab
             command: './node_modules/karma/bin/karma start'
           },
    -      testem: {
    -        options: {
    -          stdout: true
    -        },
    -        // This will run tests in all local browsers available/detected
    -        command: 'testem ci -R dot -l chrome'
    -      }
         },
         // Uglify must be run after browserify
         uglify: {
    @@ -125,8 +112,6 @@ module.exports = function(grunt) {
         'uglify:progressbar'
       ]);
     
    -  grunt.registerTask('test', ['shell:testem']);
    -
       // Run multiple tests serially, but continue if one of them fails.
       // Adapted from http://stackoverflow.com/questions/16487681/gruntfile-getting-error-codes-from-programs-serially
       grunt.registerTask('sauce', function() {
    @@ -161,7 +146,6 @@ module.exports = function(grunt) {
         bump = bump || 'patch';
     
         grunt.task.run([
    -      'test',
           'build',
           'stageMinified',
           'shell:release:' + bump
    
  • package.json+1 2 modified
    @@ -4,13 +4,12 @@
       "description": "Responsive and slick progress bars with animated SVG paths",
       "main": "dist/progressbar.js",
       "dependencies": {
    +    "lodash.merge": "^4.6.2",
         "shifty": "^2.8.3"
       },
       "devDependencies": {
         "bluebird": "^2.3.6",
         "browserify": "^13.0.0",
    -    "chai": "^1.10.0",
    -    "chai-stats": "kimmobrunfeldt/chai-stats",
         "commander": "^2.4.0",
         "concurrently": "^2.0.0",
         "eslint": "^1.0.0",
    
  • package-lock.json+22523 4873 modified
  • README.md+0 7 modified
    @@ -21,13 +21,6 @@ Documentation is [hosted at readthedocs.org](http://progressbarjs.readthedocs.or
     * [Migration between versions](http://progressbarjs.readthedocs.org/en/latest/#migrations)
     * [react-progressbar.js](https://github.com/kimmobrunfeldt/react-progressbar.js) progress bars in React.
     
    -**Build status**
    -
    -[![Build Status](https://api.travis-ci.org/kimmobrunfeldt/progressbar.js.svg?branch=master)](https://travis-ci.org/kimmobrunfeldt/progressbar.js) *Build status and browser tests for current master*
    -
    -[![Sauce Test Status](https://app.saucelabs.com/browser-matrix/kimmobrunfeldt.svg)](https://app.saucelabs.com/u/kimmobrunfeldt)
    -
    -
     
     # Contributing
     
    
  • src/utils.js+3 23 modified
    @@ -1,30 +1,10 @@
     // Utility functions
     
    +var merge = require('lodash.merge');
    +
     var PREFIXES = 'Webkit Moz O ms'.split(' ');
     var FLOAT_COMPARISON_EPSILON = 0.001;
     
    -// Copy all attributes from source object to destination object.
    -// destination object is mutated.
    -function extend(destination, source, recursive) {
    -    destination = destination || {};
    -    source = source || {};
    -    recursive = recursive || false;
    -
    -    for (var attrName in source) {
    -        if (source.hasOwnProperty(attrName)) {
    -            var destVal = destination[attrName];
    -            var sourceVal = source[attrName];
    -            if (recursive && isObject(destVal) && isObject(sourceVal)) {
    -                destination[attrName] = extend(destVal, sourceVal, recursive);
    -            } else {
    -                destination[attrName] = sourceVal;
    -            }
    -        }
    -    }
    -
    -    return destination;
    -}
    -
     // Renders templates with given variables. Variables must be surrounded with
     // braces without any spaces, e.g. {variable}
     // All instances of variable placeholders will be replaced with given content
    @@ -123,7 +103,7 @@ function removeChildren(el) {
     }
     
     module.exports = {
    -    extend: extend,
    +    extend: merge,
         render: render,
         setStyle: setStyle,
         setStyles: setStyles,
    
  • testem.json+0 12 removed
    @@ -1,12 +0,0 @@
    -{
    -  "framework": "mocha",
    -  "src_files": [
    -    "test/test-*.js"
    -  ],
    -  "test_page": "test/testem.html",
    -  "routes": {
    -    "/node_modules": "node_modules"
    -  },
    -  "before_tests": "browserify --debug test/test-all.js -o test/browserified-tests.js",
    -  "on_exit": "rm test/browserified-tests.js"
    -}
    
  • test/path-behaviour.js+0 148 removed
    @@ -1,148 +0,0 @@
    -var chai = require('chai');
    -var chaiStats = require('chai-stats');
    -chai.use(chaiStats);
    -var expect = chai.expect;
    -
    -var PRECISION = 2;
    -var ANIM_PROP = {
    -    'styleName': 'stroke-offset',
    -    'scriptName': 'strokeOffset'
    -};
    -
    -var barOpts = {
    -    duration: 800,
    -    from: {strokeOffset: 0},
    -    to: { strokeOffset: 0 },
    -    step: function(state, self, attachment) {
    -        attachment.setAttribute(ANIM_PROP.scriptName, state[ANIM_PROP.scriptName]);
    -    }
    -};
    -
    -function createPath() {
    -    var container = document.querySelector('body'),
    -        svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'),
    -        path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
    -
    -    svg.setAttribute('version', '1.1');
    -    svg.setAttribute('id', 'progress-bar');
    -    svg.setAttribute('x', '0px');
    -    svg.setAttribute('y', '0px');
    -    svg.setAttribute('viewBox', '0 0 197 165.39555');
    -    svg.setAttribute('enable-background', '0 0 197 165.39555');
    -
    -    var attrs = {
    -        'id': 'progress-path',
    -        'fill': 'none',
    -        'stroke': '#ccc',
    -        'stroke-width':'15',
    -        'stroke-miterlimit': '10',
    -        'd': 'm 31.7,160.3 c -15,-16.2 -24.2,-38 -24.2,-61.8 0,-50.3' +
    -             ' 40.7,-91 91,-91 50.3,0 91,40.7 91,91 0,23.9 -9.2,45.6 -24.2,61.8'
    -    };
    -
    -    for (var i in attrs) {
    -        path.setAttribute(i, attrs[i]);
    -    }
    -
    -    svg.appendChild(path);
    -
    -    container.appendChild(svg);
    -
    -    return {
    -        path: path,
    -        svg: svg
    -    };
    -}
    -
    -function pathTests() {
    -
    -    it('step function should recieve a reference to ProgressBar as argument #2', function() {
    -        this.bar.animate(1, {duration: 500});
    -
    -        // we only care about the second arg, for each call so we need to manually
    -        // inspect them since we dont know what state would look like
    -        var ok = true;
    -
    -        for (var i = 0; i < this.step.args.length; i++) {
    -            if (this.step.args[i][1] !== this.bar) {
    -                ok = false;
    -            }
    -        }
    -
    -        expect(ok).to.be.true();
    -    });
    -
    -    it('step function should recieve a reference to ProgressBar as argument #3', function() {
    -        this.bar.animate(1, {duration: 500});
    -
    -        // we only care about the third arg, for each call so we need to manually
    -        // inspect them since we dont know what state would look like
    -        var ok = true;
    -
    -        for (var i = 0; i < this.step.args.length; i++) {
    -            if (this.step.args[i][2] !== this.attachment) {
    -                ok = false;
    -            }
    -        }
    -
    -        expect(ok).to.be.true();
    -    });
    -
    -    it('set should change value', function() {
    -        this.bar.set(1);
    -        expect(this.bar.value()).to.almost.equal(1, PRECISION);
    -    });
    -
    -    it('animate should change SVG path stroke-dashoffset property', function(done) {
    -        var progressAtStart = this.bar.value();
    -        this.bar.animate(1, {duration: 1000});
    -
    -        var self = this;
    -        setTimeout(function checkOffsetHasChanged() {
    -            expect(self.bar.value()).to.be.greaterThan(progressAtStart);
    -            expect(self.bar.value()).to.be.lessThan(1);
    -            done();
    -        }, 100);
    -    });
    -
    -    it('animate should change value', function(done) {
    -        this.bar.set(1);
    -        this.bar.animate(0, {duration: 600});
    -
    -        var self = this;
    -        setTimeout(function checkValueHasChanged() {
    -            expect(self.bar.value()).not.to.almost.equal(1, PRECISION);
    -        }, 300);
    -
    -        setTimeout(function checkAnimationHasCompleted() {
    -            expect(self.bar.value()).to.almost.equal(0, PRECISION);
    -            done();
    -        }, 1200);
    -    });
    -
    -    it('stop() should stop animation', function(done) {
    -        this.bar.animate(1, {duration: 1000});
    -
    -        var self = this;
    -        var progressAfterStop;
    -        setTimeout(function stopAnimation() {
    -            self.bar.stop();
    -            progressAfterStop = self.bar.value();
    -        }, 100);
    -
    -        setTimeout(function checkProgressAfterStop() {
    -            expect(progressAfterStop).to.almost.equal(self.bar.value(), PRECISION);
    -            done();
    -        }, 400);
    -    });
    -
    -    it('.path attribute should exist', function() {
    -        expect(this.bar.path).to.be.ok();
    -    });
    -}
    -
    -module.exports = {
    -    options: barOpts,
    -    runTests: pathTests,
    -    createPath: createPath
    -};
    
  • test/shape-behaviour.js+0 175 removed
    @@ -1,175 +0,0 @@
    -// Tests which test shared behaviour of all progress bar shapes
    -
    -var chai = require('chai');
    -var chaiStats = require('chai-stats');
    -chai.use(chaiStats);
    -var expect = chai.expect;
    -
    -var PRECISION = 2;
    -var TEXT_CLASS_NAME = '.progressbar-text';
    -
    -var sharedTests = function sharedTests() {
    -    // Test that public attributes exist
    -    it('.svg attribute should exist', function() {
    -        expect(this.bar.svg).to.be.ok();
    -    });
    -
    -    it('.path attribute should exist', function() {
    -        expect(this.bar.path).to.be.ok();
    -    });
    -
    -    it('.trail attribute should exist', function() {
    -        expect(this.bar.trail).to.be.ok();
    -    });
    -
    -    it('.text attribute should exist', function() {
    -        expect(this.bar.text).to.be.ok();
    -    });
    -
    -    it('bar should be empty after initialization', function() {
    -        expect(this.bar.value()).to.almost.equal(0, PRECISION);
    -    });
    -
    -    it('set should change value', function() {
    -        this.bar.set(1);
    -        expect(this.bar.value()).to.almost.equal(1, PRECISION);
    -    });
    -
    -    it('animate should change SVG path stroke-dashoffset property', function(done) {
    -        var progressAtStart = this.bar.value();
    -        this.bar.animate(1, {duration: 1000});
    -
    -        var self = this;
    -        setTimeout(function checkOffsetHasChanged() {
    -            expect(self.bar.value()).to.be.greaterThan(progressAtStart);
    -            expect(self.bar.value()).to.be.lessThan(1);
    -            done();
    -        }, 100);
    -    });
    -
    -    it('animate should change value', function(done) {
    -        this.bar.set(1);
    -        this.bar.animate(0, {duration: 600});
    -
    -        var self = this;
    -        setTimeout(function checkValueHasChanged() {
    -            expect(self.bar.value()).not.to.almost.equal(1, PRECISION);
    -        }, 300);
    -
    -        setTimeout(function checkAnimationHasCompleted() {
    -            expect(self.bar.value()).to.almost.equal(0, PRECISION);
    -            done();
    -        }, 1200);
    -    });
    -
    -    it('step function should recieve a reference to ProgressBar as argument #2', function() {
    -        this.bar.animate(1, {duration: 600});
    -        var allCallsHaveBar = true;
    -
    -        for (var i = 0; i < this.step.args.length; i++) {
    -            if (this.step.args[i][1] !== this.bar) {
    -                allCallsHaveBar = false;
    -            }
    -        }
    -
    -        expect(allCallsHaveBar).to.be.true();
    -    });
    -
    -    it('step function should recieve a reference to attachment as argument #3', function() {
    -        this.bar.animate(1, {duration: 600});
    -        var allCallsHaveAttachment = true;
    -
    -        for (var i = 0; i < this.step.args.length; i++) {
    -            if (this.step.args[i][2] !== this.attachment) {
    -                allCallsHaveAttachment = false;
    -            }
    -        }
    -
    -        expect(allCallsHaveAttachment).to.be.true();
    -    });
    -
    -    it('stop() should stop animation', function(done) {
    -        this.bar.animate(1, {duration: 1000});
    -
    -        var self = this;
    -        var progressAfterStop;
    -        setTimeout(function stopAnimation() {
    -            self.bar.stop();
    -            progressAfterStop = self.bar.value();
    -        }, 100);
    -
    -        setTimeout(function checkProgressAfterStop() {
    -            expect(progressAfterStop).to.almost.equal(self.bar.value(), PRECISION);
    -            done();
    -        }, 400);
    -    });
    -
    -    // We have to test these two functions together
    -    it('pause() & resume() should pause & resume animation', function(done) {
    -        this.bar.animate(1, {duration: 1000});
    -
    -        var self = this;
    -        var progressAfterPause;
    -
    -        setTimeout(function pauseAnimation() {
    -            self.bar.pause();
    -            progressAfterPause = self.bar.value();
    -        }, 100);
    -
    -        setTimeout(function checkProgressAfterPause() {
    -            expect(progressAfterPause).to.almost.equal(self.bar.value(), PRECISION);
    -        }, 400);
    -
    -        setTimeout(function resumeAnimation() {
    -            self.bar.resume();
    -            setTimeout(function checkProgressAfterResume() {
    -                // Make sure it did resume quickly (<60ms)
    -                expect(self.bar.value() > progressAfterPause + 0.14).to.be.true;
    -                done();
    -            }, 200);
    -        }, 600);
    -    });
    -
    -    it('destroy() should delete DOM elements', function() {
    -        var svg = document.querySelector('svg');
    -        expect(svg).not.to.equal(null);
    -
    -        var textElement = document.querySelector(TEXT_CLASS_NAME);
    -        expect(textElement).not.to.equal(null);
    -
    -        this.bar.destroy();
    -        svg = document.querySelector('svg');
    -        expect(svg).to.equal(null);
    -
    -        textElement = document.querySelector(TEXT_CLASS_NAME);
    -        expect(textElement).to.equal(null);
    -    });
    -
    -    it('destroy() should make object unusable', function() {
    -        this.bar.destroy();
    -
    -        var self = this;
    -        var methodsShouldThrow = ['destroy', 'value', 'set', 'animate', 'stop', 'setText'];
    -        methodsShouldThrow.forEach(function(methodName) {
    -            expect(function shouldThrow() {
    -                self[methodName]();
    -            }).to.throw(Error);
    -        });
    -
    -        expect(this.bar.svg).to.equal(null);
    -        expect(this.bar.path).to.equal(null);
    -        expect(this.bar.trail).to.equal(null);
    -        expect(this.bar.text).to.equal(null);
    -    });
    -
    -    it('setText() should change text element', function() {
    -        var textElement = document.querySelector(TEXT_CLASS_NAME);
    -        expect(textElement.textContent).to.equal('Test');
    -        this.bar.setText('new');
    -
    -        textElement = document.querySelector(TEXT_CLASS_NAME);
    -        expect(textElement.textContent).to.equal('new');
    -    });
    -};
    -
    -module.exports = sharedTests;
    
  • test/test-all.js+0 172 removed
    @@ -1,172 +0,0 @@
    -// These tests are run with two different test runners which work a bit
    -// differently. Runners are Testem and Karma. Read more about them in
    -// CONTRIBUTING.md
    -// Supporting both has lead to some compromises.
    -
    -var chai = require('chai');
    -var chaiStats = require('chai-stats');
    -chai.use(chaiStats);
    -var sinon = require('sinon');
    -var expect = chai.expect;
    -
    -// https://github.com/mochajs/mocha/wiki/Shared-Behaviours
    -var shapeTests = require('./shape-behaviour');
    -var pathTests = require('./path-behaviour');
    -var ProgressBar = require('../src/main');
    -var utils = require('../src/utils');
    -
    -var afterEachCase = function() {
    -    try {
    -        this.bar.destroy();
    -    } catch (e) {
    -        // Some test cases destroy the bar themselves and calling again
    -        // throws an error
    -    }
    -};
    -
    -var barOpts = {
    -    text: { value: 'Test' },
    -    trailWidth: 1,
    -    attachment: {foo: 'bar'}
    -};
    -
    -describe('Line', function() {
    -    beforeEach(function() {
    -        // Append progress bar to body since adding a custom HTML and div
    -        // with Karma was not that trivial compared to Testem
    -        barOpts.step = function(state, bar, attachment) {};
    -        this.bar = new ProgressBar.Line('body', barOpts);
    -        this.attachment = this.bar._opts.attachment;
    -        this.step = sinon.spy(this.bar._opts, 'step');
    -
    -    });
    -
    -    afterEach(afterEachCase);
    -    shapeTests();
    -});
    -
    -describe('Circle', function() {
    -    beforeEach(function() {
    -        barOpts.step = function(state, bar, attachment) {};
    -        this.bar = new ProgressBar.Circle('body', barOpts);
    -        this.attachment = this.bar._opts.attachment;
    -        this.step = sinon.spy(this.bar._opts, 'step');
    -
    -    });
    -
    -    afterEach(afterEachCase);
    -    shapeTests();
    -});
    -
    -describe('SemiCircle', function() {
    -    beforeEach(function() {
    -        barOpts.step = function(state, bar, attachment) {};
    -        this.bar = new ProgressBar.SemiCircle('body', barOpts);
    -        this.attachment = this.bar._opts.attachment;
    -        this.step = sinon.spy(this.bar._opts, 'step');
    -    });
    -
    -    afterEach(afterEachCase);
    -    shapeTests();
    -});
    -
    -describe('Square', function() {
    -    beforeEach(function() {
    -        barOpts.step = function(state, bar, attachment) {};
    -        this.bar = new ProgressBar.Square('body', barOpts);
    -        this.attachment = this.bar._opts.attachment;
    -        this.step = sinon.spy(this.bar._opts, 'step');
    -    });
    -
    -    afterEach(afterEachCase);
    -    shapeTests();
    -});
    -
    -describe('Path', function() {
    -
    -    beforeEach(function() {
    -        var svgView = pathTests.createPath();
    -        this.svg = svgView.svg;
    -        this.path = svgView.path;
    -        this.path.setAttribute('strokeOffset', this.path.getTotalLength());
    -        pathTests.options.attachment = this.path;
    -
    -        this.bar = new ProgressBar.Path(this.path, pathTests.options);
    -        this.attachment = this.bar._opts.attachment;
    -        this.step = sinon.spy(this.bar._opts, 'step');
    -    });
    -
    -    afterEach(function() {
    -        var container = this.svg.parentNode;
    -        container.removeChild(this.svg);
    -        this.svg = null;
    -        pathTests.options.attachment = null;
    -        this.path = null;
    -        this.bar = null;
    -    });
    -
    -    pathTests.runTests();
    -});
    -
    -describe('utils', function() {
    -    it('extend without recursive should not merge', function() {
    -        var first = {
    -            a: { content: 1 },
    -            b: 2,
    -            c: 3,
    -            d: [1, 2]
    -
    -        };
    -        var second = {
    -            a: { test: 1 },
    -            b: 4,
    -            d: [],
    -            e: 1
    -        };
    -        utils.extend(first, second);
    -
    -        // These should normally override a's attributes
    -        expect(first.a.content).to.equal(undefined);
    -        expect(first.b).to.equal(second.b);
    -        expect(first.d).to.equal(second.d);
    -        expect(first.e).to.equal(second.e);
    -
    -        // b.c is undefined so c should not be modified
    -        expect(first.c).to.equal(first.c);
    -    });
    -
    -    it('extend with recursive should merge', function() {
    -        var first = {
    -            a: {
    -                content: 1,
    -                b: {
    -                    content: 2
    -                }
    -            },
    -            arr: [1, 2]
    -        };
    -        var second = {
    -            a: {
    -                test: 1,
    -                b: {
    -                    test: 2
    -                }
    -            },
    -            arr: []
    -        };
    -        utils.extend(first, second, true);
    -
    -        // These should normally override a's attributes
    -        expect(first).to.deep.equal({
    -            a: {
    -                content: 1,
    -                test: 1,
    -                b: {
    -                    content: 2,
    -                    test: 2
    -                }
    -            },
    -            arr: []
    -        });
    -    });
    -});
    
  • test/testem.html+0 34 removed
    @@ -1,34 +0,0 @@
    -<!DOCTYPE html>
    -<html>
    -    <head>
    -        <meta charset="utf-8">
    -        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    -        <title>Test</title>
    -        <meta name="viewport" content="width=device-width, initial-scale=1">
    -
    -        <link rel="stylesheet" href="/node_modules/mocha/mocha.css" />
    -    </head>
    -    <body>
    -        <div id="mocha"></div>
    -
    -        <!-- Container where progress bars are appended-->
    -
    -        <div id="test-container">
    -            <h1>Test div</h1>
    -            <div id="container"></div>
    -        </div>
    -
    -        <script crossorigin="anonymous" src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
    -        <script src="/node_modules/mocha/mocha.js"></script>
    -        <script>mocha.setup('bdd')</script>
    -        <script src="/testem.js"></script>
    -
    -        <!-- Tests -->
    -        <script src="browserified-tests.js"></script>
    -
    -        <script>
    -            mocha.checkLeaks();
    -            mocha.run();
    -        </script>
    -    </body>
    -</html>
    
  • test/test-utils.js+0 8 removed
    @@ -1,8 +0,0 @@
    -function getComputedStyle(element, property) {
    -    var computedStyle = window.getComputedStyle(element, null);
    -    return computedStyle.getPropertyValue(property);
    -}
    -
    -module.exports = {
    -    getComputedStyle: getComputedStyle
    -};
    
  • tools/test.sh+0 3 modified
    @@ -8,7 +8,4 @@ EXIT_STATUS=0
     echo -e "\n---- Linting code..\n"
     npm run lint || EXIT_STATUS=$?
     
    -echo -e "\n---- Running tests..\n"
    -grunt test || EXIT_STATUS=$?
    -
     exit $EXIT_STATUS
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.