    function checkDependencies(dependencies) {
        if (!dependencies) return '';
        // like [{"js-controller": ">=0.10.1"}]
        let adapters;
        if (dependencies instanceof Array) {
            adapters = {};
            for (let a = 0; a < dependencies.length; a++) {
                if (typeof dependencies[a] === 'string') continue;
                for (const b in dependencies[a]) {
                    if (dependencies[a].hasOwnProperty(b)) {
                        adapters[b] = dependencies[a][b];
                    }
                }
            }
        } else {
            adapters = dependencies;
        }

        for (const adapter in adapters) {
            if (adapters.hasOwnProperty(adapter)) {
                if (adapter === 'js-controller') {
                    if (!semver.satisfies(that.main.objects['system.host.' + that.main.currentHost].common.installedVersion, adapters[adapter])) return _('Invalid version of %s. Required %s', adapter, adapters[adapter]);
                } else {
                    if (!that.main.objects['system.adapter.' + adapter] || !that.main.objects['system.adapter.' + adapter].common || !that.main.objects['system.adapter.' + adapter].common.installedVersion) return _('No version of %s', adapter);
                    if (!semver.satisfies(that.main.objects['system.adapter.' + adapter].common.installedVersion, adapters[adapter])) return _('Invalid version of %s', adapter);
                }
            }
        }
        return '';
    }
The software uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.