Skip to content

Commit

Permalink
fix(html): False positive for multiple bootstrap script tags
Browse files Browse the repository at this point in the history
Resolves #335
  • Loading branch information
RandomByte committed Oct 1, 2024
1 parent 2495cc0 commit 74ad824
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 36 deletions.
40 changes: 26 additions & 14 deletions src/linter/html/transpiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@ export default async function transpileHtml(
const report = new HtmlReporter(resourcePath, context);
const jsScriptTags = await extractJSScriptTags(contentStream);

const bootstrapTag = findBootstrapTag(jsScriptTags);

if (bootstrapTag) {
lintBootstrapAttributes(bootstrapTag, report);
}

jsScriptTags.forEach((tag) => {
// Tags with src attribute do not parse and run inline code
const hasSrc = tag.attributes.some((attr) => {
return attr.name.value.toLowerCase() === "src";
});
if (!hasSrc && tag.textNodes?.length > 0) {
report.addMessage(MESSAGE.CSP_UNSAFE_INLINE_SCRIPT, tag);
} else if (isBootstrapTag(tag)) {
lintBootstrapAttributes(tag, report);
}
});

Expand All @@ -36,21 +40,29 @@ export default async function transpileHtml(
}
}

function isBootstrapTag(tag: Tag): boolean {
for (const attr of tag.attributes) {
if (attr.name.value.toLowerCase() === "id" &&
attr.value.value.toLowerCase() === "sap-ui-bootstrap") {
return true;
} else if (attr.name.value.toLowerCase() === "src") {
const url = attr.value.value.toLowerCase();
// RegEx from https://github.com/SAP/openui5/blob/661e5f4b6d5f1af9da2175e05f4a8217fbb22593/src/sap.ui.core/src/ui5loader-autoconfig.js#L78
const rBootScripts = /^([^?#]*\/)?(?:sap-ui-(?:core|custom|boot|merged)(?:-[^?#/]*)?|jquery.sap.global|ui5loader(?:-autoconfig)?)\.js(?:[?#]|$)/;
if (rBootScripts.exec(url)) {
return true;
function findBootstrapTag(tags: Tag[]): Tag | undefined {
// First search for script tag with id "sap-ui-bootstrap"
for (const tag of tags) {
for (const attr of tag.attributes) {
if (attr.name.value.toLowerCase() === "id" &&
attr.value.value.toLowerCase() === "sap-ui-bootstrap") {
return tag;
}
}
}

// Fallback to script tag with src attribute pointing to bootstrap script
const rBootScripts = /^([^?#]*\/)?(?:sap-ui-(?:core|custom|boot|merged)(?:-[^?#/]*)?|jquery.sap.global|ui5loader(?:-autoconfig)?)\.js(?:[?#]|$)/;
for (const tag of tags) {
for (const attr of tag.attributes) {
if (attr.name.value.toLowerCase() === "src") {
const url = attr.value.value.toLowerCase();
if (rBootScripts.exec(url)) {
return tag;
}
}
}
}
return false;
}

const oldToNewAttr = new Map([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<script id="sap-ui-bootstrap"
src="resources/my-bootstrap.js"

data-sap-ui-async="true"
data-sap-ui-libs="sap.m, sap.ui.commons">
</script>
</head>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OpenUI5 Todo App</title>
<link rel="icon" href="data:,">
<script id="foo"
src="thirdparty/jquery.js"

data-sap-ui-libs="sap.m, sap.ui.commons">
</script>
<script id="bar"
src="resources/sap-ui-core.js"

data-sap-ui-libs="sap.m, sap.ui.commons">
</script>
<script id="bar"
src="resources/sap-ui-custom.js"

data-sap-ui-libs="sap.m, sap.ui.commons">
</script>
<script id="sap-ui-NO-bootstrap"
src="resources/my-bootstrap.js"

data-sap-ui-async="true"
data-sap-ui-libs="sap.m, sap.ui.commons">
</script>
</head>

<body class="sapUiBody">
<div data-sap-ui-component data-name="sap.ui.demo.todo" data-id="container" data-settings='{"id" : "todo"}'></div>
</body>
</html>
45 changes: 23 additions & 22 deletions test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,50 +152,51 @@ Generated by [AVA](https://avajs.dev).
[
{
coverageInfo: [],
errorCount: 6,
errorCount: 2,
fatalErrorCount: 0,
filePath: 'BootstrapParameters_MultipleScripts.html',
messages: [
{
column: 21,
line: 16,
message: 'Use of deprecated library \' sap.ui.commons\'',
ruleId: 'no-deprecated-library',
severity: 2,
},
{
column: 2,
line: 13,
message: 'Missing bootstrap parameter \'data-sap-ui-async\'',
messageDetails: 'Configuration Options and URL Parameters (https://ui5.sap.com/#/topic/91f2d03b6f4d1014b6dd926db0e91070)',
ruleId: 'no-deprecated-api',
severity: 2,
},
{
column: 21,
line: 21,
line: 27,
message: 'Use of deprecated library \' sap.ui.commons\'',
ruleId: 'no-deprecated-library',
severity: 2,
},
{
column: 2,
line: 18,
message: 'Missing bootstrap parameter \'data-sap-ui-async\'',
messageDetails: 'Configuration Options and URL Parameters (https://ui5.sap.com/#/topic/91f2d03b6f4d1014b6dd926db0e91070)',
line: 23,
message: 'Missing bootstrap parameter \'data-sap-ui-compat-version\'',
messageDetails: 'Compatibility Version Information (deprecated) (https://ui5.sap.com/#/topic/9feb96da02c2429bb1afcf6534d77c79)',
ruleId: 'no-deprecated-api',
severity: 2,
},
],
warningCount: 0,
},
]

## General: BootstrapParameters_MultipleScripts2.html

> Snapshot 1
[
{
coverageInfo: [],
errorCount: 2,
fatalErrorCount: 0,
filePath: 'BootstrapParameters_MultipleScripts2.html',
messages: [
{
column: 21,
line: 26,
line: 16,
message: 'Use of deprecated library \' sap.ui.commons\'',
ruleId: 'no-deprecated-library',
severity: 2,
},
{
column: 2,
line: 23,
line: 13,
message: 'Missing bootstrap parameter \'data-sap-ui-async\'',
messageDetails: 'Configuration Options and URL Parameters (https://ui5.sap.com/#/topic/91f2d03b6f4d1014b6dd926db0e91070)',
ruleId: 'no-deprecated-api',
Expand Down
Binary file modified test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap
Binary file not shown.

0 comments on commit 74ad824

Please sign in to comment.