dlint: dynamically checking bad coding practices in javascript · dynamic lint-like checking for...
TRANSCRIPT
![Page 1: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/1.jpg)
Liang Gong1, Michael Pradel2, Manu Sridharan3 and Koushik Sen1
1 UC Berkeley 2 TU Darmstadt 3 Samsung Research America
DLint: Dynamically Checking Bad Coding Practices in JavaScript
![Page 2: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/2.jpg)
Why JavaScript?
… 2
• The RedMonk Programming Language Rankings (1st) – Based on GitHub and StackOverflow
• Web assembly language • Web applications, DSL, Desktop App, Mobile App
![Page 3: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/3.jpg)
3
• Designed and Implemented in 10 days • Not all decisions were well thought • Problematic language features
– Error prone – Inefficient code – Security loophole
• Problematic features are retained – backward compatibility
Problematic JavaScript
![Page 4: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/4.jpg)
4
Problematic JavaScript
![Page 5: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/5.jpg)
• Good coding practices • informal rules • improve quality
• Better quality means: • Less correctness issues • Better performance • Better usability • Better maintainability • Less security loopholes • Less surprises • …
5
What is coding practice?
![Page 6: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/6.jpg)
6
var sum = 0, value; var array = [11, 22, 33]; for (value in array) { sum += value; } > sum ?
Rule: avoid using for..in over arrays
![Page 7: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/7.jpg)
7
var sum = 0, value; var array = [11, 22, 33]; for (value in array) { sum += value; } > sum ?
11 + 22 + 33 => 66 array index
(not array value) 0 + 1 + 2 => 3 array index : string 0+"0"+"1"+"2" => "0012"
Rule: avoid using for..in over arrays
![Page 8: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/8.jpg)
• Cross-browser issues • Result depends on the Array prototype object
8
var sum = 0, value; var array = [11, 22, 33]; for (value in array) { sum += value; } > sum ?
11 + 22 + 33 => 66 array index
(not array value) 0 + 1 + 2 => 3 array index : string 0+"0"+"1"+"2" => "0012"
> "0012indexOftoString..."
Rule: avoid using for..in over arrays
![Page 9: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/9.jpg)
9
var sum = 0, value; var array = [11, 22, 33]; for (value in array) { sum += value; } > sum ?
for (i=0; i < array.length; i++) { sum += array[i]; } function addup(element, index, array) { sum += element; } array.forEach(addup);
Rule: avoid using for..in over arrays
![Page 10: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/10.jpg)
10
var sum = 0, value; var array = [11, 22, 33]; for (value in array) { sum += value; } > sum ?
for (i=0; i < array.length; i++) { sum += array[i]; } function addup(element, index, array) { sum += element; } array.forEach(addup);
Rule: avoid using for..in over arrays
![Page 11: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/11.jpg)
Coding Practices and Lint Tools
• Existing Lint-like checkers – Inspect source code – Rule-based checking – Detect common mistakes – Enforce coding conventions
• Limitations: – Approximates behavior – Unknown aliases – Lint tools favor precision over soundness
• Difficulty: Precise static program analysis
11
![Page 12: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/12.jpg)
12
• Dynamic Linter checking code quality rules for JS • Open-source, robust and extensible framework • Formalized and implemented 28 rules
– Counterparts of static rules – Additional rules
• Empirical study – Compare static and dynamic checking
DLint
![Page 13: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/13.jpg)
a.f = b.g PutField(Read("a", a), "f", GetField(Read("b", b), "g")) if (a.f()) ... if (Branch(Method(Read("a", a), "f")()) ... x = y + 1 x = Write("x", Binary(‘+’,Read("y", y), Literal(1))
analysis.Literal(c) analysis.Branch(c) analysis.Read(n, x) analysis.Write(n, x) analysis.PutField(b, f, v) analysis.Binary(op, x, y) analysis.Function(f, isConstructor) analysis.GetField(b,f) analysis.Method(b, f, isConstructor) analysis.Unary(op, x) ...
13
Jalangi: A Dynamic Analysis Framework for JavaScript Koushik Sen, Swaroop Kalasapur, Tasneem Brutch, and Simon Gibbs
![Page 14: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/14.jpg)
• Single-event: Stateless checking • Multi-event: Stateful checking
14
Runtime Patterns
![Page 15: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/15.jpg)
15
Language Misuse
Avoid setting properties of primitives, which has no effect. var fact = 42; fact.isTheAnswer = true; console.log(fact.isTheAnswer); > undefined DLint Checker Predicate: propWrite(base,*,*) Λ isPrim(base)
![Page 16: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/16.jpg)
16
Avoid producing NaN (Not a Number). var x = 23 – "five"; > NaN DLint Checker Predicate: unOp(*, val, NaN) Λ val ≠ NaN
binOp(*, left, right, NaN) Λ left ≠ NaN
Λ right ≠ NaN
call(*, *, args,NaN, *) Λ NaN ≠ args
Uncommon Values
![Page 17: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/17.jpg)
17
Avoid concatenating undefined to string. var value; ... var str = "price: "; ... var result = str + value; > "price: undefined" DLint Checker Predicate: binOp(+, left, right, res) Λ (left = undefined ∨ right = undefined) Λ isString(res)
Uncommon Values
![Page 18: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/18.jpg)
18
Beware that all wrapped primitives coerce to true. var b = false; if (new Boolean(b)) { console.log("true"); } > true
DLint Checker Predicate: cond(val) Λ isWrappedBoolean(val) Λ val.valueOf() = false
API Misuse
![Page 19: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/19.jpg)
19
![Page 20: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/20.jpg)
20
![Page 21: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/21.jpg)
21
![Page 22: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/22.jpg)
• Instrument SpiderMonkey to intercept JavaScript files • Transpile JavaScript code with Jalangi [Sen et al. FSE 2013] • DLint checks runtime states and find issues • Report reason and code location
22
JS program Instrumented JS program
Behavior Information Final Report
DLint Checkers
Jalangi
DLint Overview
![Page 23: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/23.jpg)
23
Evaluation
Research Questions • DLint warning vs. JSHint warning? • Additional warnings from DLint? • Coding convention vs. page popularity?
Experimental Setup • 200 web sites (top 50 + others) • Comparison to JSHint
![Page 24: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/24.jpg)
24
• Some sites: One approach finds all • Most sites: Better together
0% 20% 40% 60% 80% 100%
% of warnings on each site
Web
sites
JSHint Unique Common DLint Unique
% of Warnings: DLint vs. JSHint
![Page 25: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/25.jpg)
25
• 53 warnings per page • 49 are missed by JSHint
0
1
2
3
4
I5 T6 L3 T5 A2 V2 L4 A5 T1 L2 L1 A6 A8 A3 T2 A4 I1 I4 V3 L5 I2 T4 L6 A7 T3Loga
rithm
ic a
vera
ge. #
w
arni
ng /
site
(bas
e 2)
DLint checkers
8
4
2
1
0
Checker shares warning with JSHint Checker shares no warnings with JSHint
Additional Warnings Reported by DLint
![Page 26: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/26.jpg)
26
Correlation between Alexa popularity and number of DLint warnings: 0.6
00.0025
0.0050.0075
0.010.0125
0.0150.0175
0.02
# DL
int W
arn.
/ #C
ov. O
p.
Websites traffic ranking
Quartile 1-3
Mean
00.020.040.060.08
0.10.120.140.16
# JS
Hint
War
ning
/ LO
C
Websites traffic ranking
Quartile 1-3
Mean
Coding Convention vs. Page Popularity
![Page 27: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/27.jpg)
Liang Gong, Electric Engineering & Computer Science, University of California, Berkeley. 27
![Page 28: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/28.jpg)
Liang Gong, Electric Engineering & Computer Science, University of California, Berkeley. 28
![Page 29: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/29.jpg)
29
![Page 30: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/30.jpg)
Liang Gong, Electric Engineering & Computer Science, University of California, Berkeley. 30
![Page 31: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/31.jpg)
31
var decode64 = ""; if (dataLength > 3 && dataLength % 4 == 0) { while (index < dataLength) { decode64 += String.fromCharCode(...); } if (sixbits[3] >= 0x40) { decode64.length -= 1; } }
From Google Octane Game Boy Emulator benchmark:
Rule: avoid setting field on primitive values
![Page 32: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/32.jpg)
32
var decode64 = ""; if (dataLength > 3 && dataLength % 4 == 0) { while (index < dataLength) { decode64 += String.fromCharCode(...); } if (sixbits[3] >= 0x40) { decode64.length -= 1; } }
From Google Octane Game Boy Emulator benchmark:
No effect because decode64 is a primitive string.
Rule: avoid setting field on primitive values
![Page 33: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/33.jpg)
33
window.onbeforeunload= "Twitch.player.getPlayer().pauseVideo();" window.onunload= "Twitch.player.getPlayer().pauseVideo();"
Rule: avoid no effect operations
![Page 34: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/34.jpg)
34
window.onbeforeunload= "Twitch.player.getPlayer().pauseVideo();" window.onunload= "Twitch.player.getPlayer().pauseVideo();"
window.onbeforeunload = function () { Twitch.player.getPlayer().pauseVideo(); }
Rule: avoid no effect operations
![Page 35: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/35.jpg)
35
Takeaways
Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is a open-source, robust and extensible tool
– Works on real-world websites – Found 19 clear bugs on most popular websites
More information: • Paper: “DLint: Dynamically Checking Bad Coding Practices in JavaScript” • Source Code: https://github.com/Berkeley-Correctness-Group/DLint • Google “DLint Berkeley”
![Page 36: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/36.jpg)
36
Takeaways
Thanks!
Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is a open-source, robust and extensible tool
– Works on real-world websites – Found 19 clear bugs on most popular websites
More information: • Paper: “DLint: Dynamically Checking Bad Coding Practices in JavaScript” • Source Code: https://github.com/Berkeley-Correctness-Group/DLint • Google “DLint Berkeley”
![Page 37: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/37.jpg)
• propWrite(base, name, val) • propRead(base, name, val) • cond(val) • unOp(op, val, res) • binOp(op, left, right, res) • call(base, f, args, ret, isConstr)
1. Predicates over runtime events
Example: propWrite(*, "myObject", val) | isPrim(val)
Formalization: declarative specification
37
![Page 38: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/38.jpg)
38
74
359
191
416
1401
62
202
2335
4933
79
205
62
125
167
6
15
26 8
0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
Do not use Number, Boolean, String as a constructor.
The Function constructor is a form of eval.
The object literal notation {} is preferable.
The array literal notation [] is preferable.
document.write can be a form of eval.
Do not override built-in variables.
Implied eval (string instead of function as argument).
eval can be harmful.
Missing 'new' prefix when invoking a constructor.
Fount by JSHint Only Common with DLint
![Page 39: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/39.jpg)
39
E.g., 181 calls of eval(), Function(), etc. missed by JSHint
31
77
181
74
833
79
187
413
6
8
0% 20% 40% 60% 80% 100%
WrappedPrimitives
Literals
DoubleEvaluation
ArgumentsVariable
ConstructorFunctions
A8
L4A
1L1
T5
Found by Dlint Only Common with JSHint
![Page 40: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/40.jpg)
Liang Gong, Electric Engineering & Computer Science, University of California, Berkeley. 40
![Page 41: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/41.jpg)
Liang Gong, Electric Engineering & Computer Science, University of California, Berkeley. 41
![Page 42: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/42.jpg)
42
![Page 43: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/43.jpg)
43
![Page 44: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/44.jpg)
NaN case study for IKEA
44
<prices> <normal> <priceNormal unformatted="9.9">$9.90</priceNormal> <pricePrevious /> <priceNormalPerUnit /> <pricePreviousPerUnit /> </normal> </prices>
previousPrice = getElementValue("pricePrevious" + suffix, normal);
parseFloat(previousPrice).toFixed(2).replace(...) .replace('.00', ''));
XML: Empty Element
JS: undefined
JS: NaN
![Page 45: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/45.jpg)
Avoid accessing the undefined property.
var x; // undefined var y = {}; y[x] = 23; // { undefined: 23 }
propWrite(*, "undefined",*) propRead(*, "undefined", *)
45
Type Related Checker
![Page 46: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/46.jpg)
Chained Analysis
46
PutField(Read("a", a), "f", GetField(Read("b", b), "g"))
a.f = b.g
functions
Chained Analysis
PutField
Read
…
functions
Checker-1
PutField
Read
… functions
Checker-2
PutField
Read
… functions
Checker-n
PutField
Read
…
…
![Page 47: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/47.jpg)
www.google.com/chrome, included code from Modernizr:
https://github.com/Modernizr/Modernizr/pull/1419
47
Rule: avoid using for..in on arrays
for (i in props) { // props is an array prop = props[i]; before = mStyle.style[prop]; ... }
![Page 48: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/48.jpg)
eval is evil, do not use eval.
48
var fun = eval; ... fun("var a = 1;");
API Misuse
call(builtin, eval, ∗, ∗, ∗) call(builtin, Function, ∗, ∗, ∗) call(builtin, setTimeout, args, ∗, ∗) | isString(args[0]) call(builtin, setInterval, args, ∗, ∗) | isString(args[0]) call(document, write, ∗, ∗, ∗)
![Page 49: DLint: Dynamically Checking Bad Coding Practices in JavaScript · Dynamic lint-like checking for JavaScript • Static checkers are not sufficient, DLint complements • DLint is](https://reader035.vdocument.in/reader035/viewer/2022081323/5f0514737e708231d4112910/html5/thumbnails/49.jpg)
49