Skip to content

Commit 261821b

Browse files
committed
Merge remote-tracking branch 'upstream/master' into queryStuff
2 parents 2b0a091 + b5c8f22 commit 261821b

File tree

304 files changed

+16196
-5452
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

304 files changed

+16196
-5452
lines changed

change-notes/1.25/analysis-javascript.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,14 @@
2323
- [sqlite](https://www.npmjs.com/package/sqlite)
2424
- [ssh2-streams](https://www.npmjs.com/package/ssh2-streams)
2525
- [ssh2](https://www.npmjs.com/package/ssh2)
26+
- [vue](https://www.npmjs.com/package/vue)
2627
- [yargs](https://www.npmjs.com/package/yargs)
2728
- [webpack-dev-server](https://www.npmjs.com/package/webpack-dev-server)
2829

2930
* TypeScript 3.9 is now supported.
3031

32+
* TypeScript code embedded in HTML and Vue files is now extracted and analyzed.
33+
3134
* The analysis of sanitizers has improved, leading to more accurate
3235
results from the security queries.
3336

@@ -64,6 +67,7 @@
6467
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | More results | This query now recognizes additional utility functions as vulnerable to prototype polution. |
6568
| Uncontrolled command line (`js/command-line-injection`) | More results | This query now recognizes additional command execution calls. |
6669
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional file system calls. |
70+
| Uncontrolled data used in path expression (`js/path-injection`) | Fewer results | This query no longer flags paths that have been checked to be part of a collection. |
6771
| Unknown directive (`js/unknown-directive`) | Fewer results | This query no longer flags directives generated by the Babel compiler. |
6872
| Unneeded defensive code (`js/unneeded-defensive-code`) | Fewer false-positive results | This query now recognizes checks meant to handle the `document.all` object. |
6973
| Unused property (`js/unused-property`) | Fewer results | This query no longer flags properties of objects that are operands of `yield` expressions. |

config/opcode-qldoc.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#!/usr/bin/env python3
2+
3+
import os
4+
import re
5+
path = os.path
6+
7+
needs_an_re = re.compile(r'^(?!Unary)[AEIOU]') # Name requiring "an" instead of "a".
8+
start_qldoc_re = re.compile(r'^\s*/\*\*') # Start of a QLDoc comment
9+
end_qldoc_re = re.compile(r'\*/\s*$') # End of a QLDoc comment
10+
blank_qldoc_line_re = re.compile(r'^\s*\*\s*$') # A line in a QLDoc comment with only the '*'
11+
instruction_class_re = re.compile(r'^class (?P<name>[A-aa-z0-9]+)Instruction\s') # Declaration of an `Instruction` class
12+
opcode_base_class_re = re.compile(r'^abstract class (?P<name>[A-aa-z0-9]+)Opcode\s') # Declaration of an `Opcode` base class
13+
opcode_class_re = re.compile(r'^ class (?P<name>[A-aa-z0-9]+)\s') # Declaration of an `Opcode` class
14+
15+
script_dir = path.realpath(path.dirname(__file__))
16+
instruction_path = path.realpath(path.join(script_dir, '../cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll'))
17+
opcode_path = path.realpath(path.join(script_dir, '../cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll'))
18+
19+
# Scan `Instruction.qll`, keeping track of the QLDoc comment attached to each declaration of a class
20+
# whose name ends with `Instruction`.
21+
instruction_comments = {}
22+
in_qldoc = False
23+
saw_blank_line_in_qldoc = False
24+
qldoc_lines = []
25+
with open(instruction_path, 'r', encoding='utf-8') as instr:
26+
for line in instr:
27+
if in_qldoc:
28+
if end_qldoc_re.search(line):
29+
qldoc_lines.append(line)
30+
in_qldoc = False
31+
elif blank_qldoc_line_re.search(line):
32+
# We're going to skip any lines after the first blank line, to avoid duplicating all
33+
# of the verbose description.
34+
saw_blank_line_in_qldoc = True
35+
elif not saw_blank_line_in_qldoc:
36+
qldoc_lines.append(line)
37+
else:
38+
if start_qldoc_re.search(line):
39+
# Starting a new QLDoc comment.
40+
saw_blank_line_in_qldoc = False
41+
qldoc_lines.append(line)
42+
if not end_qldoc_re.search(line):
43+
in_qldoc = True
44+
else:
45+
instruction_match = instruction_class_re.search(line)
46+
if instruction_match:
47+
# Found the declaration of an `Instruction` class. Record the QLDoc comments.
48+
instruction_comments[instruction_match.group('name')] = qldoc_lines
49+
qldoc_lines = []
50+
51+
# Scan `Opcode.qll`. Whenever we see the declaration of an `Opcode` class for which we have a
52+
# corresponding `Instruction` class, we'll attach a copy of the `Instruction`'s QLDoc comment.
53+
in_qldoc = False
54+
qldoc_lines = []
55+
output_lines = []
56+
with open(opcode_path, 'r', encoding='utf-8') as opcode:
57+
for line in opcode:
58+
if in_qldoc:
59+
qldoc_lines.append(line)
60+
if end_qldoc_re.search(line):
61+
in_qldoc = False
62+
else:
63+
if start_qldoc_re.search(line):
64+
qldoc_lines.append(line)
65+
if not end_qldoc_re.search(line):
66+
in_qldoc = True
67+
else:
68+
name_without_suffix = None
69+
name = None
70+
indent = ''
71+
opcode_base_match = opcode_base_class_re.search(line)
72+
if opcode_base_match:
73+
name_without_suffix = opcode_base_match.group('name')
74+
name = name_without_suffix + 'Opcode'
75+
else:
76+
opcode_match = opcode_class_re.search(line)
77+
if opcode_match:
78+
name_without_suffix = opcode_match.group('name')
79+
name = name_without_suffix
80+
# Indent by two additional spaces, since opcodes are declared in the
81+
# `Opcode` module.
82+
indent = ' '
83+
84+
if name_without_suffix:
85+
# Found an `Opcode` that matches a known `Instruction`. Replace the QLDoc with
86+
# a copy of the one from the `Instruction`.
87+
if instruction_comments.get(name_without_suffix):
88+
article = 'an' if needs_an_re.search(name_without_suffix) else 'a'
89+
qldoc_lines = [
90+
indent + '/**\n',
91+
indent + ' * The `Opcode` for ' + article + ' `' + name_without_suffix + 'Instruction`.\n',
92+
indent + ' *\n',
93+
indent + ' * See the `' + name_without_suffix + 'Instruction` documentation for more details.\n',
94+
indent + ' */\n'
95+
]
96+
output_lines.extend(qldoc_lines)
97+
qldoc_lines = []
98+
output_lines.append(line)
99+
100+
# Write out the updated `Opcode.qll`
101+
with open(opcode_path, 'w', encoding='utf-8') as opcode:
102+
opcode.writelines(output_lines)

0 commit comments

Comments
 (0)