Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

Fix several edge cases in the no-octal-literal rule. #412

Closed
Closed
Show file tree
Hide file tree
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
17 changes: 11 additions & 6 deletions src/noOctalLiteralRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,26 @@ export class Rule extends Lint.Rules.AbstractRule {

class NoOctalLiteral extends ErrorTolerantWalker {
public visitNode(node: ts.Node) {
if (node.kind === ts.SyntaxKind.StringLiteral) {
if (node.kind === ts.SyntaxKind.StringLiteral || node.kind === ts.SyntaxKind.FirstTemplateToken) {
this.failOnOctalString(<ts.LiteralExpression>node);
}
super.visitNode(node);
}

private failOnOctalString(node: ts.LiteralExpression) {
const match = /("|')(.*(\\-?[0-7]{1,3}(?![0-9])).*("|'))/g.exec(node.getText());
const match = /("|'|`)[^\\]*(\\+-?[0-7]{1,3}(?![0-9]))(?:.|\n|\t|\u2028|\u2029)*(?:\1)/g.exec(node.getText());

if (match) {
const octalValue : string = match[3]; // match[3] is the matched octal value.
const startOfMatch = node.getStart() + node.getText().indexOf(octalValue);
const width = octalValue.length;
let octalValue: string = match[2]; // match[2] is the matched octal value.
const backslashCount: number = octalValue.lastIndexOf('\\') + 1;
if (backslashCount % 2 === 1) { // Make sure the string starts with an odd number of backslashes
octalValue = octalValue.substr(backslashCount - 1);

this.addFailureAt(startOfMatch, width, Rule.FAILURE_STRING + octalValue);
const startOfMatch = node.getStart() + node.getText().indexOf(octalValue);
const width = octalValue.length;

this.addFailureAt(startOfMatch, width, Rule.FAILURE_STRING + octalValue);
}
}
}
}
195 changes: 189 additions & 6 deletions src/tests/NoOctalLiteralTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('noOctalLiteralRule', () : void => {
it('should fail on 3 digit octal literals', () : void => {
const script : string = `
/**
* The following code should have no errors:
* The following code should have errors:
*/
function demoScriptFail() {
var a = "Sample text \\251";
Expand Down Expand Up @@ -65,7 +65,9 @@ function demoScriptFail1() {
return "Sample text \\7";
return "Sample text \\025";
return "Sample text \\0";
return "Sample text \\\\\\0";
return "Sample text \\-0";
return "Sample text \\\\\\-0";
return "Sample text \\-035";
return "Sample text \\-235";
}`;
Expand Down Expand Up @@ -106,25 +108,39 @@ function demoScriptFail1() {
"startPosition": { "character": 25, "line": 11 }
},
{
"failure": "Octal literals should not be used: \\0",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 27, "line": 12 }
},
{
"failure": "Octal literals should not be used: \\-0",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 12 }
"startPosition": { "character": 25, "line": 13 }
},
{
"failure": "Octal literals should not be used: \\-0",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 27, "line": 14 }
},
{
"failure": "Octal literals should not be used: \\-035",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 13 }
"startPosition": { "character": 25, "line": 15 }
},
{
"failure": "Octal literals should not be used: \\-235",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 14 }
"startPosition": { "character": 25, "line": 16 }
}
]);
});
Expand All @@ -142,6 +158,8 @@ function demoScriptFail2() {
return 'Sample text \\125';
return 'Sample text \\0';
return 'Sample text \\-0';
return 'Sample text \\\\\\0';
return 'Sample text \\\\\\-0';
return 'Sample text \\-035';
return 'Sample text \\-235';
}`;
Expand Down Expand Up @@ -195,19 +213,184 @@ function demoScriptFail2() {
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 12 }
},
{
"failure": "Octal literals should not be used: \\0",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 27, "line": 13 }
},
{
"failure": "Octal literals should not be used: \\-0",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 27, "line": 14 }
},
{
"failure": "Octal literals should not be used: \\-035",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 13 }
"startPosition": { "character": 25, "line": 15 }
},
{
"failure": "Octal literals should not be used: \\-235",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 14 }
"startPosition": { "character": 25, "line": 16 }
}
]);
});

it('should produce violations - batch3', () : void => {
const inputFile : string = `
/**
* The following code should have errors:
*/
function demoScriptFail3() {
return \`Sample text \\351\`;
return \`Sample text \\354 more text\`;
return \`Sample text \\33\`;
return \`Sample text \\6\`;
return \`Sample text \\125\`;
return \`Sample text \\0\`;
return \`Sample text \\-0\`;
return \`Sample text \\\\\\0\`;
return \`Sample text \\\\\\-0\`;
return \`Sample text \\-035\`;
return \`Sample text \\-235\`;
}`;
TestHelper.assertViolations(ruleName, inputFile, [
{
"failure": "Octal literals should not be used: \\351",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 6 }
},
{
"failure": "Octal literals should not be used: \\354",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 7 }
},
{
"failure": "Octal literals should not be used: \\33",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 8 }
},
{
"failure": "Octal literals should not be used: \\6",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 9 }
},
{
"failure": "Octal literals should not be used: \\125",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 10 }
},
{
"failure": "Octal literals should not be used: \\0",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 11 }
},
{
"failure": "Octal literals should not be used: \\-0",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 12 }
},
{
"failure": "Octal literals should not be used: \\0",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 27, "line": 13 }
},
{
"failure": "Octal literals should not be used: \\-0",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 27, "line": 14 }
},
{
"failure": "Octal literals should not be used: \\-035",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 15 }
},
{
"failure": "Octal literals should not be used: \\-235",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 16 }
}
]);
});

it('should produce violations - batch4', () : void => {
const inputFile : string = `
/**
* The following code should have errors:
*/
function demoScriptFail4() {
return 'Sample text \\354 \\n more text';
return 'Sample text \\354 \\t more text';
return 'Sample text \\354 \\u2028 more text';
return 'Sample text \\354 \\u2029 more text';
return \`Sample text \\354
more text\`;
}`;
TestHelper.assertViolations(ruleName, inputFile, [
{
"failure": "Octal literals should not be used: \\354",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 6 }
},
{
"failure": "Octal literals should not be used: \\354",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 7 }
},
{
"failure": "Octal literals should not be used: \\354",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 8 }
},
{
"failure": "Octal literals should not be used: \\354",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 9 }
},
{
"failure": "Octal literals should not be used: \\354",
"name": "file.ts",
"ruleName": "no-octal-literal",
"ruleSeverity": "ERROR",
"startPosition": { "character": 25, "line": 10 }
}
]);
});
Expand Down
16 changes: 14 additions & 2 deletions test-data/NoOctalLiteral/NoOctalLiteralTestInput-passing.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
function demoScriptPass1() {
var x = "Sample text \xB2";
var y = "Sample text \0111"; // longer than octal
var w1 = "Sample text \xB2";
var x1 = "Sample text \0111"; // longer than octal
var y1 = "Sample text \\1";
var z1 = "Sample text \\\\1";

var w2 = 'Sample text \xB2';
var x2 = 'Sample text \0111'; // longer than octal
var y2 = 'Sample text \\1';
var z2 = 'Sample text \\\\1';

var w3 = `Sample text \xB2`;
var x3 = `Sample text \0111`; // longer than octal
var y3 = `Sample text \\1`;
var z3 = `Sample text \\\\1`;
};