@@ -358,134 +358,26 @@ module API {
358358 )
359359 }
360360
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
473363
474364 /**
475365 * Gets the API graph node for all modules imported with `from ... import *` inside the scope `s`.
476366 *
477367 * For example, given
478368 *
479- * `from foo.bar import *`
369+ * ```python
370+ * from foo.bar import *
371+ * ```
480372 *
481373 * this would be the API graph node with the path
482374 *
483375 * `moduleImport("foo").getMember("bar")`
484376 */
485377 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 )
489381 )
490382 }
491383
@@ -529,14 +421,14 @@ module API {
529421 or
530422 // Built-ins, treated as members of the module `builtins`
531423 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 ) ) )
533425 or
534426 // Unknown variables that may belong to a module imported with `import *`
535427 exists ( Scope s |
536428 base = potential_import_star_base ( s ) and
537429 lbl =
538430 Label:: member ( any ( string name |
539- name_possibly_defined_in_import_star ( ref .asCfgNode ( ) , name , s )
431+ ImportStar :: namePossiblyDefinedInImportStar ( ref .asCfgNode ( ) , name , s )
540432 ) )
541433 )
542434 }
0 commit comments