Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 62 additions & 6 deletions lib/tools/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,59 @@ Config.validateJSON = function(json){
return {errors: this._errors, config: res};
};

/**
* Safe string parsing function to replace vulnerable regex
* @param {String} str - String to parse
* @returns {Array} - Parsed tokens
* @private
*/
Config._parseStringToArray = function(str) {
var result = [];
var current = '';
var inQuotes = false;
var quoteChar = '';
var i = 0;

// Add length check to prevent excessive processing
if (str.length > 10000) {
throw new Error('String too long for parsing');
}

while (i < str.length) {
var char = str[i];

if (!inQuotes) {
if (char === '"' || char === "'") {
inQuotes = true;
quoteChar = char;
current += char;
} else if (/\s/.test(char)) {
if (current.trim()) {
result.push(current.trim());
current = '';
}
} else {
current += char;
}
} else {
current += char;
if (char === quoteChar && str[i - 1] !== '\\') {
inQuotes = false;
quoteChar = '';
}
}
i++;
}

if (current.trim()) {
result.push(current.trim());
}

return result.filter(function(v) {
return v && v.length > 0;
});
};

/**
* Validate key-value pairs by specific schema
* @param {String} key
Expand Down Expand Up @@ -198,13 +251,16 @@ Config._valid = function(key, value, sch){
}

// If first type is Array, but current is String, try to split them.
// FIXED: Replace vulnerable regex with safe parsing function
if(scht.length > 1 && type != scht[0] && type == '[object String]'){
if(scht[0] == '[object Array]') {
// unfortunately, js does not support lookahead RegExp (/(?<!\\)\s+/) now (until next ver).
value = value.split(/([\w\-]+\="[^"]*")|([\w\-]+\='[^']*')|"([^"]*)"|'([^']*)'|\s/)
.filter(function(v){
return v && v.trim();
});
try {
value = this._parseStringToArray(value);
} catch (e) {
// If parsing fails, treat as validation error
this._error(true, 'type', key, scht.join(' / '), 'Invalid string format');
return null;
}
}
}

Expand Down Expand Up @@ -244,4 +300,4 @@ Config._error = function(possible, type){
this._errors && this._errors.push(util.format.apply(null, args));
}
return possible;
}
}