UNPKG

4.92 kBJavaScriptView Raw
1var assert = require("chai").assert;
2var Linter = require("../linter");
3var Config = require("../config");
4var XSSLint = require("../main");
5
6function lint(source) {
7 var linter = new Linter(source, XSSLint.config)
8 return linter.run();
9}
10
11describe("Linter", function() {
12 describe("comment directives", function() {
13 it("should be evaluated", function() {
14 var linter = new Linter("//xsslint safeString.identifier foo /bar/");
15 assert.deepEqual(
16 linter.config.properties["safeString.identifier"],
17 [{identifier: "foo"}, {identifier: /bar/}]
18 );
19 });
20
21 it("should augment existing settings", function() {
22 var config = new Config;
23 config.set("safeString.identifier", "foo");
24 var linter = new Linter("//xsslint safeString.identifier bar", config);
25 assert.deepEqual(
26 linter.config.properties["safeString.identifier"],
27 [{identifier: "foo"}, {identifier: "bar"}]
28 );
29 });
30
31 it("should replace existing settings if set with a !", function() {
32 var config = new Config;
33 config.set("!safeString.identifier", "foo");
34 var linter = new Linter("//xsslint safeString.identifier bar", config);
35 assert.deepEqual(
36 linter.config.properties["safeString.identifier"],
37 [{identifier: "bar"}]
38 );
39 });
40 });
41
42 describe("multiple arguments", function() {
43 it("should check all of them", function() {
44 assert.lengthOf(lint("foo.html('ok', 'ok')"), 0);
45 assert.lengthOf(lint("foo.html('ok', 'ok', notOk)"), 1);
46 });
47 });
48
49 describe("arrays", function() {
50 it("should check each element", function() {
51 assert.lengthOf(lint("foo.html(['ok', 'ok'])"), 0);
52 assert.lengthOf(lint("foo.html(['ok', 'ok', notOk])"), 1);
53 });
54 });
55
56 describe("logical expressions", function() {
57 it("should check both sides", function() {
58 assert.lengthOf(lint("foo.html('foo' || 'bar')"), 0);
59 assert.lengthOf(lint("foo.html('foo' || 'bar')"), 0);
60 assert.lengthOf(lint("foo.html(foo || 'bar')"), 1);
61 assert.lengthOf(lint("foo.html('foo' || bar)"), 1);
62 });
63 });
64
65 describe("ternary expressions", function() {
66 it("should check both possibilities", function() {
67 assert.lengthOf(lint("foo.html(orly ? 'foo' : 'bar')"), 0);
68 assert.lengthOf(lint("foo.html(orly ? foo : 'bar')"), 1);
69 assert.lengthOf(lint("foo.html(orly ? 'foo' : bar)"), 1);
70 });
71 });
72
73 describe("assignment expressions", function() {
74 it("should check the right hand side", function() {
75 assert.lengthOf(lint("foo.html(foo = 'bar')"), 0);
76 assert.lengthOf(lint("foo.html(foo = bar)"), 1);
77 });
78 });
79
80 describe("strings", function() {
81 describe("literals", function() {
82 it("should be ok", function() {
83 assert.lengthOf(lint("foo.html('ohai')"), 0);
84 });
85 });
86
87 describe("concatenation", function() {
88 it("should accept safe strings", function() {
89 assert.lengthOf(lint("foo.html('ohai ' + 'you')"), 0);
90 });
91
92 it("should reject unsafe strings", function() {
93 assert.lengthOf(lint("foo.html('ohai ' + unsafe)"), 1);
94 });
95
96 it("should reject unsafe strings as part of a standalone html snippet", function() {
97 assert.lengthOf(lint("var foo = '<b>' + unsafe + '</b>'"), 1);
98 assert.lengthOf(lint("var foo = '<b>' + ' ' + unsafe + ' ' + '</b>'"), 1);
99 assert.lengthOf(lint("var foo = unsafe + ' ' + '<img>'"), 1);
100 assert.lengthOf(lint("var foo = '<img>' + ' ' + unsafe"), 1);
101 assert.lengthOf(lint("var foo = '<img>' + (' ' + unsafe)"), 1);
102 });
103 });
104 });
105
106 describe("jQuery objects", function() {
107 it("should be ok", function() {
108 assert.lengthOf(lint("foo.html($('div'))"), 0);
109 });
110
111 it("should evaluate method chains", function() {
112 assert.lengthOf(lint("foo.html($('div').clone().hide())"), 0);
113 assert.lengthOf(lint("foo.html(unknown.clone().hide())"), 1);
114 });
115 });
116
117 describe("$()", function() {
118 it("should allow functions", function() {
119 assert.lengthOf(lint("$(function(){})"), 0);
120 });
121
122 it("should allow things that look safe", function() {
123 assert.lengthOf(lint("$(template)"), 0);
124 assert.lengthOf(lint("$(template())"), 0);
125 assert.lengthOf(lint("$(this)"), 0);
126 assert.lengthOf(lint("$(this.el)"), 0);
127 });
128
129 it("should check for unsafe string concatenation", function() {
130 assert.lengthOf(lint("$('<b>' + unknown + '</b>')"), 1);
131 });
132
133 it("should allow arbitrary concatenation if it seems like a selector", function() {
134 assert.lengthOf(lint("$('.foo_' + unknown)"), 0);
135 assert.lengthOf(lint("$(selectorPrefix + unknown)"), 0);
136 });
137
138 it("should validate the html attribute", function() {
139 assert.lengthOf(lint("$('<div />', {html: 'ohai'})"), 0);
140 assert.lengthOf(lint("$('<div />', {html: unsafe})"), 1);
141 });
142 });
143});