mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-09-22 05:40:48 +02:00
Reimplement helpers.isBlankLine to fix an instance of "Polynomial regular expression used on uncontrolled data".
This commit is contained in:
parent
b9474e84a3
commit
1c89dd5776
3 changed files with 76 additions and 27 deletions
|
@ -78,20 +78,44 @@ module.exports.isEmptyString = function isEmptyString(str) {
|
||||||
module.exports.isObject = function isObject(obj) {
|
module.exports.isObject = function isObject(obj) {
|
||||||
return (obj !== null) && (typeof obj === "object") && !Array.isArray(obj);
|
return (obj !== null) && (typeof obj === "object") && !Array.isArray(obj);
|
||||||
};
|
};
|
||||||
// Returns true iff the input line is blank (no content)
|
/**
|
||||||
// Example: Contains nothing, whitespace, or comment (unclosed start/end okay)
|
* Returns true iff the input line is blank (contains nothing, whitespace, or
|
||||||
module.exports.isBlankLine = function isBlankLine(line) {
|
* comments (unclosed start/end comments allowed)).
|
||||||
// Call to String.replace follows best practices and is not a security check
|
*
|
||||||
// False-positive for js/incomplete-multi-character-sanitization
|
* @param {string} line Input line.
|
||||||
|
* @returns {boolean} True iff line is blank.
|
||||||
|
*/
|
||||||
|
function isBlankLine(line) {
|
||||||
|
var startComment = "<!--";
|
||||||
|
var endComment = "-->";
|
||||||
|
var removeComments = function (s) {
|
||||||
|
// eslint-disable-next-line no-constant-condition
|
||||||
|
while (true) {
|
||||||
|
var start = s.indexOf(startComment);
|
||||||
|
var end = s.indexOf(endComment);
|
||||||
|
if ((end !== -1) && ((start === -1) || (end < start))) {
|
||||||
|
// Unmatched end comment is first
|
||||||
|
s = s.slice(end + endComment.length);
|
||||||
|
}
|
||||||
|
else if ((start !== -1) && (end !== -1)) {
|
||||||
|
// Start comment is before end comment
|
||||||
|
s = s.slice(0, start) + s.slice(end + endComment.length);
|
||||||
|
}
|
||||||
|
else if ((start !== -1) && (end === -1)) {
|
||||||
|
// Unmatched start comment is last
|
||||||
|
s = s.slice(0, start);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// No more comments to remove
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
return (!line ||
|
return (!line ||
|
||||||
!line.trim() ||
|
!line.trim() ||
|
||||||
!line
|
!removeComments(line).replace(/>/g, "").trim());
|
||||||
.replace(/<!--.*?-->/g, "")
|
}
|
||||||
.replace(/<!--.*$/g, "")
|
module.exports.isBlankLine = isBlankLine;
|
||||||
.replace(/^.*-->/g, "")
|
|
||||||
.replace(/>/g, "")
|
|
||||||
.trim());
|
|
||||||
};
|
|
||||||
/**
|
/**
|
||||||
* Compare function for Array.prototype.sort for ascending order of numbers.
|
* Compare function for Array.prototype.sort for ascending order of numbers.
|
||||||
*
|
*
|
||||||
|
|
|
@ -65,22 +65,43 @@ module.exports.isObject = function isObject(obj) {
|
||||||
return (obj !== null) && (typeof obj === "object") && !Array.isArray(obj);
|
return (obj !== null) && (typeof obj === "object") && !Array.isArray(obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Returns true iff the input line is blank (no content)
|
/**
|
||||||
// Example: Contains nothing, whitespace, or comment (unclosed start/end okay)
|
* Returns true iff the input line is blank (contains nothing, whitespace, or
|
||||||
module.exports.isBlankLine = function isBlankLine(line) {
|
* comments (unclosed start/end comments allowed)).
|
||||||
// Call to String.replace follows best practices and is not a security check
|
*
|
||||||
// False-positive for js/incomplete-multi-character-sanitization
|
* @param {string} line Input line.
|
||||||
|
* @returns {boolean} True iff line is blank.
|
||||||
|
*/
|
||||||
|
function isBlankLine(line) {
|
||||||
|
const startComment = "<!--";
|
||||||
|
const endComment = "-->";
|
||||||
|
const removeComments = (s) => {
|
||||||
|
// eslint-disable-next-line no-constant-condition
|
||||||
|
while (true) {
|
||||||
|
const start = s.indexOf(startComment);
|
||||||
|
const end = s.indexOf(endComment);
|
||||||
|
if ((end !== -1) && ((start === -1) || (end < start))) {
|
||||||
|
// Unmatched end comment is first
|
||||||
|
s = s.slice(end + endComment.length);
|
||||||
|
} else if ((start !== -1) && (end !== -1)) {
|
||||||
|
// Start comment is before end comment
|
||||||
|
s = s.slice(0, start) + s.slice(end + endComment.length);
|
||||||
|
} else if ((start !== -1) && (end === -1)) {
|
||||||
|
// Unmatched start comment is last
|
||||||
|
s = s.slice(0, start);
|
||||||
|
} else {
|
||||||
|
// No more comments to remove
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
return (
|
return (
|
||||||
!line ||
|
!line ||
|
||||||
!line.trim() ||
|
!line.trim() ||
|
||||||
!line
|
!removeComments(line).replace(/>/g, "").trim()
|
||||||
.replace(/<!--.*?-->/g, "")
|
|
||||||
.replace(/<!--.*$/g, "")
|
|
||||||
.replace(/^.*-->/g, "")
|
|
||||||
.replace(/>/g, "")
|
|
||||||
.trim()
|
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
module.exports.isBlankLine = isBlankLine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare function for Array.prototype.sort for ascending order of numbers.
|
* Compare function for Array.prototype.sort for ascending order of numbers.
|
||||||
|
|
|
@ -226,7 +226,7 @@ bar`
|
||||||
});
|
});
|
||||||
|
|
||||||
test("isBlankLine", (t) => {
|
test("isBlankLine", (t) => {
|
||||||
t.plan(29);
|
t.plan(33);
|
||||||
const blankLines = [
|
const blankLines = [
|
||||||
null,
|
null,
|
||||||
"",
|
"",
|
||||||
|
@ -248,7 +248,9 @@ test("isBlankLine", (t) => {
|
||||||
"<!--",
|
"<!--",
|
||||||
" <!-- text",
|
" <!-- text",
|
||||||
"text --> ",
|
"text --> ",
|
||||||
"-->"
|
"-->",
|
||||||
|
"text --> <!--text--> <!--text--> <!-- text",
|
||||||
|
"text --> --> <!--text--> <!--text--> <!-- <!-- text"
|
||||||
];
|
];
|
||||||
blankLines.forEach((line) => t.true(helpers.isBlankLine(line), line || ""));
|
blankLines.forEach((line) => t.true(helpers.isBlankLine(line), line || ""));
|
||||||
const nonBlankLines = [
|
const nonBlankLines = [
|
||||||
|
@ -259,7 +261,9 @@ test("isBlankLine", (t) => {
|
||||||
"<!--text--> text",
|
"<!--text--> text",
|
||||||
"text <!--text-->",
|
"text <!--text-->",
|
||||||
"text <!--",
|
"text <!--",
|
||||||
"--> text"
|
"--> text",
|
||||||
|
"text --> <!--text--> text <!--text--> <!-- text",
|
||||||
|
"text --> --> <!--text--> text <!--text--> <!-- <!-- text"
|
||||||
];
|
];
|
||||||
nonBlankLines.forEach((line) => t.true(!helpers.isBlankLine(line), line));
|
nonBlankLines.forEach((line) => t.true(!helpers.isBlankLine(line), line));
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue