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

Commit

Permalink
#412 Fixing an edge case in the no-octal-literal rule where numbers p…
Browse files Browse the repository at this point in the history
…receeded by an escaped backslash would fail the rule.

Fixing an issue where the no-octal-rule wouldn't handle template strings or newlines inside strings.

Fixing test numbering.

Fixing duplicate variable declaration.
  • Loading branch information
iclanton authored and HamletDRC committed Apr 16, 2018
1 parent 307abc4 commit 7196a26
Show file tree
Hide file tree
Showing 3 changed files with 214 additions and 14 deletions.
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`;
};

0 comments on commit 7196a26

Please sign in to comment.