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) {
|
||||
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)
|
||||
module.exports.isBlankLine = function isBlankLine(line) {
|
||||
// Call to String.replace follows best practices and is not a security check
|
||||
// False-positive for js/incomplete-multi-character-sanitization
|
||||
/**
|
||||
* Returns true iff the input line is blank (contains nothing, whitespace, or
|
||||
* comments (unclosed start/end comments allowed)).
|
||||
*
|
||||
* @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 ||
|
||||
!line.trim() ||
|
||||
!line
|
||||
.replace(/<!--.*?-->/g, "")
|
||||
.replace(/<!--.*$/g, "")
|
||||
.replace(/^.*-->/g, "")
|
||||
.replace(/>/g, "")
|
||||
.trim());
|
||||
};
|
||||
!removeComments(line).replace(/>/g, "").trim());
|
||||
}
|
||||
module.exports.isBlankLine = isBlankLine;
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
||||
// Returns true iff the input line is blank (no content)
|
||||
// Example: Contains nothing, whitespace, or comment (unclosed start/end okay)
|
||||
module.exports.isBlankLine = function isBlankLine(line) {
|
||||
// Call to String.replace follows best practices and is not a security check
|
||||
// False-positive for js/incomplete-multi-character-sanitization
|
||||
/**
|
||||
* Returns true iff the input line is blank (contains nothing, whitespace, or
|
||||
* comments (unclosed start/end comments allowed)).
|
||||
*
|
||||
* @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 (
|
||||
!line ||
|
||||
!line.trim() ||
|
||||
!line
|
||||
.replace(/<!--.*?-->/g, "")
|
||||
.replace(/<!--.*$/g, "")
|
||||
.replace(/^.*-->/g, "")
|
||||
.replace(/>/g, "")
|
||||
.trim()
|
||||
!removeComments(line).replace(/>/g, "").trim()
|
||||
);
|
||||
};
|
||||
}
|
||||
module.exports.isBlankLine = isBlankLine;
|
||||
|
||||
/**
|
||||
* Compare function for Array.prototype.sort for ascending order of numbers.
|
||||
|
|
|
@ -226,7 +226,7 @@ bar`
|
|||
});
|
||||
|
||||
test("isBlankLine", (t) => {
|
||||
t.plan(29);
|
||||
t.plan(33);
|
||||
const blankLines = [
|
||||
null,
|
||||
"",
|
||||
|
@ -248,7 +248,9 @@ test("isBlankLine", (t) => {
|
|||
"<!--",
|
||||
" <!-- text",
|
||||
"text --> ",
|
||||
"-->"
|
||||
"-->",
|
||||
"text --> <!--text--> <!--text--> <!-- text",
|
||||
"text --> --> <!--text--> <!--text--> <!-- <!-- text"
|
||||
];
|
||||
blankLines.forEach((line) => t.true(helpers.isBlankLine(line), line || ""));
|
||||
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"
|
||||
];
|
||||
nonBlankLines.forEach((line) => t.true(!helpers.isBlankLine(line), line));
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue