@@ -358,134 +358,26 @@ module API {
358
358
)
359
359
}
360
360
361
- /** Gets the name of a known built-in. */
362
- private string getBuiltInName ( ) {
363
- // These lists were created by inspecting the `builtins` and `__builtin__` modules in
364
- // Python 3 and 2 respectively, using the `dir` built-in.
365
- // Built-in functions and exceptions shared between Python 2 and 3
366
- result in [
367
- "abs" , "all" , "any" , "bin" , "bool" , "bytearray" , "callable" , "chr" , "classmethod" ,
368
- "compile" , "complex" , "delattr" , "dict" , "dir" , "divmod" , "enumerate" , "eval" , "filter" ,
369
- "float" , "format" , "frozenset" , "getattr" , "globals" , "hasattr" , "hash" , "help" , "hex" ,
370
- "id" , "input" , "int" , "isinstance" , "issubclass" , "iter" , "len" , "list" , "locals" , "map" ,
371
- "max" , "memoryview" , "min" , "next" , "object" , "oct" , "open" , "ord" , "pow" , "print" ,
372
- "property" , "range" , "repr" , "reversed" , "round" , "set" , "setattr" , "slice" , "sorted" ,
373
- "staticmethod" , "str" , "sum" , "super" , "tuple" , "type" , "vars" , "zip" , "__import__" ,
374
- // Exceptions
375
- "ArithmeticError" , "AssertionError" , "AttributeError" , "BaseException" , "BufferError" ,
376
- "BytesWarning" , "DeprecationWarning" , "EOFError" , "EnvironmentError" , "Exception" ,
377
- "FloatingPointError" , "FutureWarning" , "GeneratorExit" , "IOError" , "ImportError" ,
378
- "ImportWarning" , "IndentationError" , "IndexError" , "KeyError" , "KeyboardInterrupt" ,
379
- "LookupError" , "MemoryError" , "NameError" , "NotImplemented" , "NotImplementedError" ,
380
- "OSError" , "OverflowError" , "PendingDeprecationWarning" , "ReferenceError" , "RuntimeError" ,
381
- "RuntimeWarning" , "StandardError" , "StopIteration" , "SyntaxError" , "SyntaxWarning" ,
382
- "SystemError" , "SystemExit" , "TabError" , "TypeError" , "UnboundLocalError" ,
383
- "UnicodeDecodeError" , "UnicodeEncodeError" , "UnicodeError" , "UnicodeTranslateError" ,
384
- "UnicodeWarning" , "UserWarning" , "ValueError" , "Warning" , "ZeroDivisionError" ,
385
- // Added for compatibility
386
- "exec"
387
- ]
388
- or
389
- // Built-in constants shared between Python 2 and 3
390
- result in [ "False" , "True" , "None" , "NotImplemented" , "Ellipsis" , "__debug__" ]
391
- or
392
- // Python 3 only
393
- result in [
394
- "ascii" , "breakpoint" , "bytes" , "exec" , "aiter" , "anext" ,
395
- // Exceptions
396
- "BlockingIOError" , "BrokenPipeError" , "ChildProcessError" , "ConnectionAbortedError" ,
397
- "ConnectionError" , "ConnectionRefusedError" , "ConnectionResetError" , "FileExistsError" ,
398
- "FileNotFoundError" , "InterruptedError" , "IsADirectoryError" , "ModuleNotFoundError" ,
399
- "NotADirectoryError" , "PermissionError" , "ProcessLookupError" , "RecursionError" ,
400
- "ResourceWarning" , "StopAsyncIteration" , "TimeoutError"
401
- ]
402
- or
403
- // Python 2 only
404
- result in [
405
- "basestring" , "cmp" , "execfile" , "file" , "long" , "raw_input" , "reduce" , "reload" ,
406
- "unichr" , "unicode" , "xrange"
407
- ]
408
- }
409
-
410
- /**
411
- * Gets a data flow node that is likely to refer to a built-in with the name `name`.
412
- *
413
- * Currently this is an over-approximation, and may not account for things like overwriting a
414
- * built-in with a different value.
415
- */
416
- private DataFlow:: Node likely_builtin ( string name ) {
417
- exists ( Module m |
418
- result .asCfgNode ( ) =
419
- any ( NameNode n |
420
- possible_builtin_accessed_in_module ( n , name , m ) and
421
- not possible_builtin_defined_in_module ( name , m )
422
- )
423
- )
424
- }
425
-
426
- /**
427
- * Holds if a global variable called `name` (which is also the name of a built-in) is assigned
428
- * a value in the module `m`.
429
- */
430
- private predicate possible_builtin_defined_in_module ( string name , Module m ) {
431
- global_name_defined_in_module ( name , m ) and
432
- name = getBuiltInName ( )
433
- }
434
-
435
- /**
436
- * Holds if `n` is an access of a global variable called `name` (which is also the name of a
437
- * built-in) inside the module `m`.
438
- */
439
- private predicate possible_builtin_accessed_in_module ( NameNode n , string name , Module m ) {
440
- n .isGlobal ( ) and
441
- n .isLoad ( ) and
442
- name = n .getId ( ) and
443
- name = getBuiltInName ( ) and
444
- m = n .getEnclosingModule ( )
445
- }
446
-
447
- /**
448
- * Holds if `n` is an access of a variable called `name` (which is _not_ the name of a
449
- * built-in, and which is _not_ a global defined in the enclosing module) inside the scope `s`.
450
- */
451
- private predicate name_possibly_defined_in_import_star ( NameNode n , string name , Scope s ) {
452
- n .isLoad ( ) and
453
- name = n .getId ( ) and
454
- // Not already defined in an enclosing scope.
455
- not exists ( LocalVariable v |
456
- v .getId ( ) = name and v .getScope ( ) = n .getScope ( ) .getEnclosingScope * ( )
457
- ) and
458
- not name = getBuiltInName ( ) and
459
- s = n .getScope ( ) .getEnclosingScope * ( ) and
460
- exists ( potential_import_star_base ( s ) ) and
461
- not global_name_defined_in_module ( name , n .getEnclosingModule ( ) )
462
- }
463
-
464
- /** Holds if a global variable called `name` is assigned a value in the module `m`. */
465
- private predicate global_name_defined_in_module ( string name , Module m ) {
466
- exists ( NameNode n |
467
- not exists ( LocalVariable v | n .defines ( v ) ) and
468
- n .isStore ( ) and
469
- name = n .getId ( ) and
470
- m = n .getEnclosingModule ( )
471
- )
472
- }
361
+ private import semmle.python.dataflow.new.internal.Builtins
362
+ private import semmle.python.dataflow.new.internal.ImportStar
473
363
474
364
/**
475
365
* Gets the API graph node for all modules imported with `from ... import *` inside the scope `s`.
476
366
*
477
367
* For example, given
478
368
*
479
- * `from foo.bar import *`
369
+ * ```python
370
+ * from foo.bar import *
371
+ * ```
480
372
*
481
373
* this would be the API graph node with the path
482
374
*
483
375
* `moduleImport("foo").getMember("bar")`
484
376
*/
485
377
private TApiNode potential_import_star_base ( Scope s ) {
486
- exists ( DataFlow:: Node ref |
487
- ref .asCfgNode ( ) = any ( ImportStarNode n | n . getScope ( ) = s ) . getModule ( ) and
488
- use ( result , ref )
378
+ exists ( DataFlow:: Node n |
379
+ n .asCfgNode ( ) = ImportStar :: potentialImportStarBase ( s ) and
380
+ use ( result , n )
489
381
)
490
382
}
491
383
@@ -529,14 +421,14 @@ module API {
529
421
or
530
422
// Built-ins, treated as members of the module `builtins`
531
423
base = MkModuleImport ( "builtins" ) and
532
- lbl = Label:: member ( any ( string name | ref = likely_builtin ( name ) ) )
424
+ lbl = Label:: member ( any ( string name | ref = Builtins :: likelyBuiltin ( name ) ) )
533
425
or
534
426
// Unknown variables that may belong to a module imported with `import *`
535
427
exists ( Scope s |
536
428
base = potential_import_star_base ( s ) and
537
429
lbl =
538
430
Label:: member ( any ( string name |
539
- name_possibly_defined_in_import_star ( ref .asCfgNode ( ) , name , s )
431
+ ImportStar :: namePossiblyDefinedInImportStar ( ref .asCfgNode ( ) , name , s )
540
432
) )
541
433
)
542
434
}
0 commit comments