Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit abf0347

Browse files
committed
Python points-to: Split strings into bytes and unicode.
1 parent 48c0cbe commit abf0347

5 files changed

Lines changed: 90 additions & 16 deletions

File tree

python/ql/src/semmle/python/objects/Constants.qll

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,31 +244,74 @@ class FloatObjectInternal extends ConstantObjectInternal, TFloat {
244244
}
245245

246246

247-
class StringObjectInternal extends ConstantObjectInternal, TString {
247+
class UnicodeObjectInternal extends ConstantObjectInternal, TUnicode {
248248

249249
override string toString() {
250250
result = "'" + this.strValue() + "'"
251251
}
252252

253253
override predicate introduced(ControlFlowNode node, PointsToContext context) {
254254
context.appliesTo(node) and
255-
node.getNode().(StrConst).getText() = this.strValue()
255+
node.getNode().(StrConst).getText() = this.strValue() and
256+
node.getNode().(StrConst).isUnicode()
256257
}
257258

258259
override ObjectInternal getClass() {
259260
result = TBuiltinClassObject(Builtin::special("unicode"))
260261
}
261262

262263
override Builtin getBuiltin() {
263-
result.(Builtin).strValue() = this.strValue()
264+
result.(Builtin).strValue() = this.strValue() and
265+
result.getClass() = Builtin::special("unicode")
264266
}
265267

266268
override int intValue() {
267269
none()
268270
}
269271

270272
override string strValue() {
271-
this = TString(result)
273+
this = TUnicode(result)
274+
}
275+
276+
override boolean booleanValue() {
277+
this.strValue() = "" and result = false
278+
or
279+
this.strValue() != "" and result = true
280+
}
281+
282+
override int length() {
283+
result = this.strValue().length()
284+
}
285+
286+
}
287+
288+
class BytesObjectInternal extends ConstantObjectInternal, TBytes {
289+
290+
override string toString() {
291+
result = "'" + this.strValue() + "'"
292+
}
293+
294+
override predicate introduced(ControlFlowNode node, PointsToContext context) {
295+
context.appliesTo(node) and
296+
node.getNode().(StrConst).getText() = this.strValue() and
297+
not node.getNode().(StrConst).isUnicode()
298+
}
299+
300+
override ObjectInternal getClass() {
301+
result = TBuiltinClassObject(Builtin::special("bytes"))
302+
}
303+
304+
override Builtin getBuiltin() {
305+
result.(Builtin).strValue() = this.strValue() and
306+
result.getClass() = Builtin::special("bytes")
307+
}
308+
309+
override int intValue() {
310+
none()
311+
}
312+
313+
override string strValue() {
314+
this = TBytes(result)
272315
}
273316

274317
override boolean booleanValue() {

python/ql/src/semmle/python/objects/Modules.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ class PackageObjectInternal extends ModuleObjectInternal, TPackageObject {
171171
or
172172
ModuleAttributes::pointsToAtExit(init, name, ObjectInternal::undefined(), _)
173173
) and
174+
not name = "__init__" and
174175
value = this.submodule(name) and
175176
origin = CfgOrigin::fromObject(value)
176177
)

python/ql/src/semmle/python/objects/TObject.qll

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,34 @@ newtype TObject =
7272
f = any(FloatLiteral num).getValue()
7373
}
7474
or
75-
TString(string s) {
75+
TUnicode(string s) {
7676
// Any string explicitly mentioned in the source code.
77-
s = any(StrConst str).getText()
77+
exists(StrConst str |
78+
s = str.getText() and
79+
str.isUnicode()
80+
)
7881
or
7982
// Any string from the library put in the DB by the extractor.
80-
s = any(Builtin b).strValue()
83+
exists(Builtin b |
84+
s = b.strValue() and
85+
b.getClass() = Builtin::special("unicode")
86+
)
87+
or
88+
s = "__main__"
89+
}
90+
or
91+
TBytes(string s) {
92+
// Any string explicitly mentioned in the source code.
93+
exists(StrConst str |
94+
s = str.getText() and
95+
not str.isUnicode()
96+
)
97+
or
98+
// Any string from the library put in the DB by the extractor.
99+
exists(Builtin b |
100+
s = b.strValue() and
101+
b.getClass() = Builtin::special("bytes")
102+
)
81103
or
82104
s = "__main__"
83105
}

python/ql/src/semmle/python/pointsto/PointsTo.qll

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ cached module PointsToInternal {
177177
}
178178

179179
cached predicate pointsToString(ControlFlowNode f, PointsToContext context, string value) {
180-
exists(StringObjectInternal str |
180+
exists(ObjectInternal str |
181181
PointsToInternal::pointsTo(f, context, str, _) and
182182
str.strValue() = value
183183
)
@@ -494,7 +494,7 @@ cached module PointsToInternal {
494494

495495
/** Implicit "definition" of `__name__` at the start of a module. */
496496
pragma [noinline]
497-
private predicate module_name_points_to(ScopeEntryDefinition def, PointsToContext context, StringObjectInternal value, ControlFlowNode origin) {
497+
private predicate module_name_points_to(ScopeEntryDefinition def, PointsToContext context, ObjectInternal value, ControlFlowNode origin) {
498498
def.getVariable().getName() = "__name__" and
499499
exists(Module m |
500500
m = def.getScope()
@@ -506,7 +506,7 @@ cached module PointsToInternal {
506506
origin = def.getDefiningNode()
507507
}
508508

509-
private StringObjectInternal module_dunder_name(Module m) {
509+
private ObjectInternal module_dunder_name(Module m) {
510510
exists(string name |
511511
result.strValue() = name |
512512
if m.isPackageInit() then
@@ -685,6 +685,8 @@ module InterModulePointsTo {
685685
PointsToInternal::pointsTo(def.getDefiningNode().(ImportStarNode).getModule(), context, mod, _) |
686686
moduleExportsBoolean(mod, var.getSourceVariable().getName()) = false
687687
or
688+
var.getSourceVariable().getName().charAt(0) = "_"
689+
or
688690
exists(Module m, string name |
689691
m = mod.getSourceModule() and name = var.getSourceVariable().getName() |
690692
not m.declaredInAll(_) and name.charAt(0) = "_"
@@ -768,11 +770,14 @@ module InterModulePointsTo {
768770
}
769771

770772
boolean moduleExportsBoolean(ModuleObjectInternal mod, string name) {
771-
result = pythonModuleExportsBoolean(mod, name)
772-
or
773-
result = packageExportsBoolean(mod, name)
774-
or
775-
result = builtinModuleExportsBoolean(mod, name)
773+
not name.charAt(0) = "_" and
774+
(
775+
result = pythonModuleExportsBoolean(mod, name)
776+
or
777+
result = packageExportsBoolean(mod, name)
778+
or
779+
result = builtinModuleExportsBoolean(mod, name)
780+
)
776781
}
777782

778783
}
@@ -2011,7 +2016,8 @@ module ModuleAttributes {
20112016
)
20122017
or
20132018
/* Retain value held before import */
2014-
InterModulePointsTo::moduleExportsBoolean(mod, name) = false and
2019+
(InterModulePointsTo::moduleExportsBoolean(mod, name) = false or name.charAt(0) = "_")
2020+
and
20152021
attributePointsTo(def.getInput(), name, value, origin)
20162022
)
20172023
}

python/ql/test/3/library-tests/modules/package_members/module_attributes.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
| Module test_package | module2 | Module test_package.module2 |
1212
| Module test_package | module3 | Module test_package.module3 |
1313
| Module test_package | module4 | Module test_package.module4 |
14+
| Module test_package | module5 | Module test_package.module5 |
1415
| Module test_package | p | str u'p' |
1516
| Module test_package | q | str u'q' |
1617
| Module test_package | r | str u'r' |
@@ -52,6 +53,7 @@
5253
| Module test_star | module2 | Module test_package.module2 |
5354
| Module test_star | module3 | Module test_package.module3 |
5455
| Module test_star | module4 | Module test_package.module4 |
56+
| Module test_star | module5 | Module test_package.module5 |
5557
| Module test_star | p | str u'p' |
5658
| Module test_star | q | str u'q' |
5759
| Module test_star | r | str u'r' |

0 commit comments

Comments
 (0)