From e42002e1d74840e82f4ff4456b8eb383ac34e67b Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 17 Jul 2025 11:08:56 +0100 Subject: [PATCH 001/160] Promote IncorrectExceptOrder. However, we lose some results due to not considering builtin/stdlib types. --- .../src/Exceptions/IncorrectExceptOrder.qhelp | 8 +++--- .../ql/src/Exceptions/IncorrectExceptOrder.ql | 25 +++++++++++-------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/python/ql/src/Exceptions/IncorrectExceptOrder.qhelp b/python/ql/src/Exceptions/IncorrectExceptOrder.qhelp index d2854af6ca6..9d78350bcd2 100644 --- a/python/ql/src/Exceptions/IncorrectExceptOrder.qhelp +++ b/python/ql/src/Exceptions/IncorrectExceptOrder.qhelp @@ -25,11 +25,11 @@ is a super class of Error.

Reorganize the except blocks so that the more specific except is defined first. Alternatively, if the more specific except block is -no longer required then it should be deleted.

+no longer required, then it should be deleted.

-

In this example the except Exception: will handle AttributeError preventing the +

In the following example, the except Exception: will handle AttributeError preventing the subsequent handler from ever executing.

@@ -37,8 +37,8 @@ subsequent handler from ever executing.

-
  • Python Language Reference: The try statement, -Exceptions.
  • +
  • Python Language Reference: The try statement, +Exceptions.
  • diff --git a/python/ql/src/Exceptions/IncorrectExceptOrder.ql b/python/ql/src/Exceptions/IncorrectExceptOrder.ql index 3c0c90b36d3..6838a9bc2ae 100644 --- a/python/ql/src/Exceptions/IncorrectExceptOrder.ql +++ b/python/ql/src/Exceptions/IncorrectExceptOrder.ql @@ -14,22 +14,27 @@ */ import python +import semmle.python.dataflow.new.internal.DataFlowDispatch -predicate incorrect_except_order(ExceptStmt ex1, ClassValue cls1, ExceptStmt ex2, ClassValue cls2) { +predicate incorrectExceptOrder(ExceptStmt ex1, Class cls1, ExceptStmt ex2, Class cls2) { exists(int i, int j, Try t | ex1 = t.getHandler(i) and ex2 = t.getHandler(j) and i < j and - cls1 = except_class(ex1) and - cls2 = except_class(ex2) and - cls1 = cls2.getASuperType() + cls1 = exceptClass(ex1) and + cls2 = exceptClass(ex2) and + cls1 = getADirectSuperclass*(cls2) ) } -ClassValue except_class(ExceptStmt ex) { ex.getType().pointsTo(result) } +Class exceptClass(ExceptStmt ex) { ex.getType() = classTracker(result).asExpr() } -from ExceptStmt ex1, ClassValue cls1, ExceptStmt ex2, ClassValue cls2 -where incorrect_except_order(ex1, cls1, ex2, cls2) -select ex2, - "Except block for $@ is unreachable; the more general $@ for $@ will always be executed in preference.", - cls2, cls2.getName(), ex1, "except block", cls1, cls1.getName() +from ExceptStmt ex1, Class cls1, ExceptStmt ex2, Class cls2, string msg +where + incorrectExceptOrder(ex1, cls1, ex2, cls2) and + if cls1 = cls2 + then msg = "This except block handling $@ is unreachable; as $@ also handles $@." + else + msg = + "This except block handling $@ is unreachable; as $@ for the more general $@ always subsumes it." +select ex2, msg, cls2, cls2.getName(), ex1, "this except block", cls1, cls1.getName() From f24f7d5146032f8d611eed53b23f688c2511dc5d Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 21 Aug 2025 13:50:26 +0100 Subject: [PATCH 002/160] Add builtin subclass models, incorporate into query --- .../python/frameworks/builtins.model.yml | 249 ++++++++++++++++++ .../ql/src/Exceptions/IncorrectExceptOrder.ql | 76 +++++- 2 files changed, 321 insertions(+), 4 deletions(-) create mode 100644 python/ql/lib/semmle/python/frameworks/builtins.model.yml diff --git a/python/ql/lib/semmle/python/frameworks/builtins.model.yml b/python/ql/lib/semmle/python/frameworks/builtins.model.yml new file mode 100644 index 00000000000..9789b547903 --- /dev/null +++ b/python/ql/lib/semmle/python/frameworks/builtins.model.yml @@ -0,0 +1,249 @@ +extensions: + - addsTo: + pack: codeql/python-all + extensible: typeModel + data: + - ['builtins.PendingDeprecationWarning~Subclass', 'builtins.PendingDeprecationWarning', ''] + - ['builtins.Warning~Subclass', 'builtins.PendingDeprecationWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.PendingDeprecationWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.PendingDeprecationWarning', ''] + - ['builtins.UnicodeWarning~Subclass', 'builtins.UnicodeWarning', ''] + - ['builtins.Warning~Subclass', 'builtins.UnicodeWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.UnicodeWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.UnicodeWarning', ''] + - ['builtins.StopAsyncIteration~Subclass', 'builtins.StopAsyncIteration', ''] + - ['builtins.Exception~Subclass', 'builtins.StopAsyncIteration', ''] + - ['builtins.BaseException~Subclass', 'builtins.StopAsyncIteration', ''] + - ['builtins.KeyboardInterrupt~Subclass', 'builtins.KeyboardInterrupt', ''] + - ['builtins.BaseException~Subclass', 'builtins.KeyboardInterrupt', ''] + - ['builtins.ConnectionError~Subclass', 'builtins.ConnectionError', ''] + - ['builtins.OSError~Subclass', 'builtins.ConnectionError', ''] + - ['builtins.Exception~Subclass', 'builtins.ConnectionError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ConnectionError', ''] + - ['builtins.ConnectionResetError~Subclass', 'builtins.ConnectionResetError', ''] + - ['builtins.ConnectionError~Subclass', 'builtins.ConnectionResetError', ''] + - ['builtins.OSError~Subclass', 'builtins.ConnectionResetError', ''] + - ['builtins.Exception~Subclass', 'builtins.ConnectionResetError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ConnectionResetError', ''] + - ['builtins.InterruptedError~Subclass', 'builtins.InterruptedError', ''] + - ['builtins.OSError~Subclass', 'builtins.InterruptedError', ''] + - ['builtins.Exception~Subclass', 'builtins.InterruptedError', ''] + - ['builtins.BaseException~Subclass', 'builtins.InterruptedError', ''] + - ['builtins.RuntimeError~Subclass', 'builtins.RuntimeError', ''] + - ['builtins.Exception~Subclass', 'builtins.RuntimeError', ''] + - ['builtins.BaseException~Subclass', 'builtins.RuntimeError', ''] + - ['builtins.AttributeError~Subclass', 'builtins.AttributeError', ''] + - ['builtins.Exception~Subclass', 'builtins.AttributeError', ''] + - ['builtins.BaseException~Subclass', 'builtins.AttributeError', ''] + - ['builtins.IndexError~Subclass', 'builtins.IndexError', ''] + - ['builtins.LookupError~Subclass', 'builtins.IndexError', ''] + - ['builtins.Exception~Subclass', 'builtins.IndexError', ''] + - ['builtins.BaseException~Subclass', 'builtins.IndexError', ''] + - ['builtins.UnicodeDecodeError~Subclass', 'builtins.UnicodeDecodeError', ''] + - ['builtins.UnicodeError~Subclass', 'builtins.UnicodeDecodeError', ''] + - ['builtins.ValueError~Subclass', 'builtins.UnicodeDecodeError', ''] + - ['builtins.Exception~Subclass', 'builtins.UnicodeDecodeError', ''] + - ['builtins.BaseException~Subclass', 'builtins.UnicodeDecodeError', ''] + - ['builtins.OverflowError~Subclass', 'builtins.OverflowError', ''] + - ['builtins.ArithmeticError~Subclass', 'builtins.OverflowError', ''] + - ['builtins.Exception~Subclass', 'builtins.OverflowError', ''] + - ['builtins.BaseException~Subclass', 'builtins.OverflowError', ''] + - ['builtins.BufferError~Subclass', 'builtins.BufferError', ''] + - ['builtins.Exception~Subclass', 'builtins.BufferError', ''] + - ['builtins.BaseException~Subclass', 'builtins.BufferError', ''] + - ['builtins.SyntaxWarning~Subclass', 'builtins.SyntaxWarning', ''] + - ['builtins.Warning~Subclass', 'builtins.SyntaxWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.SyntaxWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.SyntaxWarning', ''] + - ['builtins.BytesWarning~Subclass', 'builtins.BytesWarning', ''] + - ['builtins.Warning~Subclass', 'builtins.BytesWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.BytesWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.BytesWarning', ''] + - ['builtins.StopIteration~Subclass', 'builtins.StopIteration', ''] + - ['builtins.Exception~Subclass', 'builtins.StopIteration', ''] + - ['builtins.BaseException~Subclass', 'builtins.StopIteration', ''] + - ['builtins.ImportError~Subclass', 'builtins.ImportError', ''] + - ['builtins.Exception~Subclass', 'builtins.ImportError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ImportError', ''] + - ['builtins.ChildProcessError~Subclass', 'builtins.ChildProcessError', ''] + - ['builtins.OSError~Subclass', 'builtins.ChildProcessError', ''] + - ['builtins.Exception~Subclass', 'builtins.ChildProcessError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ChildProcessError', ''] + - ['builtins.FileExistsError~Subclass', 'builtins.FileExistsError', ''] + - ['builtins.OSError~Subclass', 'builtins.FileExistsError', ''] + - ['builtins.Exception~Subclass', 'builtins.FileExistsError', ''] + - ['builtins.BaseException~Subclass', 'builtins.FileExistsError', ''] + - ['builtins.PermissionError~Subclass', 'builtins.PermissionError', ''] + - ['builtins.OSError~Subclass', 'builtins.PermissionError', ''] + - ['builtins.Exception~Subclass', 'builtins.PermissionError', ''] + - ['builtins.BaseException~Subclass', 'builtins.PermissionError', ''] + - ['builtins.RecursionError~Subclass', 'builtins.RecursionError', ''] + - ['builtins.RuntimeError~Subclass', 'builtins.RecursionError', ''] + - ['builtins.Exception~Subclass', 'builtins.RecursionError', ''] + - ['builtins.BaseException~Subclass', 'builtins.RecursionError', ''] + - ['builtins.SyntaxError~Subclass', 'builtins.SyntaxError', ''] + - ['builtins.Exception~Subclass', 'builtins.SyntaxError', ''] + - ['builtins.BaseException~Subclass', 'builtins.SyntaxError', ''] + - ['builtins.ExceptionGroup~Subclass', 'builtins.ExceptionGroup', ''] + - ['builtins.BaseExceptionGroup~Subclass', 'builtins.ExceptionGroup', ''] + - ['builtins.Exception~Subclass', 'builtins.ExceptionGroup', ''] + - ['builtins.BaseException~Subclass', 'builtins.ExceptionGroup', ''] + - ['builtins.KeyError~Subclass', 'builtins.KeyError', ''] + - ['builtins.LookupError~Subclass', 'builtins.KeyError', ''] + - ['builtins.Exception~Subclass', 'builtins.KeyError', ''] + - ['builtins.BaseException~Subclass', 'builtins.KeyError', ''] + - ['builtins.UnicodeTranslateError~Subclass', 'builtins.UnicodeTranslateError', ''] + - ['builtins.UnicodeError~Subclass', 'builtins.UnicodeTranslateError', ''] + - ['builtins.ValueError~Subclass', 'builtins.UnicodeTranslateError', ''] + - ['builtins.Exception~Subclass', 'builtins.UnicodeTranslateError', ''] + - ['builtins.BaseException~Subclass', 'builtins.UnicodeTranslateError', ''] + - ['builtins.ZeroDivisionError~Subclass', 'builtins.ZeroDivisionError', ''] + - ['builtins.ArithmeticError~Subclass', 'builtins.ZeroDivisionError', ''] + - ['builtins.Exception~Subclass', 'builtins.ZeroDivisionError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ZeroDivisionError', ''] + - ['builtins.Warning~Subclass', 'builtins.Warning', ''] + - ['builtins.Exception~Subclass', 'builtins.Warning', ''] + - ['builtins.BaseException~Subclass', 'builtins.Warning', ''] + - ['builtins.RuntimeWarning~Subclass', 'builtins.RuntimeWarning', ''] + - ['builtins.Warning~Subclass', 'builtins.RuntimeWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.RuntimeWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.RuntimeWarning', ''] + - ['builtins.EncodingWarning~Subclass', 'builtins.EncodingWarning', ''] + - ['builtins.Warning~Subclass', 'builtins.EncodingWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.EncodingWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.EncodingWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.BaseException', ''] + - ['builtins.GeneratorExit~Subclass', 'builtins.GeneratorExit', ''] + - ['builtins.BaseException~Subclass', 'builtins.GeneratorExit', ''] + - ['builtins.ModuleNotFoundError~Subclass', 'builtins.ModuleNotFoundError', ''] + - ['builtins.ImportError~Subclass', 'builtins.ModuleNotFoundError', ''] + - ['builtins.Exception~Subclass', 'builtins.ModuleNotFoundError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ModuleNotFoundError', ''] + - ['builtins.BrokenPipeError~Subclass', 'builtins.BrokenPipeError', ''] + - ['builtins.ConnectionError~Subclass', 'builtins.BrokenPipeError', ''] + - ['builtins.OSError~Subclass', 'builtins.BrokenPipeError', ''] + - ['builtins.Exception~Subclass', 'builtins.BrokenPipeError', ''] + - ['builtins.BaseException~Subclass', 'builtins.BrokenPipeError', ''] + - ['builtins.FileNotFoundError~Subclass', 'builtins.FileNotFoundError', ''] + - ['builtins.OSError~Subclass', 'builtins.FileNotFoundError', ''] + - ['builtins.Exception~Subclass', 'builtins.FileNotFoundError', ''] + - ['builtins.BaseException~Subclass', 'builtins.FileNotFoundError', ''] + - ['builtins.ProcessLookupError~Subclass', 'builtins.ProcessLookupError', ''] + - ['builtins.OSError~Subclass', 'builtins.ProcessLookupError', ''] + - ['builtins.Exception~Subclass', 'builtins.ProcessLookupError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ProcessLookupError', ''] + - ['builtins.NotImplementedError~Subclass', 'builtins.NotImplementedError', ''] + - ['builtins.RuntimeError~Subclass', 'builtins.NotImplementedError', ''] + - ['builtins.Exception~Subclass', 'builtins.NotImplementedError', ''] + - ['builtins.BaseException~Subclass', 'builtins.NotImplementedError', ''] + - ['builtins.IndentationError~Subclass', 'builtins.IndentationError', ''] + - ['builtins.SyntaxError~Subclass', 'builtins.IndentationError', ''] + - ['builtins.Exception~Subclass', 'builtins.IndentationError', ''] + - ['builtins.BaseException~Subclass', 'builtins.IndentationError', ''] + - ['builtins.ValueError~Subclass', 'builtins.ValueError', ''] + - ['builtins.Exception~Subclass', 'builtins.ValueError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ValueError', ''] + - ['builtins.AssertionError~Subclass', 'builtins.AssertionError', ''] + - ['builtins.Exception~Subclass', 'builtins.AssertionError', ''] + - ['builtins.BaseException~Subclass', 'builtins.AssertionError', ''] + - ['builtins.SystemError~Subclass', 'builtins.SystemError', ''] + - ['builtins.Exception~Subclass', 'builtins.SystemError', ''] + - ['builtins.BaseException~Subclass', 'builtins.SystemError', ''] + - ['builtins.UserWarning~Subclass', 'builtins.UserWarning', ''] + - ['builtins.Warning~Subclass', 'builtins.UserWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.UserWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.UserWarning', ''] + - ['builtins.FutureWarning~Subclass', 'builtins.FutureWarning', ''] + - ['builtins.Warning~Subclass', 'builtins.FutureWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.FutureWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.FutureWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.Exception', ''] + - ['builtins.BaseException~Subclass', 'builtins.Exception', ''] + - ['builtins.ResourceWarning~Subclass', 'builtins.ResourceWarning', ''] + - ['builtins.Warning~Subclass', 'builtins.ResourceWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.ResourceWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.ResourceWarning', ''] + - ['builtins.SystemExit~Subclass', 'builtins.SystemExit', ''] + - ['builtins.BaseException~Subclass', 'builtins.SystemExit', ''] + - ['builtins.OSError~Subclass', 'builtins.OSError', ''] + - ['builtins.Exception~Subclass', 'builtins.OSError', ''] + - ['builtins.BaseException~Subclass', 'builtins.OSError', ''] + - ['builtins.ConnectionAbortedError~Subclass', 'builtins.ConnectionAbortedError', ''] + - ['builtins.ConnectionError~Subclass', 'builtins.ConnectionAbortedError', ''] + - ['builtins.OSError~Subclass', 'builtins.ConnectionAbortedError', ''] + - ['builtins.Exception~Subclass', 'builtins.ConnectionAbortedError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ConnectionAbortedError', ''] + - ['builtins.IsADirectoryError~Subclass', 'builtins.IsADirectoryError', ''] + - ['builtins.OSError~Subclass', 'builtins.IsADirectoryError', ''] + - ['builtins.Exception~Subclass', 'builtins.IsADirectoryError', ''] + - ['builtins.BaseException~Subclass', 'builtins.IsADirectoryError', ''] + - ['builtins.TimeoutError~Subclass', 'builtins.TimeoutError', ''] + - ['builtins.OSError~Subclass', 'builtins.TimeoutError', ''] + - ['builtins.Exception~Subclass', 'builtins.TimeoutError', ''] + - ['builtins.BaseException~Subclass', 'builtins.TimeoutError', ''] + - ['builtins.NameError~Subclass', 'builtins.NameError', ''] + - ['builtins.Exception~Subclass', 'builtins.NameError', ''] + - ['builtins.BaseException~Subclass', 'builtins.NameError', ''] + - ['builtins.TabError~Subclass', 'builtins.TabError', ''] + - ['builtins.IndentationError~Subclass', 'builtins.TabError', ''] + - ['builtins.SyntaxError~Subclass', 'builtins.TabError', ''] + - ['builtins.Exception~Subclass', 'builtins.TabError', ''] + - ['builtins.BaseException~Subclass', 'builtins.TabError', ''] + - ['builtins.UnicodeError~Subclass', 'builtins.UnicodeError', ''] + - ['builtins.ValueError~Subclass', 'builtins.UnicodeError', ''] + - ['builtins.Exception~Subclass', 'builtins.UnicodeError', ''] + - ['builtins.BaseException~Subclass', 'builtins.UnicodeError', ''] + - ['builtins.ArithmeticError~Subclass', 'builtins.ArithmeticError', ''] + - ['builtins.Exception~Subclass', 'builtins.ArithmeticError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ArithmeticError', ''] + - ['builtins.ReferenceError~Subclass', 'builtins.ReferenceError', ''] + - ['builtins.Exception~Subclass', 'builtins.ReferenceError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ReferenceError', ''] + - ['builtins.DeprecationWarning~Subclass', 'builtins.DeprecationWarning', ''] + - ['builtins.Warning~Subclass', 'builtins.DeprecationWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.DeprecationWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.DeprecationWarning', ''] + - ['builtins.ImportWarning~Subclass', 'builtins.ImportWarning', ''] + - ['builtins.Warning~Subclass', 'builtins.ImportWarning', ''] + - ['builtins.Exception~Subclass', 'builtins.ImportWarning', ''] + - ['builtins.BaseException~Subclass', 'builtins.ImportWarning', ''] + - ['builtins.TypeError~Subclass', 'builtins.TypeError', ''] + - ['builtins.Exception~Subclass', 'builtins.TypeError', ''] + - ['builtins.BaseException~Subclass', 'builtins.TypeError', ''] + - ['builtins.BaseExceptionGroup~Subclass', 'builtins.BaseExceptionGroup', ''] + - ['builtins.BaseException~Subclass', 'builtins.BaseExceptionGroup', ''] + - ['builtins.BlockingIOError~Subclass', 'builtins.BlockingIOError', ''] + - ['builtins.OSError~Subclass', 'builtins.BlockingIOError', ''] + - ['builtins.Exception~Subclass', 'builtins.BlockingIOError', ''] + - ['builtins.BaseException~Subclass', 'builtins.BlockingIOError', ''] + - ['builtins.ConnectionRefusedError~Subclass', 'builtins.ConnectionRefusedError', ''] + - ['builtins.ConnectionError~Subclass', 'builtins.ConnectionRefusedError', ''] + - ['builtins.OSError~Subclass', 'builtins.ConnectionRefusedError', ''] + - ['builtins.Exception~Subclass', 'builtins.ConnectionRefusedError', ''] + - ['builtins.BaseException~Subclass', 'builtins.ConnectionRefusedError', ''] + - ['builtins.NotADirectoryError~Subclass', 'builtins.NotADirectoryError', ''] + - ['builtins.OSError~Subclass', 'builtins.NotADirectoryError', ''] + - ['builtins.Exception~Subclass', 'builtins.NotADirectoryError', ''] + - ['builtins.BaseException~Subclass', 'builtins.NotADirectoryError', ''] + - ['builtins.EOFError~Subclass', 'builtins.EOFError', ''] + - ['builtins.Exception~Subclass', 'builtins.EOFError', ''] + - ['builtins.BaseException~Subclass', 'builtins.EOFError', ''] + - ['builtins.UnboundLocalError~Subclass', 'builtins.UnboundLocalError', ''] + - ['builtins.NameError~Subclass', 'builtins.UnboundLocalError', ''] + - ['builtins.Exception~Subclass', 'builtins.UnboundLocalError', ''] + - ['builtins.BaseException~Subclass', 'builtins.UnboundLocalError', ''] + - ['builtins.LookupError~Subclass', 'builtins.LookupError', ''] + - ['builtins.Exception~Subclass', 'builtins.LookupError', ''] + - ['builtins.BaseException~Subclass', 'builtins.LookupError', ''] + - ['builtins.UnicodeEncodeError~Subclass', 'builtins.UnicodeEncodeError', ''] + - ['builtins.UnicodeError~Subclass', 'builtins.UnicodeEncodeError', ''] + - ['builtins.ValueError~Subclass', 'builtins.UnicodeEncodeError', ''] + - ['builtins.Exception~Subclass', 'builtins.UnicodeEncodeError', ''] + - ['builtins.BaseException~Subclass', 'builtins.UnicodeEncodeError', ''] + - ['builtins.FloatingPointError~Subclass', 'builtins.FloatingPointError', ''] + - ['builtins.ArithmeticError~Subclass', 'builtins.FloatingPointError', ''] + - ['builtins.Exception~Subclass', 'builtins.FloatingPointError', ''] + - ['builtins.BaseException~Subclass', 'builtins.FloatingPointError', ''] + - ['builtins.MemoryError~Subclass', 'builtins.MemoryError', ''] + - ['builtins.Exception~Subclass', 'builtins.MemoryError', ''] + - ['builtins.BaseException~Subclass', 'builtins.MemoryError', ''] \ No newline at end of file diff --git a/python/ql/src/Exceptions/IncorrectExceptOrder.ql b/python/ql/src/Exceptions/IncorrectExceptOrder.ql index 6838a9bc2ae..5637c9e3b61 100644 --- a/python/ql/src/Exceptions/IncorrectExceptOrder.ql +++ b/python/ql/src/Exceptions/IncorrectExceptOrder.ql @@ -15,21 +15,89 @@ import python import semmle.python.dataflow.new.internal.DataFlowDispatch +import semmle.python.ApiGraphs +import semmle.python.frameworks.data.internal.ApiGraphModels -predicate incorrectExceptOrder(ExceptStmt ex1, Class cls1, ExceptStmt ex2, Class cls2) { +predicate builtinException(string name) { + typeModel("builtins.BaseException~Subclass", "builtins." + name, "") +} + +predicate builtinExceptionSubclass(string base, string sub) { + typeModel("builtins." + base + "~Subclass", sub, "") +} + +newtype TExceptType = + TClass(Class c) or + TBuiltin(string name) { builtinException(name) } + +class ExceptType extends TExceptType { + Class asClass() { this = TClass(result) } + + string asBuiltinName() { this = TBuiltin(result) } + + predicate isBuiltin() { this = TBuiltin(_) } + + string getName() { + result = this.asClass().getName() + or + result = this.asBuiltinName() + } + + string toString() { result = this.getName() } + + DataFlow::Node getAUse() { + result = classTracker(this.asClass()) + or + result = API::builtin(this.asBuiltinName()).asSource() + } + + ExceptType getADirectSuperclass() { + result.asClass() = getADirectSuperclass(this.asClass()) + or + result.isBuiltin() and + result.getAUse().asExpr() = this.asClass().getABase() + or + builtinExceptionSubclass(result.asBuiltinName(), this.asBuiltinName()) and + this != result + } + + /** + * Holds if this element is at the specified location. + * The location spans column `startColumn` of line `startLine` to + * column `endColumn` of line `endLine` in file `filepath`. + * For more information, see + * [Providing locations in CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ + predicate hasLocationInfo( + string filePath, int startLine, int startColumn, int endLine, int endColumn + ) { + this.asClass() + .getLocation() + .hasLocationInfo(filePath, startLine, startColumn, endLine, endColumn) + or + this.isBuiltin() and + filePath = "" and + startLine = 0 and + startColumn = 0 and + endLine = 0 and + endColumn = 0 + } +} + +predicate incorrectExceptOrder(ExceptStmt ex1, ExceptType cls1, ExceptStmt ex2, ExceptType cls2) { exists(int i, int j, Try t | ex1 = t.getHandler(i) and ex2 = t.getHandler(j) and i < j and cls1 = exceptClass(ex1) and cls2 = exceptClass(ex2) and - cls1 = getADirectSuperclass*(cls2) + cls1 = cls2.getADirectSuperclass*() ) } -Class exceptClass(ExceptStmt ex) { ex.getType() = classTracker(result).asExpr() } +ExceptType exceptClass(ExceptStmt ex) { ex.getType() = result.getAUse().asExpr() } -from ExceptStmt ex1, Class cls1, ExceptStmt ex2, Class cls2, string msg +from ExceptStmt ex1, ExceptType cls1, ExceptStmt ex2, ExceptType cls2, string msg where incorrectExceptOrder(ex1, cls1, ex2, cls2) and if cls1 = cls2 From 9edfd7a6fbbbc66ca609e2de1007306a9034c0b8 Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Thu, 21 Aug 2025 14:01:24 +0100 Subject: [PATCH 003/160] Use generator script directly --- .../python/frameworks/builtins.model.yml | 985 +++++++++++++----- .../process-builtin-exceptions.py | 31 + 2 files changed, 768 insertions(+), 248 deletions(-) create mode 100644 python/ql/src/meta/ClassHierarchy/process-builtin-exceptions.py diff --git a/python/ql/lib/semmle/python/frameworks/builtins.model.yml b/python/ql/lib/semmle/python/frameworks/builtins.model.yml index 9789b547903..da976cb40bb 100644 --- a/python/ql/lib/semmle/python/frameworks/builtins.model.yml +++ b/python/ql/lib/semmle/python/frameworks/builtins.model.yml @@ -1,249 +1,738 @@ +# process-builtin-exceptions 0.0.1; Python 3.11.0rc2 extensions: - - addsTo: - pack: codeql/python-all - extensible: typeModel - data: - - ['builtins.PendingDeprecationWarning~Subclass', 'builtins.PendingDeprecationWarning', ''] - - ['builtins.Warning~Subclass', 'builtins.PendingDeprecationWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.PendingDeprecationWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.PendingDeprecationWarning', ''] - - ['builtins.UnicodeWarning~Subclass', 'builtins.UnicodeWarning', ''] - - ['builtins.Warning~Subclass', 'builtins.UnicodeWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.UnicodeWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.UnicodeWarning', ''] - - ['builtins.StopAsyncIteration~Subclass', 'builtins.StopAsyncIteration', ''] - - ['builtins.Exception~Subclass', 'builtins.StopAsyncIteration', ''] - - ['builtins.BaseException~Subclass', 'builtins.StopAsyncIteration', ''] - - ['builtins.KeyboardInterrupt~Subclass', 'builtins.KeyboardInterrupt', ''] - - ['builtins.BaseException~Subclass', 'builtins.KeyboardInterrupt', ''] - - ['builtins.ConnectionError~Subclass', 'builtins.ConnectionError', ''] - - ['builtins.OSError~Subclass', 'builtins.ConnectionError', ''] - - ['builtins.Exception~Subclass', 'builtins.ConnectionError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ConnectionError', ''] - - ['builtins.ConnectionResetError~Subclass', 'builtins.ConnectionResetError', ''] - - ['builtins.ConnectionError~Subclass', 'builtins.ConnectionResetError', ''] - - ['builtins.OSError~Subclass', 'builtins.ConnectionResetError', ''] - - ['builtins.Exception~Subclass', 'builtins.ConnectionResetError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ConnectionResetError', ''] - - ['builtins.InterruptedError~Subclass', 'builtins.InterruptedError', ''] - - ['builtins.OSError~Subclass', 'builtins.InterruptedError', ''] - - ['builtins.Exception~Subclass', 'builtins.InterruptedError', ''] - - ['builtins.BaseException~Subclass', 'builtins.InterruptedError', ''] - - ['builtins.RuntimeError~Subclass', 'builtins.RuntimeError', ''] - - ['builtins.Exception~Subclass', 'builtins.RuntimeError', ''] - - ['builtins.BaseException~Subclass', 'builtins.RuntimeError', ''] - - ['builtins.AttributeError~Subclass', 'builtins.AttributeError', ''] - - ['builtins.Exception~Subclass', 'builtins.AttributeError', ''] - - ['builtins.BaseException~Subclass', 'builtins.AttributeError', ''] - - ['builtins.IndexError~Subclass', 'builtins.IndexError', ''] - - ['builtins.LookupError~Subclass', 'builtins.IndexError', ''] - - ['builtins.Exception~Subclass', 'builtins.IndexError', ''] - - ['builtins.BaseException~Subclass', 'builtins.IndexError', ''] - - ['builtins.UnicodeDecodeError~Subclass', 'builtins.UnicodeDecodeError', ''] - - ['builtins.UnicodeError~Subclass', 'builtins.UnicodeDecodeError', ''] - - ['builtins.ValueError~Subclass', 'builtins.UnicodeDecodeError', ''] - - ['builtins.Exception~Subclass', 'builtins.UnicodeDecodeError', ''] - - ['builtins.BaseException~Subclass', 'builtins.UnicodeDecodeError', ''] - - ['builtins.OverflowError~Subclass', 'builtins.OverflowError', ''] - - ['builtins.ArithmeticError~Subclass', 'builtins.OverflowError', ''] - - ['builtins.Exception~Subclass', 'builtins.OverflowError', ''] - - ['builtins.BaseException~Subclass', 'builtins.OverflowError', ''] - - ['builtins.BufferError~Subclass', 'builtins.BufferError', ''] - - ['builtins.Exception~Subclass', 'builtins.BufferError', ''] - - ['builtins.BaseException~Subclass', 'builtins.BufferError', ''] - - ['builtins.SyntaxWarning~Subclass', 'builtins.SyntaxWarning', ''] - - ['builtins.Warning~Subclass', 'builtins.SyntaxWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.SyntaxWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.SyntaxWarning', ''] - - ['builtins.BytesWarning~Subclass', 'builtins.BytesWarning', ''] - - ['builtins.Warning~Subclass', 'builtins.BytesWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.BytesWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.BytesWarning', ''] - - ['builtins.StopIteration~Subclass', 'builtins.StopIteration', ''] - - ['builtins.Exception~Subclass', 'builtins.StopIteration', ''] - - ['builtins.BaseException~Subclass', 'builtins.StopIteration', ''] - - ['builtins.ImportError~Subclass', 'builtins.ImportError', ''] - - ['builtins.Exception~Subclass', 'builtins.ImportError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ImportError', ''] - - ['builtins.ChildProcessError~Subclass', 'builtins.ChildProcessError', ''] - - ['builtins.OSError~Subclass', 'builtins.ChildProcessError', ''] - - ['builtins.Exception~Subclass', 'builtins.ChildProcessError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ChildProcessError', ''] - - ['builtins.FileExistsError~Subclass', 'builtins.FileExistsError', ''] - - ['builtins.OSError~Subclass', 'builtins.FileExistsError', ''] - - ['builtins.Exception~Subclass', 'builtins.FileExistsError', ''] - - ['builtins.BaseException~Subclass', 'builtins.FileExistsError', ''] - - ['builtins.PermissionError~Subclass', 'builtins.PermissionError', ''] - - ['builtins.OSError~Subclass', 'builtins.PermissionError', ''] - - ['builtins.Exception~Subclass', 'builtins.PermissionError', ''] - - ['builtins.BaseException~Subclass', 'builtins.PermissionError', ''] - - ['builtins.RecursionError~Subclass', 'builtins.RecursionError', ''] - - ['builtins.RuntimeError~Subclass', 'builtins.RecursionError', ''] - - ['builtins.Exception~Subclass', 'builtins.RecursionError', ''] - - ['builtins.BaseException~Subclass', 'builtins.RecursionError', ''] - - ['builtins.SyntaxError~Subclass', 'builtins.SyntaxError', ''] - - ['builtins.Exception~Subclass', 'builtins.SyntaxError', ''] - - ['builtins.BaseException~Subclass', 'builtins.SyntaxError', ''] - - ['builtins.ExceptionGroup~Subclass', 'builtins.ExceptionGroup', ''] - - ['builtins.BaseExceptionGroup~Subclass', 'builtins.ExceptionGroup', ''] - - ['builtins.Exception~Subclass', 'builtins.ExceptionGroup', ''] - - ['builtins.BaseException~Subclass', 'builtins.ExceptionGroup', ''] - - ['builtins.KeyError~Subclass', 'builtins.KeyError', ''] - - ['builtins.LookupError~Subclass', 'builtins.KeyError', ''] - - ['builtins.Exception~Subclass', 'builtins.KeyError', ''] - - ['builtins.BaseException~Subclass', 'builtins.KeyError', ''] - - ['builtins.UnicodeTranslateError~Subclass', 'builtins.UnicodeTranslateError', ''] - - ['builtins.UnicodeError~Subclass', 'builtins.UnicodeTranslateError', ''] - - ['builtins.ValueError~Subclass', 'builtins.UnicodeTranslateError', ''] - - ['builtins.Exception~Subclass', 'builtins.UnicodeTranslateError', ''] - - ['builtins.BaseException~Subclass', 'builtins.UnicodeTranslateError', ''] - - ['builtins.ZeroDivisionError~Subclass', 'builtins.ZeroDivisionError', ''] - - ['builtins.ArithmeticError~Subclass', 'builtins.ZeroDivisionError', ''] - - ['builtins.Exception~Subclass', 'builtins.ZeroDivisionError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ZeroDivisionError', ''] - - ['builtins.Warning~Subclass', 'builtins.Warning', ''] - - ['builtins.Exception~Subclass', 'builtins.Warning', ''] - - ['builtins.BaseException~Subclass', 'builtins.Warning', ''] - - ['builtins.RuntimeWarning~Subclass', 'builtins.RuntimeWarning', ''] - - ['builtins.Warning~Subclass', 'builtins.RuntimeWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.RuntimeWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.RuntimeWarning', ''] - - ['builtins.EncodingWarning~Subclass', 'builtins.EncodingWarning', ''] - - ['builtins.Warning~Subclass', 'builtins.EncodingWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.EncodingWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.EncodingWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.BaseException', ''] - - ['builtins.GeneratorExit~Subclass', 'builtins.GeneratorExit', ''] - - ['builtins.BaseException~Subclass', 'builtins.GeneratorExit', ''] - - ['builtins.ModuleNotFoundError~Subclass', 'builtins.ModuleNotFoundError', ''] - - ['builtins.ImportError~Subclass', 'builtins.ModuleNotFoundError', ''] - - ['builtins.Exception~Subclass', 'builtins.ModuleNotFoundError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ModuleNotFoundError', ''] - - ['builtins.BrokenPipeError~Subclass', 'builtins.BrokenPipeError', ''] - - ['builtins.ConnectionError~Subclass', 'builtins.BrokenPipeError', ''] - - ['builtins.OSError~Subclass', 'builtins.BrokenPipeError', ''] - - ['builtins.Exception~Subclass', 'builtins.BrokenPipeError', ''] - - ['builtins.BaseException~Subclass', 'builtins.BrokenPipeError', ''] - - ['builtins.FileNotFoundError~Subclass', 'builtins.FileNotFoundError', ''] - - ['builtins.OSError~Subclass', 'builtins.FileNotFoundError', ''] - - ['builtins.Exception~Subclass', 'builtins.FileNotFoundError', ''] - - ['builtins.BaseException~Subclass', 'builtins.FileNotFoundError', ''] - - ['builtins.ProcessLookupError~Subclass', 'builtins.ProcessLookupError', ''] - - ['builtins.OSError~Subclass', 'builtins.ProcessLookupError', ''] - - ['builtins.Exception~Subclass', 'builtins.ProcessLookupError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ProcessLookupError', ''] - - ['builtins.NotImplementedError~Subclass', 'builtins.NotImplementedError', ''] - - ['builtins.RuntimeError~Subclass', 'builtins.NotImplementedError', ''] - - ['builtins.Exception~Subclass', 'builtins.NotImplementedError', ''] - - ['builtins.BaseException~Subclass', 'builtins.NotImplementedError', ''] - - ['builtins.IndentationError~Subclass', 'builtins.IndentationError', ''] - - ['builtins.SyntaxError~Subclass', 'builtins.IndentationError', ''] - - ['builtins.Exception~Subclass', 'builtins.IndentationError', ''] - - ['builtins.BaseException~Subclass', 'builtins.IndentationError', ''] - - ['builtins.ValueError~Subclass', 'builtins.ValueError', ''] - - ['builtins.Exception~Subclass', 'builtins.ValueError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ValueError', ''] - - ['builtins.AssertionError~Subclass', 'builtins.AssertionError', ''] - - ['builtins.Exception~Subclass', 'builtins.AssertionError', ''] - - ['builtins.BaseException~Subclass', 'builtins.AssertionError', ''] - - ['builtins.SystemError~Subclass', 'builtins.SystemError', ''] - - ['builtins.Exception~Subclass', 'builtins.SystemError', ''] - - ['builtins.BaseException~Subclass', 'builtins.SystemError', ''] - - ['builtins.UserWarning~Subclass', 'builtins.UserWarning', ''] - - ['builtins.Warning~Subclass', 'builtins.UserWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.UserWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.UserWarning', ''] - - ['builtins.FutureWarning~Subclass', 'builtins.FutureWarning', ''] - - ['builtins.Warning~Subclass', 'builtins.FutureWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.FutureWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.FutureWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.Exception', ''] - - ['builtins.BaseException~Subclass', 'builtins.Exception', ''] - - ['builtins.ResourceWarning~Subclass', 'builtins.ResourceWarning', ''] - - ['builtins.Warning~Subclass', 'builtins.ResourceWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.ResourceWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.ResourceWarning', ''] - - ['builtins.SystemExit~Subclass', 'builtins.SystemExit', ''] - - ['builtins.BaseException~Subclass', 'builtins.SystemExit', ''] - - ['builtins.OSError~Subclass', 'builtins.OSError', ''] - - ['builtins.Exception~Subclass', 'builtins.OSError', ''] - - ['builtins.BaseException~Subclass', 'builtins.OSError', ''] - - ['builtins.ConnectionAbortedError~Subclass', 'builtins.ConnectionAbortedError', ''] - - ['builtins.ConnectionError~Subclass', 'builtins.ConnectionAbortedError', ''] - - ['builtins.OSError~Subclass', 'builtins.ConnectionAbortedError', ''] - - ['builtins.Exception~Subclass', 'builtins.ConnectionAbortedError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ConnectionAbortedError', ''] - - ['builtins.IsADirectoryError~Subclass', 'builtins.IsADirectoryError', ''] - - ['builtins.OSError~Subclass', 'builtins.IsADirectoryError', ''] - - ['builtins.Exception~Subclass', 'builtins.IsADirectoryError', ''] - - ['builtins.BaseException~Subclass', 'builtins.IsADirectoryError', ''] - - ['builtins.TimeoutError~Subclass', 'builtins.TimeoutError', ''] - - ['builtins.OSError~Subclass', 'builtins.TimeoutError', ''] - - ['builtins.Exception~Subclass', 'builtins.TimeoutError', ''] - - ['builtins.BaseException~Subclass', 'builtins.TimeoutError', ''] - - ['builtins.NameError~Subclass', 'builtins.NameError', ''] - - ['builtins.Exception~Subclass', 'builtins.NameError', ''] - - ['builtins.BaseException~Subclass', 'builtins.NameError', ''] - - ['builtins.TabError~Subclass', 'builtins.TabError', ''] - - ['builtins.IndentationError~Subclass', 'builtins.TabError', ''] - - ['builtins.SyntaxError~Subclass', 'builtins.TabError', ''] - - ['builtins.Exception~Subclass', 'builtins.TabError', ''] - - ['builtins.BaseException~Subclass', 'builtins.TabError', ''] - - ['builtins.UnicodeError~Subclass', 'builtins.UnicodeError', ''] - - ['builtins.ValueError~Subclass', 'builtins.UnicodeError', ''] - - ['builtins.Exception~Subclass', 'builtins.UnicodeError', ''] - - ['builtins.BaseException~Subclass', 'builtins.UnicodeError', ''] - - ['builtins.ArithmeticError~Subclass', 'builtins.ArithmeticError', ''] - - ['builtins.Exception~Subclass', 'builtins.ArithmeticError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ArithmeticError', ''] - - ['builtins.ReferenceError~Subclass', 'builtins.ReferenceError', ''] - - ['builtins.Exception~Subclass', 'builtins.ReferenceError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ReferenceError', ''] - - ['builtins.DeprecationWarning~Subclass', 'builtins.DeprecationWarning', ''] - - ['builtins.Warning~Subclass', 'builtins.DeprecationWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.DeprecationWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.DeprecationWarning', ''] - - ['builtins.ImportWarning~Subclass', 'builtins.ImportWarning', ''] - - ['builtins.Warning~Subclass', 'builtins.ImportWarning', ''] - - ['builtins.Exception~Subclass', 'builtins.ImportWarning', ''] - - ['builtins.BaseException~Subclass', 'builtins.ImportWarning', ''] - - ['builtins.TypeError~Subclass', 'builtins.TypeError', ''] - - ['builtins.Exception~Subclass', 'builtins.TypeError', ''] - - ['builtins.BaseException~Subclass', 'builtins.TypeError', ''] - - ['builtins.BaseExceptionGroup~Subclass', 'builtins.BaseExceptionGroup', ''] - - ['builtins.BaseException~Subclass', 'builtins.BaseExceptionGroup', ''] - - ['builtins.BlockingIOError~Subclass', 'builtins.BlockingIOError', ''] - - ['builtins.OSError~Subclass', 'builtins.BlockingIOError', ''] - - ['builtins.Exception~Subclass', 'builtins.BlockingIOError', ''] - - ['builtins.BaseException~Subclass', 'builtins.BlockingIOError', ''] - - ['builtins.ConnectionRefusedError~Subclass', 'builtins.ConnectionRefusedError', ''] - - ['builtins.ConnectionError~Subclass', 'builtins.ConnectionRefusedError', ''] - - ['builtins.OSError~Subclass', 'builtins.ConnectionRefusedError', ''] - - ['builtins.Exception~Subclass', 'builtins.ConnectionRefusedError', ''] - - ['builtins.BaseException~Subclass', 'builtins.ConnectionRefusedError', ''] - - ['builtins.NotADirectoryError~Subclass', 'builtins.NotADirectoryError', ''] - - ['builtins.OSError~Subclass', 'builtins.NotADirectoryError', ''] - - ['builtins.Exception~Subclass', 'builtins.NotADirectoryError', ''] - - ['builtins.BaseException~Subclass', 'builtins.NotADirectoryError', ''] - - ['builtins.EOFError~Subclass', 'builtins.EOFError', ''] - - ['builtins.Exception~Subclass', 'builtins.EOFError', ''] - - ['builtins.BaseException~Subclass', 'builtins.EOFError', ''] - - ['builtins.UnboundLocalError~Subclass', 'builtins.UnboundLocalError', ''] - - ['builtins.NameError~Subclass', 'builtins.UnboundLocalError', ''] - - ['builtins.Exception~Subclass', 'builtins.UnboundLocalError', ''] - - ['builtins.BaseException~Subclass', 'builtins.UnboundLocalError', ''] - - ['builtins.LookupError~Subclass', 'builtins.LookupError', ''] - - ['builtins.Exception~Subclass', 'builtins.LookupError', ''] - - ['builtins.BaseException~Subclass', 'builtins.LookupError', ''] - - ['builtins.UnicodeEncodeError~Subclass', 'builtins.UnicodeEncodeError', ''] - - ['builtins.UnicodeError~Subclass', 'builtins.UnicodeEncodeError', ''] - - ['builtins.ValueError~Subclass', 'builtins.UnicodeEncodeError', ''] - - ['builtins.Exception~Subclass', 'builtins.UnicodeEncodeError', ''] - - ['builtins.BaseException~Subclass', 'builtins.UnicodeEncodeError', ''] - - ['builtins.FloatingPointError~Subclass', 'builtins.FloatingPointError', ''] - - ['builtins.ArithmeticError~Subclass', 'builtins.FloatingPointError', ''] - - ['builtins.Exception~Subclass', 'builtins.FloatingPointError', ''] - - ['builtins.BaseException~Subclass', 'builtins.FloatingPointError', ''] - - ['builtins.MemoryError~Subclass', 'builtins.MemoryError', ''] - - ['builtins.Exception~Subclass', 'builtins.MemoryError', ''] - - ['builtins.BaseException~Subclass', 'builtins.MemoryError', ''] \ No newline at end of file +- addsTo: + extensible: typeModel + pack: codeql/python-all + data: + - - builtins.PendingDeprecationWarning~Subclass + - builtins.PendingDeprecationWarning + - '' + - - builtins.Warning~Subclass + - builtins.PendingDeprecationWarning + - '' + - - builtins.Exception~Subclass + - builtins.PendingDeprecationWarning + - '' + - - builtins.BaseException~Subclass + - builtins.PendingDeprecationWarning + - '' + - - builtins.UnicodeWarning~Subclass + - builtins.UnicodeWarning + - '' + - - builtins.Warning~Subclass + - builtins.UnicodeWarning + - '' + - - builtins.Exception~Subclass + - builtins.UnicodeWarning + - '' + - - builtins.BaseException~Subclass + - builtins.UnicodeWarning + - '' + - - builtins.StopAsyncIteration~Subclass + - builtins.StopAsyncIteration + - '' + - - builtins.Exception~Subclass + - builtins.StopAsyncIteration + - '' + - - builtins.BaseException~Subclass + - builtins.StopAsyncIteration + - '' + - - builtins.KeyboardInterrupt~Subclass + - builtins.KeyboardInterrupt + - '' + - - builtins.BaseException~Subclass + - builtins.KeyboardInterrupt + - '' + - - builtins.ConnectionError~Subclass + - builtins.ConnectionError + - '' + - - builtins.OSError~Subclass + - builtins.ConnectionError + - '' + - - builtins.Exception~Subclass + - builtins.ConnectionError + - '' + - - builtins.BaseException~Subclass + - builtins.ConnectionError + - '' + - - builtins.ConnectionResetError~Subclass + - builtins.ConnectionResetError + - '' + - - builtins.ConnectionError~Subclass + - builtins.ConnectionResetError + - '' + - - builtins.OSError~Subclass + - builtins.ConnectionResetError + - '' + - - builtins.Exception~Subclass + - builtins.ConnectionResetError + - '' + - - builtins.BaseException~Subclass + - builtins.ConnectionResetError + - '' + - - builtins.InterruptedError~Subclass + - builtins.InterruptedError + - '' + - - builtins.OSError~Subclass + - builtins.InterruptedError + - '' + - - builtins.Exception~Subclass + - builtins.InterruptedError + - '' + - - builtins.BaseException~Subclass + - builtins.InterruptedError + - '' + - - builtins.RuntimeError~Subclass + - builtins.RuntimeError + - '' + - - builtins.Exception~Subclass + - builtins.RuntimeError + - '' + - - builtins.BaseException~Subclass + - builtins.RuntimeError + - '' + - - builtins.AttributeError~Subclass + - builtins.AttributeError + - '' + - - builtins.Exception~Subclass + - builtins.AttributeError + - '' + - - builtins.BaseException~Subclass + - builtins.AttributeError + - '' + - - builtins.IndexError~Subclass + - builtins.IndexError + - '' + - - builtins.LookupError~Subclass + - builtins.IndexError + - '' + - - builtins.Exception~Subclass + - builtins.IndexError + - '' + - - builtins.BaseException~Subclass + - builtins.IndexError + - '' + - - builtins.UnicodeDecodeError~Subclass + - builtins.UnicodeDecodeError + - '' + - - builtins.UnicodeError~Subclass + - builtins.UnicodeDecodeError + - '' + - - builtins.ValueError~Subclass + - builtins.UnicodeDecodeError + - '' + - - builtins.Exception~Subclass + - builtins.UnicodeDecodeError + - '' + - - builtins.BaseException~Subclass + - builtins.UnicodeDecodeError + - '' + - - builtins.ExceptionGroup~Subclass + - builtins.ExceptionGroup + - '' + - - builtins.BaseExceptionGroup~Subclass + - builtins.ExceptionGroup + - '' + - - builtins.Exception~Subclass + - builtins.ExceptionGroup + - '' + - - builtins.BaseException~Subclass + - builtins.ExceptionGroup + - '' + - - builtins.OverflowError~Subclass + - builtins.OverflowError + - '' + - - builtins.ArithmeticError~Subclass + - builtins.OverflowError + - '' + - - builtins.Exception~Subclass + - builtins.OverflowError + - '' + - - builtins.BaseException~Subclass + - builtins.OverflowError + - '' + - - builtins.BufferError~Subclass + - builtins.BufferError + - '' + - - builtins.Exception~Subclass + - builtins.BufferError + - '' + - - builtins.BaseException~Subclass + - builtins.BufferError + - '' + - - builtins.SyntaxWarning~Subclass + - builtins.SyntaxWarning + - '' + - - builtins.Warning~Subclass + - builtins.SyntaxWarning + - '' + - - builtins.Exception~Subclass + - builtins.SyntaxWarning + - '' + - - builtins.BaseException~Subclass + - builtins.SyntaxWarning + - '' + - - builtins.BytesWarning~Subclass + - builtins.BytesWarning + - '' + - - builtins.Warning~Subclass + - builtins.BytesWarning + - '' + - - builtins.Exception~Subclass + - builtins.BytesWarning + - '' + - - builtins.BaseException~Subclass + - builtins.BytesWarning + - '' + - - builtins.StopIteration~Subclass + - builtins.StopIteration + - '' + - - builtins.Exception~Subclass + - builtins.StopIteration + - '' + - - builtins.BaseException~Subclass + - builtins.StopIteration + - '' + - - builtins.ImportError~Subclass + - builtins.ImportError + - '' + - - builtins.Exception~Subclass + - builtins.ImportError + - '' + - - builtins.BaseException~Subclass + - builtins.ImportError + - '' + - - builtins.ChildProcessError~Subclass + - builtins.ChildProcessError + - '' + - - builtins.OSError~Subclass + - builtins.ChildProcessError + - '' + - - builtins.Exception~Subclass + - builtins.ChildProcessError + - '' + - - builtins.BaseException~Subclass + - builtins.ChildProcessError + - '' + - - builtins.FileExistsError~Subclass + - builtins.FileExistsError + - '' + - - builtins.OSError~Subclass + - builtins.FileExistsError + - '' + - - builtins.Exception~Subclass + - builtins.FileExistsError + - '' + - - builtins.BaseException~Subclass + - builtins.FileExistsError + - '' + - - builtins.PermissionError~Subclass + - builtins.PermissionError + - '' + - - builtins.OSError~Subclass + - builtins.PermissionError + - '' + - - builtins.Exception~Subclass + - builtins.PermissionError + - '' + - - builtins.BaseException~Subclass + - builtins.PermissionError + - '' + - - builtins.RecursionError~Subclass + - builtins.RecursionError + - '' + - - builtins.RuntimeError~Subclass + - builtins.RecursionError + - '' + - - builtins.Exception~Subclass + - builtins.RecursionError + - '' + - - builtins.BaseException~Subclass + - builtins.RecursionError + - '' + - - builtins.SyntaxError~Subclass + - builtins.SyntaxError + - '' + - - builtins.Exception~Subclass + - builtins.SyntaxError + - '' + - - builtins.BaseException~Subclass + - builtins.SyntaxError + - '' + - - builtins.KeyError~Subclass + - builtins.KeyError + - '' + - - builtins.LookupError~Subclass + - builtins.KeyError + - '' + - - builtins.Exception~Subclass + - builtins.KeyError + - '' + - - builtins.BaseException~Subclass + - builtins.KeyError + - '' + - - builtins.UnicodeTranslateError~Subclass + - builtins.UnicodeTranslateError + - '' + - - builtins.UnicodeError~Subclass + - builtins.UnicodeTranslateError + - '' + - - builtins.ValueError~Subclass + - builtins.UnicodeTranslateError + - '' + - - builtins.Exception~Subclass + - builtins.UnicodeTranslateError + - '' + - - builtins.BaseException~Subclass + - builtins.UnicodeTranslateError + - '' + - - builtins.ZeroDivisionError~Subclass + - builtins.ZeroDivisionError + - '' + - - builtins.ArithmeticError~Subclass + - builtins.ZeroDivisionError + - '' + - - builtins.Exception~Subclass + - builtins.ZeroDivisionError + - '' + - - builtins.BaseException~Subclass + - builtins.ZeroDivisionError + - '' + - - builtins.Warning~Subclass + - builtins.Warning + - '' + - - builtins.Exception~Subclass + - builtins.Warning + - '' + - - builtins.BaseException~Subclass + - builtins.Warning + - '' + - - builtins.RuntimeWarning~Subclass + - builtins.RuntimeWarning + - '' + - - builtins.Warning~Subclass + - builtins.RuntimeWarning + - '' + - - builtins.Exception~Subclass + - builtins.RuntimeWarning + - '' + - - builtins.BaseException~Subclass + - builtins.RuntimeWarning + - '' + - - builtins.EncodingWarning~Subclass + - builtins.EncodingWarning + - '' + - - builtins.Warning~Subclass + - builtins.EncodingWarning + - '' + - - builtins.Exception~Subclass + - builtins.EncodingWarning + - '' + - - builtins.BaseException~Subclass + - builtins.EncodingWarning + - '' + - - builtins.BaseException~Subclass + - builtins.BaseException + - '' + - - builtins.GeneratorExit~Subclass + - builtins.GeneratorExit + - '' + - - builtins.BaseException~Subclass + - builtins.GeneratorExit + - '' + - - builtins.ModuleNotFoundError~Subclass + - builtins.ModuleNotFoundError + - '' + - - builtins.ImportError~Subclass + - builtins.ModuleNotFoundError + - '' + - - builtins.Exception~Subclass + - builtins.ModuleNotFoundError + - '' + - - builtins.BaseException~Subclass + - builtins.ModuleNotFoundError + - '' + - - builtins.BrokenPipeError~Subclass + - builtins.BrokenPipeError + - '' + - - builtins.ConnectionError~Subclass + - builtins.BrokenPipeError + - '' + - - builtins.OSError~Subclass + - builtins.BrokenPipeError + - '' + - - builtins.Exception~Subclass + - builtins.BrokenPipeError + - '' + - - builtins.BaseException~Subclass + - builtins.BrokenPipeError + - '' + - - builtins.FileNotFoundError~Subclass + - builtins.FileNotFoundError + - '' + - - builtins.OSError~Subclass + - builtins.FileNotFoundError + - '' + - - builtins.Exception~Subclass + - builtins.FileNotFoundError + - '' + - - builtins.BaseException~Subclass + - builtins.FileNotFoundError + - '' + - - builtins.ProcessLookupError~Subclass + - builtins.ProcessLookupError + - '' + - - builtins.OSError~Subclass + - builtins.ProcessLookupError + - '' + - - builtins.Exception~Subclass + - builtins.ProcessLookupError + - '' + - - builtins.BaseException~Subclass + - builtins.ProcessLookupError + - '' + - - builtins.NotImplementedError~Subclass + - builtins.NotImplementedError + - '' + - - builtins.RuntimeError~Subclass + - builtins.NotImplementedError + - '' + - - builtins.Exception~Subclass + - builtins.NotImplementedError + - '' + - - builtins.BaseException~Subclass + - builtins.NotImplementedError + - '' + - - builtins.IndentationError~Subclass + - builtins.IndentationError + - '' + - - builtins.SyntaxError~Subclass + - builtins.IndentationError + - '' + - - builtins.Exception~Subclass + - builtins.IndentationError + - '' + - - builtins.BaseException~Subclass + - builtins.IndentationError + - '' + - - builtins.ValueError~Subclass + - builtins.ValueError + - '' + - - builtins.Exception~Subclass + - builtins.ValueError + - '' + - - builtins.BaseException~Subclass + - builtins.ValueError + - '' + - - builtins.AssertionError~Subclass + - builtins.AssertionError + - '' + - - builtins.Exception~Subclass + - builtins.AssertionError + - '' + - - builtins.BaseException~Subclass + - builtins.AssertionError + - '' + - - builtins.SystemError~Subclass + - builtins.SystemError + - '' + - - builtins.Exception~Subclass + - builtins.SystemError + - '' + - - builtins.BaseException~Subclass + - builtins.SystemError + - '' + - - builtins.UserWarning~Subclass + - builtins.UserWarning + - '' + - - builtins.Warning~Subclass + - builtins.UserWarning + - '' + - - builtins.Exception~Subclass + - builtins.UserWarning + - '' + - - builtins.BaseException~Subclass + - builtins.UserWarning + - '' + - - builtins.FutureWarning~Subclass + - builtins.FutureWarning + - '' + - - builtins.Warning~Subclass + - builtins.FutureWarning + - '' + - - builtins.Exception~Subclass + - builtins.FutureWarning + - '' + - - builtins.BaseException~Subclass + - builtins.FutureWarning + - '' + - - builtins.Exception~Subclass + - builtins.Exception + - '' + - - builtins.BaseException~Subclass + - builtins.Exception + - '' + - - builtins.ResourceWarning~Subclass + - builtins.ResourceWarning + - '' + - - builtins.Warning~Subclass + - builtins.ResourceWarning + - '' + - - builtins.Exception~Subclass + - builtins.ResourceWarning + - '' + - - builtins.BaseException~Subclass + - builtins.ResourceWarning + - '' + - - builtins.SystemExit~Subclass + - builtins.SystemExit + - '' + - - builtins.BaseException~Subclass + - builtins.SystemExit + - '' + - - builtins.OSError~Subclass + - builtins.OSError + - '' + - - builtins.Exception~Subclass + - builtins.OSError + - '' + - - builtins.BaseException~Subclass + - builtins.OSError + - '' + - - builtins.ConnectionAbortedError~Subclass + - builtins.ConnectionAbortedError + - '' + - - builtins.ConnectionError~Subclass + - builtins.ConnectionAbortedError + - '' + - - builtins.OSError~Subclass + - builtins.ConnectionAbortedError + - '' + - - builtins.Exception~Subclass + - builtins.ConnectionAbortedError + - '' + - - builtins.BaseException~Subclass + - builtins.ConnectionAbortedError + - '' + - - builtins.IsADirectoryError~Subclass + - builtins.IsADirectoryError + - '' + - - builtins.OSError~Subclass + - builtins.IsADirectoryError + - '' + - - builtins.Exception~Subclass + - builtins.IsADirectoryError + - '' + - - builtins.BaseException~Subclass + - builtins.IsADirectoryError + - '' + - - builtins.TimeoutError~Subclass + - builtins.TimeoutError + - '' + - - builtins.OSError~Subclass + - builtins.TimeoutError + - '' + - - builtins.Exception~Subclass + - builtins.TimeoutError + - '' + - - builtins.BaseException~Subclass + - builtins.TimeoutError + - '' + - - builtins.NameError~Subclass + - builtins.NameError + - '' + - - builtins.Exception~Subclass + - builtins.NameError + - '' + - - builtins.BaseException~Subclass + - builtins.NameError + - '' + - - builtins.TabError~Subclass + - builtins.TabError + - '' + - - builtins.IndentationError~Subclass + - builtins.TabError + - '' + - - builtins.SyntaxError~Subclass + - builtins.TabError + - '' + - - builtins.Exception~Subclass + - builtins.TabError + - '' + - - builtins.BaseException~Subclass + - builtins.TabError + - '' + - - builtins.UnicodeError~Subclass + - builtins.UnicodeError + - '' + - - builtins.ValueError~Subclass + - builtins.UnicodeError + - '' + - - builtins.Exception~Subclass + - builtins.UnicodeError + - '' + - - builtins.BaseException~Subclass + - builtins.UnicodeError + - '' + - - builtins.ArithmeticError~Subclass + - builtins.ArithmeticError + - '' + - - builtins.Exception~Subclass + - builtins.ArithmeticError + - '' + - - builtins.BaseException~Subclass + - builtins.ArithmeticError + - '' + - - builtins.ReferenceError~Subclass + - builtins.ReferenceError + - '' + - - builtins.Exception~Subclass + - builtins.ReferenceError + - '' + - - builtins.BaseException~Subclass + - builtins.ReferenceError + - '' + - - builtins.DeprecationWarning~Subclass + - builtins.DeprecationWarning + - '' + - - builtins.Warning~Subclass + - builtins.DeprecationWarning + - '' + - - builtins.Exception~Subclass + - builtins.DeprecationWarning + - '' + - - builtins.BaseException~Subclass + - builtins.DeprecationWarning + - '' + - - builtins.ImportWarning~Subclass + - builtins.ImportWarning + - '' + - - builtins.Warning~Subclass + - builtins.ImportWarning + - '' + - - builtins.Exception~Subclass + - builtins.ImportWarning + - '' + - - builtins.BaseException~Subclass + - builtins.ImportWarning + - '' + - - builtins.TypeError~Subclass + - builtins.TypeError + - '' + - - builtins.Exception~Subclass + - builtins.TypeError + - '' + - - builtins.BaseException~Subclass + - builtins.TypeError + - '' + - - builtins.BaseExceptionGroup~Subclass + - builtins.BaseExceptionGroup + - '' + - - builtins.BaseException~Subclass + - builtins.BaseExceptionGroup + - '' + - - builtins.BlockingIOError~Subclass + - builtins.BlockingIOError + - '' + - - builtins.OSError~Subclass + - builtins.BlockingIOError + - '' + - - builtins.Exception~Subclass + - builtins.BlockingIOError + - '' + - - builtins.BaseException~Subclass + - builtins.BlockingIOError + - '' + - - builtins.ConnectionRefusedError~Subclass + - builtins.ConnectionRefusedError + - '' + - - builtins.ConnectionError~Subclass + - builtins.ConnectionRefusedError + - '' + - - builtins.OSError~Subclass + - builtins.ConnectionRefusedError + - '' + - - builtins.Exception~Subclass + - builtins.ConnectionRefusedError + - '' + - - builtins.BaseException~Subclass + - builtins.ConnectionRefusedError + - '' + - - builtins.NotADirectoryError~Subclass + - builtins.NotADirectoryError + - '' + - - builtins.OSError~Subclass + - builtins.NotADirectoryError + - '' + - - builtins.Exception~Subclass + - builtins.NotADirectoryError + - '' + - - builtins.BaseException~Subclass + - builtins.NotADirectoryError + - '' + - - builtins.EOFError~Subclass + - builtins.EOFError + - '' + - - builtins.Exception~Subclass + - builtins.EOFError + - '' + - - builtins.BaseException~Subclass + - builtins.EOFError + - '' + - - builtins.UnboundLocalError~Subclass + - builtins.UnboundLocalError + - '' + - - builtins.NameError~Subclass + - builtins.UnboundLocalError + - '' + - - builtins.Exception~Subclass + - builtins.UnboundLocalError + - '' + - - builtins.BaseException~Subclass + - builtins.UnboundLocalError + - '' + - - builtins.LookupError~Subclass + - builtins.LookupError + - '' + - - builtins.Exception~Subclass + - builtins.LookupError + - '' + - - builtins.BaseException~Subclass + - builtins.LookupError + - '' + - - builtins.UnicodeEncodeError~Subclass + - builtins.UnicodeEncodeError + - '' + - - builtins.UnicodeError~Subclass + - builtins.UnicodeEncodeError + - '' + - - builtins.ValueError~Subclass + - builtins.UnicodeEncodeError + - '' + - - builtins.Exception~Subclass + - builtins.UnicodeEncodeError + - '' + - - builtins.BaseException~Subclass + - builtins.UnicodeEncodeError + - '' + - - builtins.FloatingPointError~Subclass + - builtins.FloatingPointError + - '' + - - builtins.ArithmeticError~Subclass + - builtins.FloatingPointError + - '' + - - builtins.Exception~Subclass + - builtins.FloatingPointError + - '' + - - builtins.BaseException~Subclass + - builtins.FloatingPointError + - '' + - - builtins.MemoryError~Subclass + - builtins.MemoryError + - '' + - - builtins.Exception~Subclass + - builtins.MemoryError + - '' + - - builtins.BaseException~Subclass + - builtins.MemoryError + - '' diff --git a/python/ql/src/meta/ClassHierarchy/process-builtin-exceptions.py b/python/ql/src/meta/ClassHierarchy/process-builtin-exceptions.py new file mode 100644 index 00000000000..fc0266a5b99 --- /dev/null +++ b/python/ql/src/meta/ClassHierarchy/process-builtin-exceptions.py @@ -0,0 +1,31 @@ +from shared_subclass_functions import wrap_in_template +import sys +import yaml +from pathlib import Path + +py_version = sys.version.split()[0] +VERSION = f"process-builtin-exceptions 0.0.1; Python {py_version}" + +builtins_model_path = Path(__file__).parent.parent.parent.parent / "lib/semmle/python/frameworks/builtins.model.yml" + +def write_data(data, path: Path): + f = path.open("w+") + f.write(f"# {VERSION}\n") + yaml.dump(data, indent=2, stream=f, Dumper=yaml.CDumper) + +builtin_names = dir(__builtins__) +builtin_dict = {x: getattr(__builtins__,x) for x in builtin_names} + + +builtin_exceptions = {v for v in builtin_dict.values() if type(v) is type and issubclass(v, BaseException)} + +data = [] +for sub in builtin_exceptions: + for base in sub.__mro__: + if issubclass(base, BaseException): + basename = base.__name__ + subname = sub.__name__ + row = [f"builtins.{basename}~Subclass", f"builtins.{subname}", ""] + data.append(row) + +write_data(wrap_in_template(data), builtins_model_path) From eb4841230ab72ce3dc77d66127d0dada993f248b Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Mon, 25 Aug 2025 13:30:45 +0100 Subject: [PATCH 004/160] Add tests (WIP) --- .../ql/src/Exceptions/IncorrectExceptOrder.ql | 6 ++-- .../general/IncorrectExceptOrder.qlref | 3 +- .../Exceptions/general/exceptions_test.py | 28 ++++++++++++++++++- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/python/ql/src/Exceptions/IncorrectExceptOrder.ql b/python/ql/src/Exceptions/IncorrectExceptOrder.ql index 5637c9e3b61..6eb1b39b0e6 100644 --- a/python/ql/src/Exceptions/IncorrectExceptOrder.ql +++ b/python/ql/src/Exceptions/IncorrectExceptOrder.ql @@ -1,5 +1,5 @@ /** - * @name Unreachable 'except' block + * @name Unreachable `except` block * @description Handling general exceptions before specific exceptions means that the specific * handlers are never executed. * @kind problem @@ -23,7 +23,7 @@ predicate builtinException(string name) { } predicate builtinExceptionSubclass(string base, string sub) { - typeModel("builtins." + base + "~Subclass", sub, "") + typeModel("builtins." + base + "~Subclass", "builtins." + sub, "") } newtype TExceptType = @@ -48,7 +48,7 @@ class ExceptType extends TExceptType { DataFlow::Node getAUse() { result = classTracker(this.asClass()) or - result = API::builtin(this.asBuiltinName()).asSource() + API::builtin(this.asBuiltinName()).asSource().flowsTo(result) } ExceptType getADirectSuperclass() { diff --git a/python/ql/test/query-tests/Exceptions/general/IncorrectExceptOrder.qlref b/python/ql/test/query-tests/Exceptions/general/IncorrectExceptOrder.qlref index bc4c3a07081..5844968f9d6 100644 --- a/python/ql/test/query-tests/Exceptions/general/IncorrectExceptOrder.qlref +++ b/python/ql/test/query-tests/Exceptions/general/IncorrectExceptOrder.qlref @@ -1 +1,2 @@ -Exceptions/IncorrectExceptOrder.ql +query: Exceptions/IncorrectExceptOrder.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/python/ql/test/query-tests/Exceptions/general/exceptions_test.py b/python/ql/test/query-tests/Exceptions/general/exceptions_test.py index d3f782f874f..291b3cb30e0 100644 --- a/python/ql/test/query-tests/Exceptions/general/exceptions_test.py +++ b/python/ql/test/query-tests/Exceptions/general/exceptions_test.py @@ -61,8 +61,34 @@ try: val.attr except Exception: print (2) -except AttributeError: +except AttributeError: # $Alert[py/unreachable-except] print (3) + +class MyExc(ValueError): + pass + +try: + pass +except ValueError: + pass +except MyExc: # $Alert[py/unreachable-except] + pass + +class MyBaseExc(Exception): + pass + +class MySubExc(MyBaseExc): + pass + +try: + pass +except MyBaseExc: + pass +except MySubExc: # $Alert[py/unreachable-except] + pass +except Exception: + pass + #Catch BaseException def catch_base_exception(): From ff4c11f503755f0cbaddedd13df875eb5596ee7a Mon Sep 17 00:00:00 2001 From: Joe Farebrother Date: Sat, 6 Sep 2025 00:45:15 +0100 Subject: [PATCH 005/160] Update test output. Accepting some FNs due to dataflow issue. --- .../Exceptions/general/CatchingBaseException.expected | 2 +- .../test/query-tests/Exceptions/general/EmptyExcept.expected | 3 +++ .../Exceptions/general/IllegalExceptionHandlerType.expected | 2 +- .../Exceptions/general/IncorrectExceptOrder.expected | 2 +- .../general/NotImplementedIsNotAnException.expected | 4 ++-- .../ql/test/query-tests/Exceptions/general/exceptions_test.py | 4 ++-- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/python/ql/test/query-tests/Exceptions/general/CatchingBaseException.expected b/python/ql/test/query-tests/Exceptions/general/CatchingBaseException.expected index 8cbb6d9c961..dbc838a90be 100644 --- a/python/ql/test/query-tests/Exceptions/general/CatchingBaseException.expected +++ b/python/ql/test/query-tests/Exceptions/general/CatchingBaseException.expected @@ -1,2 +1,2 @@ | exceptions_test.py:7:5:7:11 | ExceptStmt | Except block directly handles BaseException. | -| exceptions_test.py:71:5:71:25 | ExceptStmt | Except block directly handles BaseException. | +| exceptions_test.py:97:5:97:25 | ExceptStmt | Except block directly handles BaseException. | diff --git a/python/ql/test/query-tests/Exceptions/general/EmptyExcept.expected b/python/ql/test/query-tests/Exceptions/general/EmptyExcept.expected index 57c50449af8..f9d9c69dd87 100644 --- a/python/ql/test/query-tests/Exceptions/general/EmptyExcept.expected +++ b/python/ql/test/query-tests/Exceptions/general/EmptyExcept.expected @@ -1,2 +1,5 @@ | exceptions_test.py:7:5:7:11 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. | | exceptions_test.py:13:5:13:21 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. | +| exceptions_test.py:72:1:72:18 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. | +| exceptions_test.py:85:1:85:17 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. | +| exceptions_test.py:89:1:89:17 | ExceptStmt | 'except' clause does nothing but pass and there is no explanatory comment. | diff --git a/python/ql/test/query-tests/Exceptions/general/IllegalExceptionHandlerType.expected b/python/ql/test/query-tests/Exceptions/general/IllegalExceptionHandlerType.expected index 0864dd0fe30..5ba0c716371 100644 --- a/python/ql/test/query-tests/Exceptions/general/IllegalExceptionHandlerType.expected +++ b/python/ql/test/query-tests/Exceptions/general/IllegalExceptionHandlerType.expected @@ -1,4 +1,4 @@ | exceptions_test.py:51:5:51:25 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | exceptions_test.py:33:1:33:28 | ControlFlowNode for ClassExpr | class 'NotException1' | | exceptions_test.py:54:5:54:25 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | exceptions_test.py:36:1:36:28 | ControlFlowNode for ClassExpr | class 'NotException2' | -| exceptions_test.py:112:5:112:22 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | exceptions_test.py:107:12:107:14 | ControlFlowNode for FloatLiteral | instance of 'float' | +| exceptions_test.py:138:5:138:22 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | exceptions_test.py:133:12:133:14 | ControlFlowNode for FloatLiteral | instance of 'float' | | pypy_test.py:14:5:14:14 | ExceptStmt | Non-exception $@ in exception handler which will never match raised exception. | pypy_test.py:14:12:14:13 | ControlFlowNode for IntegerLiteral | instance of 'int' | diff --git a/python/ql/test/query-tests/Exceptions/general/IncorrectExceptOrder.expected b/python/ql/test/query-tests/Exceptions/general/IncorrectExceptOrder.expected index 160d5176724..3fab57be376 100644 --- a/python/ql/test/query-tests/Exceptions/general/IncorrectExceptOrder.expected +++ b/python/ql/test/query-tests/Exceptions/general/IncorrectExceptOrder.expected @@ -1 +1 @@ -| exceptions_test.py:64:1:64:22 | ExceptStmt | Except block for $@ is unreachable; the more general $@ for $@ will always be executed in preference. | file://:0:0:0:0 | builtin-class AttributeError | AttributeError | exceptions_test.py:62:1:62:17 | ExceptStmt | except block | file://:0:0:0:0 | builtin-class Exception | Exception | +| exceptions_test.py:64:1:64:22 | ExceptStmt | This except block handling $@ is unreachable; as $@ for the more general $@ always subsumes it. | file://:0:0:0:0 | AttributeError | AttributeError | exceptions_test.py:62:1:62:17 | ExceptStmt | this except block | file://:0:0:0:0 | Exception | Exception | diff --git a/python/ql/test/query-tests/Exceptions/general/NotImplementedIsNotAnException.expected b/python/ql/test/query-tests/Exceptions/general/NotImplementedIsNotAnException.expected index 7c5ee490b4e..0bb863ccfed 100644 --- a/python/ql/test/query-tests/Exceptions/general/NotImplementedIsNotAnException.expected +++ b/python/ql/test/query-tests/Exceptions/general/NotImplementedIsNotAnException.expected @@ -1,2 +1,2 @@ -| exceptions_test.py:170:11:170:24 | NotImplemented | NotImplemented is not an Exception. Did you mean NotImplementedError? | -| exceptions_test.py:173:11:173:26 | NotImplemented() | NotImplemented is not an Exception. Did you mean NotImplementedError? | +| exceptions_test.py:196:11:196:24 | NotImplemented | NotImplemented is not an Exception. Did you mean NotImplementedError? | +| exceptions_test.py:199:11:199:26 | NotImplemented() | NotImplemented is not an Exception. Did you mean NotImplementedError? | diff --git a/python/ql/test/query-tests/Exceptions/general/exceptions_test.py b/python/ql/test/query-tests/Exceptions/general/exceptions_test.py index 291b3cb30e0..cf197683f15 100644 --- a/python/ql/test/query-tests/Exceptions/general/exceptions_test.py +++ b/python/ql/test/query-tests/Exceptions/general/exceptions_test.py @@ -71,7 +71,7 @@ try: pass except ValueError: pass -except MyExc: # $Alert[py/unreachable-except] +except MyExc: # $MISSING:Alert[py/unreachable-except] # Missing due to dataflow limitiation preventing MyExc from being tracked here. pass class MyBaseExc(Exception): @@ -84,7 +84,7 @@ try: pass except MyBaseExc: pass -except MySubExc: # $Alert[py/unreachable-except] +except MySubExc: # $MISSING:Alert[py/unreachable-except] # Missing due to dataflow limitation preventing MyExc from being tracked here. pass except Exception: pass From d729ab501b0d7ed30e2a6e3ea9c14dcd96245973 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 12 Sep 2025 08:45:18 +0200 Subject: [PATCH 006/160] JS: Add test that calls .json or .jsonp --- .../frameworks/Express/src/json.js | 10 +++ .../frameworks/Express/tests.expected | 73 +++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 javascript/ql/test/library-tests/frameworks/Express/src/json.js diff --git a/javascript/ql/test/library-tests/frameworks/Express/src/json.js b/javascript/ql/test/library-tests/frameworks/Express/src/json.js new file mode 100644 index 00000000000..6b87cad68cf --- /dev/null +++ b/javascript/ql/test/library-tests/frameworks/Express/src/json.js @@ -0,0 +1,10 @@ +const express = require('express'); +const app = express(); + +app.get('/test/json', function(req, res) { + res.json(req.query.data); +}); + +app.get('/test/jsonp', function(req, res) { + res.jsonp(req.query.data); +}); diff --git a/javascript/ql/test/library-tests/frameworks/Express/tests.expected b/javascript/ql/test/library-tests/frameworks/Express/tests.expected index ec4253740f7..0abc2dbdf95 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/Express/tests.expected @@ -131,6 +131,12 @@ test_isRequest | src/inheritedFromNode.js:4:24:4:26 | req | | src/inheritedFromNode.js:4:24:4:26 | req | | src/inheritedFromNode.js:7:2:7:4 | req | +| src/json.js:4:32:4:34 | req | +| src/json.js:4:32:4:34 | req | +| src/json.js:5:14:5:16 | req | +| src/json.js:8:33:8:35 | req | +| src/json.js:8:33:8:35 | req | +| src/json.js:9:15:9:17 | req | | src/middleware-flow.js:5:20:5:22 | req | | src/middleware-flow.js:5:20:5:22 | req | | src/middleware-flow.js:6:5:6:7 | req | @@ -201,6 +207,8 @@ test_RouteSetup | src/express.js:65:1:69:2 | app.get ... es);\\n}) | src/express.js:2:11:2:19 | express() | false | | src/express.js:71:1:75:2 | app.get ... es);\\n}) | src/express.js:2:11:2:19 | express() | false | | src/inheritedFromNode.js:4:1:8:2 | app.pos ... url;\\n}) | src/inheritedFromNode.js:2:11:2:19 | express() | false | +| src/json.js:4:1:6:2 | app.get ... ta);\\n}) | src/json.js:2:13:2:21 | express() | false | +| src/json.js:8:1:10:2 | app.get ... ta);\\n}) | src/json.js:2:13:2:21 | express() | false | | src/middleware-flow.js:13:5:13:25 | router. ... tallDb) | src/middleware-flow.js:2:13:2:21 | express() | true | | src/middleware-flow.js:17:5:21:6 | router. ... \\n }) | src/middleware-flow.js:2:13:2:21 | express() | false | | src/middleware-flow.js:39:1:43:2 | unrelat ... .db;\\n}) | src/middleware-flow.js:37:22:37:30 | express() | false | @@ -345,6 +353,14 @@ test_isResponse | src/inheritedFromNode.js:4:29:4:31 | res | | src/inheritedFromNode.js:5:2:5:4 | res | | src/inheritedFromNode.js:6:2:6:4 | res | +| src/json.js:4:37:4:39 | res | +| src/json.js:4:37:4:39 | res | +| src/json.js:5:5:5:7 | res | +| src/json.js:5:5:5:28 | res.jso ... y.data) | +| src/json.js:8:38:8:40 | res | +| src/json.js:8:38:8:40 | res | +| src/json.js:9:5:9:7 | res | +| src/json.js:9:5:9:29 | res.jso ... y.data) | | src/middleware-flow.js:5:25:5:27 | res | | src/middleware-flow.js:17:30:17:32 | res | | src/middleware-flow.js:23:23:23:25 | res | @@ -575,6 +591,12 @@ test_RequestExpr | src/inheritedFromNode.js:4:24:4:26 | req | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | | src/inheritedFromNode.js:4:24:4:26 | req | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | | src/inheritedFromNode.js:7:2:7:4 | req | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/json.js:4:32:4:34 | req | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:4:32:4:34 | req | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:5:14:5:16 | req | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:8:33:8:35 | req | src/json.js:8:24:10:1 | functio ... ata);\\n} | +| src/json.js:8:33:8:35 | req | src/json.js:8:24:10:1 | functio ... ata);\\n} | +| src/json.js:9:15:9:17 | req | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/middleware-flow.js:5:20:5:22 | req | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | | src/middleware-flow.js:5:20:5:22 | req | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | | src/middleware-flow.js:6:5:6:7 | req | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | @@ -627,6 +649,7 @@ test_appCreation | src/express4.js:2:11:2:19 | express() | | src/express.js:2:11:2:19 | express() | | src/inheritedFromNode.js:2:11:2:19 | express() | +| src/json.js:2:13:2:21 | express() | | src/middleware-flow.js:2:13:2:21 | express() | | src/middleware-flow.js:37:22:37:30 | express() | | src/params.js:2:11:2:19 | express() | @@ -820,6 +843,14 @@ test_ResponseExpr | src/inheritedFromNode.js:4:29:4:31 | res | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | | src/inheritedFromNode.js:5:2:5:4 | res | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | | src/inheritedFromNode.js:6:2:6:4 | res | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/json.js:4:37:4:39 | res | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:4:37:4:39 | res | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:5:5:5:7 | res | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:5:5:5:28 | res.jso ... y.data) | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:8:38:8:40 | res | src/json.js:8:24:10:1 | functio ... ata);\\n} | +| src/json.js:8:38:8:40 | res | src/json.js:8:24:10:1 | functio ... ata);\\n} | +| src/json.js:9:5:9:7 | res | src/json.js:8:24:10:1 | functio ... ata);\\n} | +| src/json.js:9:5:9:29 | res.jso ... y.data) | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/middleware-flow.js:5:25:5:27 | res | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | | src/middleware-flow.js:17:30:17:32 | res | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | | src/middleware-flow.js:23:23:23:25 | res | src/middleware-flow.js:23:17:23:41 | (req, r ... q.db; } | @@ -940,6 +971,8 @@ test_RouteHandler | src/express.js:65:27:69:1 | functio ... res);\\n} | src/express.js:65:36:65:38 | req | src/express.js:65:41:65:43 | res | | src/express.js:71:23:75:1 | functio ... res);\\n} | src/express.js:71:32:71:34 | req | src/express.js:71:37:71:39 | res | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:4:24:4:26 | req | src/inheritedFromNode.js:4:29:4:31 | res | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | src/json.js:4:32:4:34 | req | src/json.js:4:37:4:39 | res | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | src/json.js:8:33:8:35 | req | src/json.js:8:38:8:40 | res | | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:5:20:5:22 | req | src/middleware-flow.js:5:25:5:27 | res | | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | src/middleware-flow.js:17:25:17:27 | req | src/middleware-flow.js:17:30:17:32 | res | | src/middleware-flow.js:23:17:23:41 | (req, r ... q.db; } | src/middleware-flow.js:23:18:23:20 | req | src/middleware-flow.js:23:23:23:25 | res | @@ -1036,6 +1069,8 @@ test_RouteHandlerExpr | src/express.js:65:27:69:1 | functio ... res);\\n} | src/express.js:65:1:69:2 | app.get ... es);\\n}) | true | | src/express.js:71:23:75:1 | functio ... res);\\n} | src/express.js:71:1:75:2 | app.get ... es);\\n}) | true | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:4:1:8:2 | app.pos ... url;\\n}) | true | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | src/json.js:4:1:6:2 | app.get ... ta);\\n}) | true | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | src/json.js:8:1:10:2 | app.get ... ta);\\n}) | true | | src/middleware-flow.js:13:16:13:24 | installDb | src/middleware-flow.js:13:5:13:25 | router. ... tallDb) | false | | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | src/middleware-flow.js:17:5:21:6 | router. ... \\n }) | true | | src/middleware-flow.js:27:23:27:32 | routers[p] | src/middleware-flow.js:27:9:27:33 | router. ... ers[p]) | true | @@ -1068,6 +1103,7 @@ test_isRouterCreation | src/express4.js:2:11:2:19 | express() | | src/express.js:2:11:2:19 | express() | | src/inheritedFromNode.js:2:11:2:19 | express() | +| src/json.js:2:13:2:21 | express() | | src/middleware-flow.js:2:13:2:21 | express() | | src/middleware-flow.js:37:22:37:30 | express() | | src/params.js:2:11:2:19 | express() | @@ -1111,6 +1147,8 @@ test_RequestInputAccess | src/express.js:67:12:67:25 | req.params.foo | parameter | src/express.js:65:27:69:1 | functio ... res);\\n} | | src/express.js:73:12:73:19 | req.path | url | src/express.js:71:23:75:1 | functio ... res);\\n} | | src/inheritedFromNode.js:7:2:7:8 | req.url | url | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/json.js:5:14:5:27 | req.query.data | parameter | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:9:15:9:28 | req.query.data | parameter | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/params.js:4:35:4:39 | value | parameter | src/params.js:4:18:12:1 | (req, r ... }\\n} | | src/params.js:5:17:5:28 | req.query.xx | parameter | src/params.js:4:18:12:1 | (req, r ... }\\n} | | src/params.js:6:17:6:24 | req.body | body | src/params.js:4:18:12:1 | (req, r ... }\\n} | @@ -1182,6 +1220,8 @@ test_RouteSetup_getRouter | src/express.js:65:1:69:2 | app.get ... es);\\n}) | src/express.js:2:11:2:19 | express() | | src/express.js:71:1:75:2 | app.get ... es);\\n}) | src/express.js:2:11:2:19 | express() | | src/inheritedFromNode.js:4:1:8:2 | app.pos ... url;\\n}) | src/inheritedFromNode.js:2:11:2:19 | express() | +| src/json.js:4:1:6:2 | app.get ... ta);\\n}) | src/json.js:2:13:2:21 | express() | +| src/json.js:8:1:10:2 | app.get ... ta);\\n}) | src/json.js:2:13:2:21 | express() | | src/middleware-flow.js:13:5:13:25 | router. ... tallDb) | src/middleware-flow.js:2:13:2:21 | express() | | src/middleware-flow.js:17:5:21:6 | router. ... \\n }) | src/middleware-flow.js:2:13:2:21 | express() | | src/middleware-flow.js:27:9:27:33 | router. ... ers[p]) | src/middleware-flow.js:2:13:2:21 | express() | @@ -1226,6 +1266,8 @@ test_RouteSetup_getServer | src/express.js:65:1:69:2 | app.get ... es);\\n}) | src/express.js:2:11:2:19 | express() | | src/express.js:71:1:75:2 | app.get ... es);\\n}) | src/express.js:2:11:2:19 | express() | | src/inheritedFromNode.js:4:1:8:2 | app.pos ... url;\\n}) | src/inheritedFromNode.js:2:11:2:19 | express() | +| src/json.js:4:1:6:2 | app.get ... ta);\\n}) | src/json.js:2:13:2:21 | express() | +| src/json.js:8:1:10:2 | app.get ... ta);\\n}) | src/json.js:2:13:2:21 | express() | | src/middleware-flow.js:13:5:13:25 | router. ... tallDb) | src/middleware-flow.js:2:13:2:21 | express() | | src/middleware-flow.js:17:5:21:6 | router. ... \\n }) | src/middleware-flow.js:2:13:2:21 | express() | | src/middleware-flow.js:39:1:43:2 | unrelat ... .db;\\n}) | src/middleware-flow.js:37:22:37:30 | express() | @@ -1266,6 +1308,8 @@ test_StandardRouteHandler | src/express.js:65:27:69:1 | functio ... res);\\n} | src/express.js:2:11:2:19 | express() | src/express.js:65:36:65:38 | req | src/express.js:65:41:65:43 | res | | src/express.js:71:23:75:1 | functio ... res);\\n} | src/express.js:2:11:2:19 | express() | src/express.js:71:32:71:34 | req | src/express.js:71:37:71:39 | res | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:2:11:2:19 | express() | src/inheritedFromNode.js:4:24:4:26 | req | src/inheritedFromNode.js:4:29:4:31 | res | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | src/json.js:2:13:2:21 | express() | src/json.js:4:32:4:34 | req | src/json.js:4:37:4:39 | res | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | src/json.js:2:13:2:21 | express() | src/json.js:8:33:8:35 | req | src/json.js:8:38:8:40 | res | | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:2:13:2:21 | express() | src/middleware-flow.js:5:20:5:22 | req | src/middleware-flow.js:5:25:5:27 | res | | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | src/middleware-flow.js:2:13:2:21 | express() | src/middleware-flow.js:17:25:17:27 | req | src/middleware-flow.js:17:30:17:32 | res | | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | src/middleware-flow.js:37:22:37:30 | express() | src/middleware-flow.js:39:24:39:26 | req | src/middleware-flow.js:39:29:39:31 | res | @@ -1346,6 +1390,8 @@ test_RouteHandlerExpr_getBody | src/express.js:65:27:69:1 | functio ... res);\\n} | src/express.js:65:27:69:1 | functio ... res);\\n} | | src/express.js:71:23:75:1 | functio ... res);\\n} | src/express.js:71:23:75:1 | functio ... res);\\n} | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/middleware-flow.js:13:16:13:24 | installDb | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | @@ -1466,6 +1512,8 @@ test_RouteSetup_getARouteHandler | src/express.js:65:1:69:2 | app.get ... es);\\n}) | src/express.js:65:27:69:1 | functio ... res);\\n} | | src/express.js:71:1:75:2 | app.get ... es);\\n}) | src/express.js:71:23:75:1 | functio ... res);\\n} | | src/inheritedFromNode.js:4:1:8:2 | app.pos ... url;\\n}) | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/json.js:4:1:6:2 | app.get ... ta);\\n}) | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:8:1:10:2 | app.get ... ta);\\n}) | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/middleware-flow.js:13:5:13:25 | router. ... tallDb) | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | | src/middleware-flow.js:17:5:21:6 | router. ... \\n }) | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | | src/middleware-flow.js:27:9:27:33 | router. ... ers[p]) | src/middleware-flow.js:23:17:23:41 | (req, r ... q.db; } | @@ -1526,6 +1574,8 @@ test_RouteSetup_getRequestMethod | src/express.js:65:1:69:2 | app.get ... es);\\n}) | GET | | src/express.js:71:1:75:2 | app.get ... es);\\n}) | GET | | src/inheritedFromNode.js:4:1:8:2 | app.pos ... url;\\n}) | POST | +| src/json.js:4:1:6:2 | app.get ... ta);\\n}) | GET | +| src/json.js:8:1:10:2 | app.get ... ta);\\n}) | GET | | src/middleware-flow.js:17:5:21:6 | router. ... \\n }) | GET | | src/middleware-flow.js:27:9:27:33 | router. ... ers[p]) | GET | | src/middleware-flow.js:39:1:43:2 | unrelat ... .db;\\n}) | GET | @@ -1699,6 +1749,12 @@ test_RouteHandler_getARequestExpr | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:4:24:4:26 | req | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:4:24:4:26 | req | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:7:2:7:4 | req | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | src/json.js:4:32:4:34 | req | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | src/json.js:4:32:4:34 | req | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | src/json.js:5:14:5:16 | req | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | src/json.js:8:33:8:35 | req | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | src/json.js:8:33:8:35 | req | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | src/json.js:9:15:9:17 | req | | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:5:20:5:22 | req | | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:5:20:5:22 | req | | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:6:5:6:7 | req | @@ -1909,6 +1965,14 @@ test_RouteHandler_getAResponseExpr | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:4:29:4:31 | res | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:5:2:5:4 | res | | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | src/inheritedFromNode.js:6:2:6:4 | res | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | src/json.js:4:37:4:39 | res | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | src/json.js:4:37:4:39 | res | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | src/json.js:5:5:5:7 | res | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | src/json.js:5:5:5:28 | res.jso ... y.data) | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | src/json.js:8:38:8:40 | res | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | src/json.js:8:38:8:40 | res | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | src/json.js:9:5:9:7 | res | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | src/json.js:9:5:9:29 | res.jso ... y.data) | | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | src/middleware-flow.js:5:25:5:27 | res | | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | src/middleware-flow.js:17:30:17:32 | res | | src/middleware-flow.js:23:17:23:41 | (req, r ... q.db; } | src/middleware-flow.js:23:23:23:25 | res | @@ -2041,6 +2105,8 @@ test_RouteSetup_getRouteHandlerExpr | src/express.js:65:1:69:2 | app.get ... es);\\n}) | 0 | src/express.js:65:27:69:1 | functio ... res);\\n} | | src/express.js:71:1:75:2 | app.get ... es);\\n}) | 0 | src/express.js:71:23:75:1 | functio ... res);\\n} | | src/inheritedFromNode.js:4:1:8:2 | app.pos ... url;\\n}) | 0 | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/json.js:4:1:6:2 | app.get ... ta);\\n}) | 0 | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:8:1:10:2 | app.get ... ta);\\n}) | 0 | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/middleware-flow.js:13:5:13:25 | router. ... tallDb) | 0 | src/middleware-flow.js:13:16:13:24 | installDb | | src/middleware-flow.js:17:5:21:6 | router. ... \\n }) | 0 | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | | src/middleware-flow.js:27:9:27:33 | router. ... ers[p]) | 0 | src/middleware-flow.js:27:23:27:32 | routers[p] | @@ -2149,6 +2215,8 @@ test_RouteSetup_getARouteHandlerExpr | src/express.js:65:1:69:2 | app.get ... es);\\n}) | src/express.js:65:27:69:1 | functio ... res);\\n} | | src/express.js:71:1:75:2 | app.get ... es);\\n}) | src/express.js:71:23:75:1 | functio ... res);\\n} | | src/inheritedFromNode.js:4:1:8:2 | app.pos ... url;\\n}) | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/json.js:4:1:6:2 | app.get ... ta);\\n}) | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:8:1:10:2 | app.get ... ta);\\n}) | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/middleware-flow.js:13:5:13:25 | router. ... tallDb) | src/middleware-flow.js:13:16:13:24 | installDb | | src/middleware-flow.js:17:5:21:6 | router. ... \\n }) | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | | src/middleware-flow.js:27:9:27:33 | router. ... ers[p]) | src/middleware-flow.js:27:23:27:32 | routers[p] | @@ -2181,6 +2249,7 @@ test_RouterDefinition_RouterDefinition | src/express4.js:2:11:2:19 | express() | | src/express.js:2:11:2:19 | express() | | src/inheritedFromNode.js:2:11:2:19 | express() | +| src/json.js:2:13:2:21 | express() | | src/middleware-flow.js:2:13:2:21 | express() | | src/middleware-flow.js:37:22:37:30 | express() | | src/params.js:2:11:2:19 | express() | @@ -2216,6 +2285,8 @@ test_RouterDefinition_getARouteHandler | src/express.js:2:11:2:19 | express() | src/express.js:65:27:69:1 | functio ... res);\\n} | | src/express.js:2:11:2:19 | express() | src/express.js:71:23:75:1 | functio ... res);\\n} | | src/inheritedFromNode.js:2:11:2:19 | express() | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/json.js:2:13:2:21 | express() | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:2:13:2:21 | express() | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/middleware-flow.js:2:13:2:21 | express() | src/middleware-flow.js:5:1:10:1 | functio ... xt();\\n} | | src/middleware-flow.js:2:13:2:21 | express() | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | | src/middleware-flow.js:37:22:37:30 | express() | src/middleware-flow.js:39:23:43:1 | (req, r ... s.db;\\n} | @@ -2334,6 +2405,8 @@ test_RouteSetup_getLastRouteHandlerExpr | src/express.js:65:1:69:2 | app.get ... es);\\n}) | src/express.js:65:27:69:1 | functio ... res);\\n} | | src/express.js:71:1:75:2 | app.get ... es);\\n}) | src/express.js:71:23:75:1 | functio ... res);\\n} | | src/inheritedFromNode.js:4:1:8:2 | app.pos ... url;\\n}) | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/json.js:4:1:6:2 | app.get ... ta);\\n}) | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:8:1:10:2 | app.get ... ta);\\n}) | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/middleware-flow.js:13:5:13:25 | router. ... tallDb) | src/middleware-flow.js:13:16:13:24 | installDb | | src/middleware-flow.js:17:5:21:6 | router. ... \\n }) | src/middleware-flow.js:17:24:21:5 | (req, r ... ;\\n } | | src/middleware-flow.js:27:9:27:33 | router. ... ers[p]) | src/middleware-flow.js:27:23:27:32 | routers[p] | From 132a8b8b53bd8ce115d0641c8b11d47a0e0648e2 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 12 Sep 2025 08:46:21 +0200 Subject: [PATCH 007/160] JS: Model json and jsonp methods --- .../semmle/javascript/frameworks/Express.qll | 34 +++++++++++++++++++ .../frameworks/Express/tests.expected | 12 +++++++ 2 files changed, 46 insertions(+) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll index 8c016b3afe9..41e4d1c860c 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll @@ -781,6 +781,40 @@ module Express { override RouteHandler getRouteHandler() { result = response.getRouteHandler() } } + /** + * A call to `res.json()` or `res.jsonp()`. + * + * This sets the `content-type` header. + */ + private class ResponseJsonCall extends DataFlow::MethodCallNode, Http::HeaderDefinition { + private ResponseSource response; + + ResponseJsonCall() { this = response.ref().getAMethodCall(["json", "jsonp"]) } + + override RouteHandler getRouteHandler() { result = response.getRouteHandler() } + + override string getAHeaderName() { result = "content-type" } + + override predicate defines(string headerName, string headerValue) { + // Note: for `jsonp` the actual content-type header will be `text/javascript` or similar, but to avoid + // generating a spurious HTML injection sink, we treat it as `application/json` here. + headerName = "content-type" and headerValue = "application/json" + } + } + + /** + * An argument passed to the `json` or `json` method of an HTTP response object. + */ + private class ResponseJsonCallArgument extends Http::ResponseSendArgument { + ResponseJsonCall call; + + ResponseJsonCallArgument() { this = call.getArgument(0) } + + override RouteHandler getRouteHandler() { result = call.getRouteHandler() } + + override HeaderDefinition getAnAssociatedHeaderDefinition() { result = call } + } + /** * An invocation of the `cookie` method on an HTTP response object. */ diff --git a/javascript/ql/test/library-tests/frameworks/Express/tests.expected b/javascript/ql/test/library-tests/frameworks/Express/tests.expected index 0abc2dbdf95..9007a1ed984 100644 --- a/javascript/ql/test/library-tests/frameworks/Express/tests.expected +++ b/javascript/ql/test/library-tests/frameworks/Express/tests.expected @@ -674,6 +674,8 @@ test_ResponseBody | src/express.js:61:12:61:25 | req.params.foo | src/express.js:59:23:63:1 | functio ... res);\\n} | | src/express.js:67:12:67:25 | req.params.foo | src/express.js:65:27:69:1 | functio ... res);\\n} | | src/express.js:73:12:73:19 | req.path | src/express.js:71:23:75:1 | functio ... res);\\n} | +| src/json.js:5:14:5:27 | req.query.data | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:9:15:9:28 | req.query.data | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/params.js:8:18:8:22 | value | src/params.js:4:18:12:1 | (req, r ... }\\n} | | src/params.js:15:12:15:18 | "Hello" | src/params.js:14:24:16:1 | functio ... lo");\\n} | test_ResponseExpr @@ -1005,6 +1007,8 @@ test_HeaderDefinition | src/express.js:66:3:66:42 | res.hea ... plain") | src/express.js:65:27:69:1 | functio ... res);\\n} | | src/express.js:72:3:72:41 | res.hea ... /html") | src/express.js:71:23:75:1 | functio ... res);\\n} | | src/inheritedFromNode.js:6:2:6:16 | res.setHeader() | src/inheritedFromNode.js:4:15:8:1 | functio ... .url;\\n} | +| src/json.js:5:5:5:28 | res.jso ... y.data) | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:9:5:9:29 | res.jso ... y.data) | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/responseExprs.js:19:5:19:16 | res.append() | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/responseExprs.js:37:5:37:28 | f(res.a ... ppend() | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | | src/responseExprs.js:37:7:37:18 | res.append() | src/responseExprs.js:16:30:42:1 | functio ... }\\n} | @@ -1163,6 +1167,8 @@ test_ResponseSendArgument | src/express.js:61:12:61:25 | req.params.foo | src/express.js:59:23:63:1 | functio ... res);\\n} | | src/express.js:67:12:67:25 | req.params.foo | src/express.js:65:27:69:1 | functio ... res);\\n} | | src/express.js:73:12:73:19 | req.path | src/express.js:71:23:75:1 | functio ... res);\\n} | +| src/json.js:5:14:5:27 | req.query.data | src/json.js:4:23:6:1 | functio ... ata);\\n} | +| src/json.js:9:15:9:28 | req.query.data | src/json.js:8:24:10:1 | functio ... ata);\\n} | | src/params.js:8:18:8:22 | value | src/params.js:4:18:12:1 | (req, r ... }\\n} | | src/params.js:15:12:15:18 | "Hello" | src/params.js:14:24:16:1 | functio ... lo");\\n} | test_RouteSetup_getRouter @@ -1366,6 +1372,8 @@ test_HeaderDefinition_defines | src/express.js:60:3:60:47 | res.hea ... n/xml") | content-type | application/xml | | src/express.js:66:3:66:42 | res.hea ... plain") | content-type | text/plain | | src/express.js:72:3:72:41 | res.hea ... /html") | content-type | text/html | +| src/json.js:5:5:5:28 | res.jso ... y.data) | content-type | application/json | +| src/json.js:9:5:9:29 | res.jso ... y.data) | content-type | application/json | test_RouteHandlerExpr_getBody | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | src/advanced-routehandler-registration.js:51:9:51:60 | (req, r ... tever") | | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | src/advanced-routehandler-registration.js:64:9:64:53 | (req, r ... q, res) | @@ -2139,6 +2147,8 @@ test_HeaderDefinition_getAHeaderName | src/express.js:60:3:60:47 | res.hea ... n/xml") | content-type | | src/express.js:66:3:66:42 | res.hea ... plain") | content-type | | src/express.js:72:3:72:41 | res.hea ... /html") | content-type | +| src/json.js:5:5:5:28 | res.jso ... y.data) | content-type | +| src/json.js:9:5:9:29 | res.jso ... y.data) | content-type | test_RouteHandlerExpr_getAsSubRouter | src/csurf-example.js:13:17:13:19 | api | src/csurf-example.js:30:16:30:35 | new express.Router() | | src/express2.js:6:9:6:14 | router | src/express2.js:2:14:2:23 | e.Router() | @@ -2155,6 +2165,8 @@ test_RouteHandler_getAResponseHeader | src/express.js:65:27:69:1 | functio ... res);\\n} | content-type | src/express.js:66:3:66:42 | res.hea ... plain") | | src/express.js:71:23:75:1 | functio ... res);\\n} | access-control-allow-credentials | src/express.js:12:3:12:54 | arg.hea ... , true) | | src/express.js:71:23:75:1 | functio ... res);\\n} | content-type | src/express.js:72:3:72:41 | res.hea ... /html") | +| src/json.js:4:23:6:1 | functio ... ata);\\n} | content-type | src/json.js:5:5:5:28 | res.jso ... y.data) | +| src/json.js:8:24:10:1 | functio ... ata);\\n} | content-type | src/json.js:9:5:9:29 | res.jso ... y.data) | test_RouteSetup_getARouteHandlerExpr | src/advanced-routehandler-registration.js:10:3:10:24 | app.get ... es0[p]) | src/advanced-routehandler-registration.js:10:14:10:23 | routes0[p] | | src/advanced-routehandler-registration.js:19:3:19:18 | app.use(handler) | src/advanced-routehandler-registration.js:19:11:19:17 | handler | From d295acc3c33268fe10fa5aaf20fde43ef900c59d Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Fri, 12 Sep 2025 19:22:05 -0400 Subject: [PATCH 008/160] Add initial support for Ruby Grape --- ruby/ql/lib/codeql/ruby/Frameworks.qll | 1 + ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 198 ++++++++++++++++++ .../frameworks/grape/Grape.expected | 25 +++ .../library-tests/frameworks/grape/Grape.ql | 18 ++ .../library-tests/frameworks/grape/app.rb | 54 +++++ .../security/cwe-089/ArelInjection.rb | 9 + .../security/cwe-089/SqlInjection.expected | 11 + 7 files changed, 316 insertions(+) create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/Grape.qll create mode 100644 ruby/ql/test/library-tests/frameworks/grape/Grape.expected create mode 100644 ruby/ql/test/library-tests/frameworks/grape/Grape.ql create mode 100644 ruby/ql/test/library-tests/frameworks/grape/app.rb diff --git a/ruby/ql/lib/codeql/ruby/Frameworks.qll b/ruby/ql/lib/codeql/ruby/Frameworks.qll index 9bc01874710..e8009c91b7d 100644 --- a/ruby/ql/lib/codeql/ruby/Frameworks.qll +++ b/ruby/ql/lib/codeql/ruby/Frameworks.qll @@ -21,6 +21,7 @@ private import codeql.ruby.frameworks.Rails private import codeql.ruby.frameworks.Railties private import codeql.ruby.frameworks.Stdlib private import codeql.ruby.frameworks.Files +private import codeql.ruby.frameworks.Grape private import codeql.ruby.frameworks.HttpClients private import codeql.ruby.frameworks.XmlParsing private import codeql.ruby.frameworks.ActionDispatch diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll new file mode 100644 index 00000000000..8e9a062dc9a --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -0,0 +1,198 @@ +/** + * Provides modeling for the `Grape` API framework. + */ + +private import codeql.ruby.AST +private import codeql.ruby.Concepts +private import codeql.ruby.controlflow.CfgNodes +private import codeql.ruby.DataFlow +private import codeql.ruby.dataflow.RemoteFlowSources +private import codeql.ruby.ApiGraphs +private import codeql.ruby.typetracking.TypeTracking +private import codeql.ruby.frameworks.Rails +private import codeql.ruby.frameworks.internal.Rails +private import codeql.ruby.dataflow.internal.DataFlowDispatch + +/** + * Provides modeling for Grape, a REST-like API framework for Ruby. + * Grape allows you to build RESTful APIs in Ruby with minimal effort. + */ +module Grape { + /** + * A Grape API class which sits at the top of the class hierarchy. + * In other words, it does not subclass any other Grape API class in source code. + */ + class RootAPI extends GrapeAPIClass { + RootAPI() { + not exists(GrapeAPIClass parent | this != parent and this = parent.getADescendent()) + } + } +} + +/** + * A class that extends `Grape::API`. + * For example, + * + * ```rb + * class FooAPI < Grape::API + * get '/users' do + * name = params[:name] + * User.where("name = #{name}") + * end + * end + * ``` + */ +class GrapeAPIClass extends DataFlow::ClassNode { + GrapeAPIClass() { + this = grapeAPIBaseClass().getADescendentModule() and + not exists(DataFlow::ModuleNode m | m = grapeAPIBaseClass().asModule() | this = m) + } + + /** + * Gets a `GrapeEndpoint` defined in this class. + */ + GrapeEndpoint getAnEndpoint() { + result.getAPIClass() = this + } + + /** + * Gets a `self` that possibly refers to an instance of this class. + */ + DataFlow::LocalSourceNode getSelf() { + result = this.getAnInstanceSelf() + or + // Include the module-level `self` to recover some cases where a block at the module level + // is invoked with an instance as the `self`. + result = this.getModuleLevelSelf() + } +} + +private DataFlow::ConstRef grapeAPIBaseClass() { + result = DataFlow::getConstant("Grape").getConstant("API") +} + +private API::Node grapeAPIInstance() { + result = any(GrapeAPIClass cls).getSelf().track() +} + +/** + * A Grape API endpoint (get, post, put, delete, etc.) call within a `Grape::API` class. + */ +class GrapeEndpoint extends DataFlow::CallNode { + private GrapeAPIClass apiClass; + + GrapeEndpoint() { + this = apiClass.getAModuleLevelCall(["get", "post", "put", "delete", "patch", "head", "options"]) + } + + /** + * Gets the HTTP method for this endpoint (e.g., "GET", "POST", etc.) + */ + string getHttpMethod() { + result = this.getMethodName().toUpperCase() + } + + /** + * Gets the API class containing this endpoint. + */ + GrapeAPIClass getAPIClass() { result = apiClass } + + /** + * Gets the block containing the endpoint logic. + */ + DataFlow::BlockNode getBody() { result = this.getBlock() } + + /** + * Gets the path pattern for this endpoint, if specified. + */ + string getPath() { + result = this.getArgument(0).getConstantValue().getString() + } +} + +/** + * A `RemoteFlowSource::Range` to represent accessing the + * Grape parameters available via the `params` method within an endpoint. + */ +class GrapeParamsSource extends Http::Server::RequestInputAccess::Range { + GrapeParamsSource() { + this.asExpr().getExpr() instanceof GrapeParamsCall + } + + override string getSourceType() { result = "Grape::API#params" } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::parameterInputKind() } +} + +/** + * A call to `params` from within a Grape API endpoint. + */ +private class GrapeParamsCall extends ParamsCallImpl { + GrapeParamsCall() { + exists(GrapeEndpoint endpoint | + this.getParent+() = endpoint.getBody().asCallableAstNode() and + this.getMethodName() = "params" + ) + or + // Also handle cases where params is called on an instance of a Grape API class + this = grapeAPIInstance().getAMethodCall("params").asExpr().getExpr() + } +} + +/** + * A call to `headers` from within a Grape API endpoint. + * Headers can also be a source of user input. + */ +class GrapeHeadersSource extends Http::Server::RequestInputAccess::Range { + GrapeHeadersSource() { + this.asExpr().getExpr() instanceof GrapeHeadersCall + } + + override string getSourceType() { result = "Grape::API#headers" } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() } +} + +/** + * A call to `headers` from within a Grape API endpoint. + */ +private class GrapeHeadersCall extends MethodCall { + GrapeHeadersCall() { + exists(GrapeEndpoint endpoint | + this.getParent+() = endpoint.getBody().asCallableAstNode() and + this.getMethodName() = "headers" + ) + or + // Also handle cases where headers is called on an instance of a Grape API class + this = grapeAPIInstance().getAMethodCall("headers").asExpr().getExpr() + } +} + +/** + * A call to `request` from within a Grape API endpoint. + * The request object can contain user input. + */ +class GrapeRequestSource extends Http::Server::RequestInputAccess::Range { + GrapeRequestSource() { + this.asExpr().getExpr() instanceof GrapeRequestCall + } + + override string getSourceType() { result = "Grape::API#request" } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::parameterInputKind() } +} + +/** + * A call to `request` from within a Grape API endpoint. + */ +private class GrapeRequestCall extends MethodCall { + GrapeRequestCall() { + exists(GrapeEndpoint endpoint | + this.getParent+() = endpoint.getBody().asCallableAstNode() and + this.getMethodName() = "request" + ) + or + // Also handle cases where request is called on an instance of a Grape API class + this = grapeAPIInstance().getAMethodCall("request").asExpr().getExpr() + } +} \ No newline at end of file diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.expected b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected new file mode 100644 index 00000000000..904cb36333a --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected @@ -0,0 +1,25 @@ +grapeAPIClasses +| app.rb:1:1:48:3 | MyAPI | +| app.rb:50:1:54:3 | AdminAPI | +grapeEndpoints +| app.rb:1:1:48:3 | MyAPI | app.rb:7:3:11:5 | call to get | GET | /hello/:name | +| app.rb:1:1:48:3 | MyAPI | app.rb:17:3:20:5 | call to post | POST | /messages | +| app.rb:1:1:48:3 | MyAPI | app.rb:23:3:27:5 | call to put | PUT | /update/:id | +| app.rb:1:1:48:3 | MyAPI | app.rb:30:3:32:5 | call to delete | DELETE | /items/:id | +| app.rb:1:1:48:3 | MyAPI | app.rb:35:3:37:5 | call to patch | PATCH | /items/:id | +| app.rb:1:1:48:3 | MyAPI | app.rb:40:3:42:5 | call to head | HEAD | /status | +| app.rb:1:1:48:3 | MyAPI | app.rb:45:3:47:5 | call to options | OPTIONS | /info | +| app.rb:50:1:54:3 | AdminAPI | app.rb:51:3:53:5 | call to get | GET | /admin | +grapeParams +| app.rb:8:12:8:17 | call to params | +| app.rb:14:3:16:5 | call to params | +| app.rb:18:11:18:16 | call to params | +| app.rb:24:10:24:15 | call to params | +| app.rb:31:5:31:10 | call to params | +| app.rb:36:5:36:10 | call to params | +| app.rb:52:5:52:10 | call to params | +grapeHeaders +| app.rb:9:18:9:24 | call to headers | +| app.rb:46:5:46:11 | call to headers | +grapeRequest +| app.rb:25:12:25:18 | call to request | \ No newline at end of file diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql new file mode 100644 index 00000000000..a35c639d9ad --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql @@ -0,0 +1,18 @@ +import ruby +import codeql.ruby.frameworks.Grape +import codeql.ruby.Concepts +import codeql.ruby.AST + +query predicate grapeAPIClasses(GrapeAPIClass api) { any() } + +query predicate grapeEndpoints(GrapeAPIClass api, GrapeEndpoint endpoint, string method, string path) { + endpoint = api.getAnEndpoint() and + method = endpoint.getHttpMethod() and + path = endpoint.getPath() +} + +query predicate grapeParams(GrapeParamsSource params) { any() } + +query predicate grapeHeaders(GrapeHeadersSource headers) { any() } + +query predicate grapeRequest(GrapeRequestSource request) { any() } \ No newline at end of file diff --git a/ruby/ql/test/library-tests/frameworks/grape/app.rb b/ruby/ql/test/library-tests/frameworks/grape/app.rb new file mode 100644 index 00000000000..3e33caa85e9 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/grape/app.rb @@ -0,0 +1,54 @@ +class MyAPI < Grape::API + version 'v1', using: :header, vendor: 'myapi' + format :json + prefix :api + + desc 'Simple get endpoint' + get '/hello/:name' do + name = params[:name] + user_agent = headers['User-Agent'] + "Hello #{name}!" + end + + desc 'Post endpoint with params' + params do + requires :message, type: String + end + post '/messages' do + msg = params[:message] + { status: 'received', message: msg } + end + + desc 'Put endpoint accessing request' + put '/update/:id' do + id = params[:id] + body = request.body.read + { id: id, body: body } + end + + desc 'Delete endpoint' + delete '/items/:id' do + params[:id] + end + + desc 'Patch endpoint' + patch '/items/:id' do + params[:id] + end + + desc 'Head endpoint' + head '/status' do + # Just return status + end + + desc 'Options endpoint' + options '/info' do + headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS' + end +end + +class AdminAPI < Grape::API + get '/admin' do + params[:token] + end +end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb index 1cd6782b241..30832894b9e 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb +++ b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb @@ -6,4 +6,13 @@ class PotatoController < ActionController::Base sql = Arel.sql("SELECT * FROM users WHERE name = #{name}") sql = Arel::Nodes::SqlLiteral.new("SELECT * FROM users WHERE name = #{name}") end +end + +class PotatoAPI < Grape::API + get '/unsafe_endpoint' do + name = params[:user_name] + # BAD: SQL statement constructed from user input + sql = Arel.sql("SELECT * FROM users WHERE name = #{name}") + sql = Arel::Nodes::SqlLiteral.new("SELECT * FROM users WHERE name = #{name}") + end end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected index 069cb34810f..b8b1350882d 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected @@ -81,6 +81,10 @@ edges | ArelInjection.rb:4:5:4:8 | name | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | provenance | AdditionalTaintStep | | ArelInjection.rb:4:12:4:17 | call to params | ArelInjection.rb:4:12:4:29 | ...[...] | provenance | | | ArelInjection.rb:4:12:4:29 | ...[...] | ArelInjection.rb:4:5:4:8 | name | provenance | | +| ArelInjection.rb:13:5:13:8 | name | ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | provenance | AdditionalTaintStep | +| ArelInjection.rb:13:5:13:8 | name | ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | provenance | AdditionalTaintStep | +| ArelInjection.rb:13:12:13:17 | call to params | ArelInjection.rb:13:12:13:29 | ...[...] | provenance | | +| ArelInjection.rb:13:12:13:29 | ...[...] | ArelInjection.rb:13:5:13:8 | name | provenance | | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:13:5:13:8 | qry1 : String | provenance | AdditionalTaintStep | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:19:5:19:8 | qry2 : String | provenance | AdditionalTaintStep | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:31:5:31:8 | qry3 : String | provenance | AdditionalTaintStep | @@ -209,6 +213,11 @@ nodes | ArelInjection.rb:4:12:4:29 | ...[...] | semmle.label | ...[...] | | ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | +| ArelInjection.rb:13:5:13:8 | name | semmle.label | name | +| ArelInjection.rb:13:12:13:17 | call to params | semmle.label | call to params | +| ArelInjection.rb:13:12:13:29 | ...[...] | semmle.label | ...[...] | +| ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | +| ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | | PgInjection.rb:6:5:6:8 | name | semmle.label | name | | PgInjection.rb:6:12:6:17 | call to params | semmle.label | call to params | | PgInjection.rb:6:12:6:24 | ...[...] | semmle.label | ...[...] | @@ -266,6 +275,8 @@ subpaths | ActiveRecordInjection.rb:216:38:216:53 | "role = #{...}" | ActiveRecordInjection.rb:222:29:222:34 | call to params | ActiveRecordInjection.rb:216:38:216:53 | "role = #{...}" | This SQL query depends on a $@. | ActiveRecordInjection.rb:222:29:222:34 | call to params | user-provided value | | ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:4:12:4:17 | call to params | ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:4:12:4:17 | call to params | user-provided value | | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:4:12:4:17 | call to params | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:4:12:4:17 | call to params | user-provided value | +| ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:13:12:13:17 | call to params | ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:13:12:13:17 | call to params | user-provided value | +| ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:13:12:13:17 | call to params | ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:13:12:13:17 | call to params | user-provided value | | PgInjection.rb:14:15:14:18 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:14:15:14:18 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | | PgInjection.rb:15:21:15:24 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:15:21:15:24 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | | PgInjection.rb:20:22:20:25 | qry2 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:20:22:20:25 | qry2 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | From 738ab6fba7ff64b97c60cf7f2593f136c5bf0f04 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Fri, 12 Sep 2025 19:23:15 -0400 Subject: [PATCH 009/160] Refactor Grape framework code for improved readability and consistency --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 2 +- .../test/library-tests/frameworks/grape/Grape.ql | 2 +- .../test/library-tests/frameworks/grape/app.rb | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index 8e9a062dc9a..857b849f425 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -115,7 +115,7 @@ class GrapeEndpoint extends DataFlow::CallNode { * Grape parameters available via the `params` method within an endpoint. */ class GrapeParamsSource extends Http::Server::RequestInputAccess::Range { - GrapeParamsSource() { + GrapeParamsSource() { this.asExpr().getExpr() instanceof GrapeParamsCall } diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql index a35c639d9ad..3dd7c488a49 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql @@ -5,7 +5,7 @@ import codeql.ruby.AST query predicate grapeAPIClasses(GrapeAPIClass api) { any() } -query predicate grapeEndpoints(GrapeAPIClass api, GrapeEndpoint endpoint, string method, string path) { +query predicate grapeEndpoints(GrapeAPIClass api, GrapeEndpoint endpoint, string method, string path) { endpoint = api.getAnEndpoint() and method = endpoint.getHttpMethod() and path = endpoint.getPath() diff --git a/ruby/ql/test/library-tests/frameworks/grape/app.rb b/ruby/ql/test/library-tests/frameworks/grape/app.rb index 3e33caa85e9..6333240debe 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/app.rb +++ b/ruby/ql/test/library-tests/frameworks/grape/app.rb @@ -9,7 +9,7 @@ class MyAPI < Grape::API user_agent = headers['User-Agent'] "Hello #{name}!" end - + desc 'Post endpoint with params' params do requires :message, type: String @@ -18,36 +18,36 @@ class MyAPI < Grape::API msg = params[:message] { status: 'received', message: msg } end - + desc 'Put endpoint accessing request' put '/update/:id' do id = params[:id] body = request.body.read { id: id, body: body } end - - desc 'Delete endpoint' + + desc 'Delete endpoint' delete '/items/:id' do params[:id] end - + desc 'Patch endpoint' patch '/items/:id' do params[:id] end - + desc 'Head endpoint' head '/status' do # Just return status end - + desc 'Options endpoint' options '/info' do headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS' end end -class AdminAPI < Grape::API +class AdminAPI < Grape::API get '/admin' do params[:token] end From 3252bd39d2e671710e94ada3adaae1cefb1deaf1 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Fri, 12 Sep 2025 22:13:21 -0400 Subject: [PATCH 010/160] Enhance Grape framework with additional data flow modeling and helper method support --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 57 +++++++++++++++---- .../frameworks/grape/Grape.expected | 2 +- .../security/cwe-089/ArelInjection.rb | 25 +++++++- .../security/cwe-089/SqlInjection.expected | 20 +++++++ 4 files changed, 92 insertions(+), 12 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index 857b849f425..a3aa2f684c7 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -12,6 +12,7 @@ private import codeql.ruby.typetracking.TypeTracking private import codeql.ruby.frameworks.Rails private import codeql.ruby.frameworks.internal.Rails private import codeql.ruby.dataflow.internal.DataFlowDispatch +private import codeql.ruby.dataflow.FlowSteps /** * Provides modeling for Grape, a REST-like API framework for Ruby. @@ -125,21 +126,17 @@ class GrapeParamsSource extends Http::Server::RequestInputAccess::Range { } /** - * A call to `params` from within a Grape API endpoint. + * A call to `params` from within a Grape API endpoint or helper method. */ private class GrapeParamsCall extends ParamsCallImpl { GrapeParamsCall() { - exists(GrapeEndpoint endpoint | - this.getParent+() = endpoint.getBody().asCallableAstNode() and - this.getMethodName() = "params" + // Simplified approach: find params calls that are descendants of Grape API class methods + exists(GrapeAPIClass api | + this.getMethodName() = "params" and + this.getParent+() = api.getADeclaration() ) - or - // Also handle cases where params is called on an instance of a Grape API class - this = grapeAPIInstance().getAMethodCall("params").asExpr().getExpr() } -} - -/** +}/** * A call to `headers` from within a Grape API endpoint. * Headers can also be a source of user input. */ @@ -195,4 +192,44 @@ private class GrapeRequestCall extends MethodCall { // Also handle cases where request is called on an instance of a Grape API class this = grapeAPIInstance().getAMethodCall("request").asExpr().getExpr() } +} + +/** + * A method defined within a `helpers` block in a Grape API class. + * These methods become available in endpoint contexts through Grape's DSL. + */ +private class GrapeHelperMethod extends Method { + private GrapeAPIClass apiClass; + + GrapeHelperMethod() { + exists(DataFlow::CallNode helpersCall | + helpersCall = apiClass.getAModuleLevelCall("helpers") and + this.getParent+() = helpersCall.getBlock().asExpr().getExpr() + ) + } + + /** + * Gets the API class that contains this helper method. + */ + GrapeAPIClass getAPIClass() { result = apiClass } +} + +/** + * Additional taint step to model dataflow from method arguments to parameters + * for Grape helper methods defined in `helpers` blocks. + * This bridges the gap where standard dataflow doesn't recognize the Grape DSL semantics. + */ +private class GrapeHelperMethodTaintStep extends AdditionalTaintStep { + override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + exists(GrapeHelperMethod helperMethod, MethodCall call, int i | + // Find calls to helper methods from within Grape endpoints + call.getMethodName() = helperMethod.getName() and + exists(GrapeEndpoint endpoint | + call.getParent+() = endpoint.getBody().asExpr().getExpr() + ) and + // Map argument to parameter + nodeFrom.asExpr().getExpr() = call.getArgument(i) and + nodeTo.asParameter() = helperMethod.getParameter(i) + ) + } } \ No newline at end of file diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.expected b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected index 904cb36333a..7e792465911 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Grape.expected +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected @@ -22,4 +22,4 @@ grapeHeaders | app.rb:9:18:9:24 | call to headers | | app.rb:46:5:46:11 | call to headers | grapeRequest -| app.rb:25:12:25:18 | call to request | \ No newline at end of file +| app.rb:25:12:25:18 | call to request | diff --git a/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb index 30832894b9e..cf0769c0acd 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb +++ b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb @@ -15,4 +15,27 @@ class PotatoAPI < Grape::API sql = Arel.sql("SELECT * FROM users WHERE name = #{name}") sql = Arel::Nodes::SqlLiteral.new("SELECT * FROM users WHERE name = #{name}") end -end \ No newline at end of file +end + +class SimpleAPI < Grape::API + get '/test' do + x = params[:name] + Arel.sql("SELECT * FROM users WHERE name = #{x}") + end +end + + # Test helper method pattern in Grape helpers block + class TestAPI < Grape::API + helpers do + def vulnerable_helper(user_id) + # BAD: SQL statement constructed from user input passed as parameter + Arel.sql("SELECT * FROM users WHERE id = #{user_id}") + end + end + + get '/helper_test' do + # This should be detected as SQL injection via helper method + user_id = params[:user_id] + vulnerable_helper(user_id) + end + end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected index b8b1350882d..0b14504058e 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected @@ -85,6 +85,14 @@ edges | ArelInjection.rb:13:5:13:8 | name | ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | provenance | AdditionalTaintStep | | ArelInjection.rb:13:12:13:17 | call to params | ArelInjection.rb:13:12:13:29 | ...[...] | provenance | | | ArelInjection.rb:13:12:13:29 | ...[...] | ArelInjection.rb:13:5:13:8 | name | provenance | | +| ArelInjection.rb:22:5:22:5 | x | ArelInjection.rb:23:14:23:52 | "SELECT * FROM users WHERE nam..." | provenance | AdditionalTaintStep | +| ArelInjection.rb:22:9:22:14 | call to params | ArelInjection.rb:22:9:22:21 | ...[...] | provenance | | +| ArelInjection.rb:22:9:22:21 | ...[...] | ArelInjection.rb:22:5:22:5 | x | provenance | | +| ArelInjection.rb:30:29:30:35 | user_id | ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | +| ArelInjection.rb:38:7:38:13 | user_id | ArelInjection.rb:39:25:39:31 | user_id | provenance | | +| ArelInjection.rb:38:17:38:22 | call to params | ArelInjection.rb:38:17:38:32 | ...[...] | provenance | | +| ArelInjection.rb:38:17:38:32 | ...[...] | ArelInjection.rb:38:7:38:13 | user_id | provenance | | +| ArelInjection.rb:39:25:39:31 | user_id | ArelInjection.rb:30:29:30:35 | user_id | provenance | AdditionalTaintStep | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:13:5:13:8 | qry1 : String | provenance | AdditionalTaintStep | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:19:5:19:8 | qry2 : String | provenance | AdditionalTaintStep | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:31:5:31:8 | qry3 : String | provenance | AdditionalTaintStep | @@ -218,6 +226,16 @@ nodes | ArelInjection.rb:13:12:13:29 | ...[...] | semmle.label | ...[...] | | ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | | ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | +| ArelInjection.rb:22:5:22:5 | x | semmle.label | x | +| ArelInjection.rb:22:9:22:14 | call to params | semmle.label | call to params | +| ArelInjection.rb:22:9:22:21 | ...[...] | semmle.label | ...[...] | +| ArelInjection.rb:23:14:23:52 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | +| ArelInjection.rb:30:29:30:35 | user_id | semmle.label | user_id | +| ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | semmle.label | "SELECT * FROM users WHERE id ..." | +| ArelInjection.rb:38:7:38:13 | user_id | semmle.label | user_id | +| ArelInjection.rb:38:17:38:22 | call to params | semmle.label | call to params | +| ArelInjection.rb:38:17:38:32 | ...[...] | semmle.label | ...[...] | +| ArelInjection.rb:39:25:39:31 | user_id | semmle.label | user_id | | PgInjection.rb:6:5:6:8 | name | semmle.label | name | | PgInjection.rb:6:12:6:17 | call to params | semmle.label | call to params | | PgInjection.rb:6:12:6:24 | ...[...] | semmle.label | ...[...] | @@ -277,6 +295,8 @@ subpaths | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:4:12:4:17 | call to params | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:4:12:4:17 | call to params | user-provided value | | ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:13:12:13:17 | call to params | ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:13:12:13:17 | call to params | user-provided value | | ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:13:12:13:17 | call to params | ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:13:12:13:17 | call to params | user-provided value | +| ArelInjection.rb:23:14:23:52 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:22:9:22:14 | call to params | ArelInjection.rb:23:14:23:52 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:22:9:22:14 | call to params | user-provided value | +| ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:38:17:38:22 | call to params | ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:38:17:38:22 | call to params | user-provided value | | PgInjection.rb:14:15:14:18 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:14:15:14:18 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | | PgInjection.rb:15:21:15:24 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:15:21:15:24 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | | PgInjection.rb:20:22:20:25 | qry2 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:20:22:20:25 | qry2 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | From 5cfa6e83b390aafe6783eba0e282674a8247db46 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Fri, 12 Sep 2025 22:51:47 -0400 Subject: [PATCH 011/160] Add support for route parameters(+ blocks), headers, and cookies in Grape API --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 92 ++++++++++++++++++- .../frameworks/grape/Grape.expected | 37 +++++--- .../library-tests/frameworks/grape/Grape.ql | 6 +- .../library-tests/frameworks/grape/app.rb | 42 +++++++++ .../security/cwe-089/ArelInjection.rb | 32 ++++++- .../security/cwe-089/SqlInjection.expected | 53 +++++++++-- 6 files changed, 239 insertions(+), 23 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index a3aa2f684c7..fbab28180b8 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -137,12 +137,14 @@ private class GrapeParamsCall extends ParamsCallImpl { ) } }/** - * A call to `headers` from within a Grape API endpoint. + * A call to `headers` from within a Grape API endpoint or headers block. * Headers can also be a source of user input. */ class GrapeHeadersSource extends Http::Server::RequestInputAccess::Range { GrapeHeadersSource() { this.asExpr().getExpr() instanceof GrapeHeadersCall + or + this.asExpr().getExpr() instanceof GrapeHeadersBlockCall } override string getSourceType() { result = "Grape::API#headers" } @@ -179,6 +181,20 @@ class GrapeRequestSource extends Http::Server::RequestInputAccess::Range { override Http::Server::RequestInputKind getKind() { result = Http::Server::parameterInputKind() } } +/** + * A call to `route_param` from within a Grape API endpoint. + * Route parameters are extracted from the URL path and can be a source of user input. + */ +class GrapeRouteParamSource extends Http::Server::RequestInputAccess::Range { + GrapeRouteParamSource() { + this.asExpr().getExpr() instanceof GrapeRouteParamCall + } + + override string getSourceType() { result = "Grape::API#route_param" } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::parameterInputKind() } +} + /** * A call to `request` from within a Grape API endpoint. */ @@ -194,6 +210,80 @@ private class GrapeRequestCall extends MethodCall { } } +/** + * A call to `route_param` from within a Grape API endpoint. + */ +private class GrapeRouteParamCall extends MethodCall { + GrapeRouteParamCall() { + exists(GrapeEndpoint endpoint | + this.getParent+() = endpoint.getBody().asExpr().getExpr() and + this.getMethodName() = "route_param" + ) + or + // Also handle cases where route_param is called on an instance of a Grape API class + this = grapeAPIInstance().getAMethodCall("route_param").asExpr().getExpr() + } +} + +/** + * A call to `headers` block within a Grape API class. + * This is different from the headers() method call - this is the DSL block for defining header requirements. + */ +private class GrapeHeadersBlockCall extends MethodCall { + GrapeHeadersBlockCall() { + exists(GrapeAPIClass api | + this.getParent+() = api.getADeclaration() and + this.getMethodName() = "headers" and + exists(this.getBlock()) + ) + } +} + +/** + * A call to `cookies` block within a Grape API class. + * This DSL block defines cookie requirements and those cookies are user-controlled. + */ +private class GrapeCookiesBlockCall extends MethodCall { + GrapeCookiesBlockCall() { + exists(GrapeAPIClass api | + this.getParent+() = api.getADeclaration() and + this.getMethodName() = "cookies" and + exists(this.getBlock()) + ) + } +} + +/** + * A call to `cookies` method from within a Grape API endpoint or cookies block. + * Similar to headers, cookies can be accessed as a method and are user-controlled input. + */ +class GrapeCookiesSource extends Http::Server::RequestInputAccess::Range { + GrapeCookiesSource() { + this.asExpr().getExpr() instanceof GrapeCookiesCall + or + this.asExpr().getExpr() instanceof GrapeCookiesBlockCall + } + + override string getSourceType() { result = "Grape::API#cookies" } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::cookieInputKind() } +} + +/** + * A call to `cookies` method from within a Grape API endpoint. + */ +private class GrapeCookiesCall extends MethodCall { + GrapeCookiesCall() { + exists(GrapeEndpoint endpoint | + this.getParent+() = endpoint.getBody().asCallableAstNode() and + this.getMethodName() = "cookies" + ) + or + // Also handle cases where cookies is called on an instance of a Grape API class + this = grapeAPIInstance().getAMethodCall("cookies").asExpr().getExpr() + } +} + /** * A method defined within a `helpers` block in a Grape API class. * These methods become available in endpoint contexts through Grape's DSL. diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.expected b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected index 7e792465911..c0bee75371c 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Grape.expected +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected @@ -1,15 +1,18 @@ grapeAPIClasses -| app.rb:1:1:48:3 | MyAPI | -| app.rb:50:1:54:3 | AdminAPI | +| app.rb:1:1:90:3 | MyAPI | +| app.rb:92:1:96:3 | AdminAPI | grapeEndpoints -| app.rb:1:1:48:3 | MyAPI | app.rb:7:3:11:5 | call to get | GET | /hello/:name | -| app.rb:1:1:48:3 | MyAPI | app.rb:17:3:20:5 | call to post | POST | /messages | -| app.rb:1:1:48:3 | MyAPI | app.rb:23:3:27:5 | call to put | PUT | /update/:id | -| app.rb:1:1:48:3 | MyAPI | app.rb:30:3:32:5 | call to delete | DELETE | /items/:id | -| app.rb:1:1:48:3 | MyAPI | app.rb:35:3:37:5 | call to patch | PATCH | /items/:id | -| app.rb:1:1:48:3 | MyAPI | app.rb:40:3:42:5 | call to head | HEAD | /status | -| app.rb:1:1:48:3 | MyAPI | app.rb:45:3:47:5 | call to options | OPTIONS | /info | -| app.rb:50:1:54:3 | AdminAPI | app.rb:51:3:53:5 | call to get | GET | /admin | +| app.rb:1:1:90:3 | MyAPI | app.rb:7:3:11:5 | call to get | GET | /hello/:name | +| app.rb:1:1:90:3 | MyAPI | app.rb:17:3:20:5 | call to post | POST | /messages | +| app.rb:1:1:90:3 | MyAPI | app.rb:23:3:27:5 | call to put | PUT | /update/:id | +| app.rb:1:1:90:3 | MyAPI | app.rb:30:3:32:5 | call to delete | DELETE | /items/:id | +| app.rb:1:1:90:3 | MyAPI | app.rb:35:3:37:5 | call to patch | PATCH | /items/:id | +| app.rb:1:1:90:3 | MyAPI | app.rb:40:3:42:5 | call to head | HEAD | /status | +| app.rb:1:1:90:3 | MyAPI | app.rb:45:3:47:5 | call to options | OPTIONS | /info | +| app.rb:1:1:90:3 | MyAPI | app.rb:50:3:54:5 | call to get | GET | /users/:user_id/posts/:post_id | +| app.rb:1:1:90:3 | MyAPI | app.rb:78:3:82:5 | call to get | GET | /cookie_test | +| app.rb:1:1:90:3 | MyAPI | app.rb:85:3:89:5 | call to get | GET | /header_test | +| app.rb:92:1:96:3 | AdminAPI | app.rb:93:3:95:5 | call to get | GET | /admin | grapeParams | app.rb:8:12:8:17 | call to params | | app.rb:14:3:16:5 | call to params | @@ -17,9 +20,21 @@ grapeParams | app.rb:24:10:24:15 | call to params | | app.rb:31:5:31:10 | call to params | | app.rb:36:5:36:10 | call to params | -| app.rb:52:5:52:10 | call to params | +| app.rb:60:12:60:17 | call to params | +| app.rb:94:5:94:10 | call to params | grapeHeaders | app.rb:9:18:9:24 | call to headers | | app.rb:46:5:46:11 | call to headers | +| app.rb:66:3:69:5 | call to headers | +| app.rb:86:12:86:18 | call to headers | +| app.rb:87:14:87:20 | call to headers | grapeRequest | app.rb:25:12:25:18 | call to request | +grapeRouteParam +| app.rb:51:15:51:35 | call to route_param | +| app.rb:52:15:52:36 | call to route_param | +| app.rb:57:3:63:5 | call to route_param | +grapeCookies +| app.rb:72:3:75:5 | call to cookies | +| app.rb:79:15:79:21 | call to cookies | +| app.rb:80:16:80:22 | call to cookies | diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql index 3dd7c488a49..63d59d0bdd7 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql @@ -15,4 +15,8 @@ query predicate grapeParams(GrapeParamsSource params) { any() } query predicate grapeHeaders(GrapeHeadersSource headers) { any() } -query predicate grapeRequest(GrapeRequestSource request) { any() } \ No newline at end of file +query predicate grapeRequest(GrapeRequestSource request) { any() } + +query predicate grapeRouteParam(GrapeRouteParamSource routeParam) { any() } + +query predicate grapeCookies(GrapeCookiesSource cookies) { any() } \ No newline at end of file diff --git a/ruby/ql/test/library-tests/frameworks/grape/app.rb b/ruby/ql/test/library-tests/frameworks/grape/app.rb index 6333240debe..a034f325f7b 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/app.rb +++ b/ruby/ql/test/library-tests/frameworks/grape/app.rb @@ -45,6 +45,48 @@ class MyAPI < Grape::API options '/info' do headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS' end + + desc 'Route param endpoint' + get '/users/:user_id/posts/:post_id' do + user_id = route_param(:user_id) + post_id = route_param('post_id') + { user_id: user_id, post_id: post_id } + end + + desc 'Route param block pattern' + route_param :id do + get do + # params[:id] is user input from the path parameter + id = params[:id] + { id: id } + end + end + + # Headers block for defining expected headers + headers do + requires :Authorization, type: String + optional 'X-Custom-Header', type: String + end + + # Cookies block for defining expected cookies + cookies do + requires :session_id, type: String + optional :tracking_id, type: String + end + + desc 'Endpoint that uses cookies method' + get '/cookie_test' do + session = cookies[:session_id] + tracking = cookies['tracking_id'] + { session: session, tracking: tracking } + end + + desc 'Endpoint that uses headers method' + get '/header_test' do + auth = headers[:Authorization] + custom = headers['X-Custom-Header'] + { auth: auth, custom: custom } + end end class AdminAPI < Grape::API diff --git a/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb index cf0769c0acd..8c9c3bff4fb 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb +++ b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb @@ -33,9 +33,39 @@ end end end + # Headers and cookies blocks for DSL testing + headers do + requires :Authorization, type: String + end + + cookies do + requires :session_id, type: String + end + + get '/comprehensive_test/:user_id' do + # BAD: Comprehensive test using all Grape input sources in one SQL query + user_id = params[:user_id] # params taint source + route_id = route_param(:user_id) # route_param taint source + auth = headers[:Authorization] # headers taint source + session = cookies[:session_id] # cookies taint source + body_data = request.body.read # request taint source + + # All sources flow to SQL injection + Arel.sql("SELECT * FROM users WHERE id = #{user_id} AND route_id = #{route_id} AND auth = #{auth} AND session = #{session} AND data = #{body_data}") + end + get '/helper_test' do - # This should be detected as SQL injection via helper method + # BAD: Test helper method dataflow user_id = params[:user_id] vulnerable_helper(user_id) end + + # Test route_param block pattern + route_param :id do + get do + # BAD: params[:id] should be user input from the path + user_id = params[:id] + Arel.sql("SELECT * FROM users WHERE id = #{user_id}") + end + end end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected index 0b14504058e..34128474cb9 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected @@ -89,10 +89,24 @@ edges | ArelInjection.rb:22:9:22:14 | call to params | ArelInjection.rb:22:9:22:21 | ...[...] | provenance | | | ArelInjection.rb:22:9:22:21 | ...[...] | ArelInjection.rb:22:5:22:5 | x | provenance | | | ArelInjection.rb:30:29:30:35 | user_id | ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | -| ArelInjection.rb:38:7:38:13 | user_id | ArelInjection.rb:39:25:39:31 | user_id | provenance | | -| ArelInjection.rb:38:17:38:22 | call to params | ArelInjection.rb:38:17:38:32 | ...[...] | provenance | | -| ArelInjection.rb:38:17:38:32 | ...[...] | ArelInjection.rb:38:7:38:13 | user_id | provenance | | -| ArelInjection.rb:39:25:39:31 | user_id | ArelInjection.rb:30:29:30:35 | user_id | provenance | AdditionalTaintStep | +| ArelInjection.rb:47:7:47:13 | user_id | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | +| ArelInjection.rb:47:17:47:22 | call to params | ArelInjection.rb:47:17:47:32 | ...[...] | provenance | | +| ArelInjection.rb:47:17:47:32 | ...[...] | ArelInjection.rb:47:7:47:13 | user_id | provenance | | +| ArelInjection.rb:48:7:48:14 | route_id | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | +| ArelInjection.rb:48:18:48:38 | call to route_param | ArelInjection.rb:48:7:48:14 | route_id | provenance | | +| ArelInjection.rb:49:7:49:10 | auth | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | +| ArelInjection.rb:49:14:49:20 | call to headers | ArelInjection.rb:49:14:49:36 | ...[...] | provenance | | +| ArelInjection.rb:49:14:49:36 | ...[...] | ArelInjection.rb:49:7:49:10 | auth | provenance | | +| ArelInjection.rb:50:7:50:13 | session | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | +| ArelInjection.rb:50:17:50:23 | call to cookies | ArelInjection.rb:50:17:50:36 | ...[...] | provenance | | +| ArelInjection.rb:50:17:50:36 | ...[...] | ArelInjection.rb:50:7:50:13 | session | provenance | | +| ArelInjection.rb:59:7:59:13 | user_id | ArelInjection.rb:60:25:60:31 | user_id | provenance | | +| ArelInjection.rb:59:17:59:22 | call to params | ArelInjection.rb:59:17:59:32 | ...[...] | provenance | | +| ArelInjection.rb:59:17:59:32 | ...[...] | ArelInjection.rb:59:7:59:13 | user_id | provenance | | +| ArelInjection.rb:60:25:60:31 | user_id | ArelInjection.rb:30:29:30:35 | user_id | provenance | AdditionalTaintStep | +| ArelInjection.rb:67:9:67:15 | user_id | ArelInjection.rb:68:18:68:60 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | +| ArelInjection.rb:67:19:67:24 | call to params | ArelInjection.rb:67:19:67:29 | ...[...] | provenance | | +| ArelInjection.rb:67:19:67:29 | ...[...] | ArelInjection.rb:67:9:67:15 | user_id | provenance | | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:13:5:13:8 | qry1 : String | provenance | AdditionalTaintStep | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:19:5:19:8 | qry2 : String | provenance | AdditionalTaintStep | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:31:5:31:8 | qry3 : String | provenance | AdditionalTaintStep | @@ -232,10 +246,26 @@ nodes | ArelInjection.rb:23:14:23:52 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | | ArelInjection.rb:30:29:30:35 | user_id | semmle.label | user_id | | ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | semmle.label | "SELECT * FROM users WHERE id ..." | -| ArelInjection.rb:38:7:38:13 | user_id | semmle.label | user_id | -| ArelInjection.rb:38:17:38:22 | call to params | semmle.label | call to params | -| ArelInjection.rb:38:17:38:32 | ...[...] | semmle.label | ...[...] | -| ArelInjection.rb:39:25:39:31 | user_id | semmle.label | user_id | +| ArelInjection.rb:47:7:47:13 | user_id | semmle.label | user_id | +| ArelInjection.rb:47:17:47:22 | call to params | semmle.label | call to params | +| ArelInjection.rb:47:17:47:32 | ...[...] | semmle.label | ...[...] | +| ArelInjection.rb:48:7:48:14 | route_id | semmle.label | route_id | +| ArelInjection.rb:48:18:48:38 | call to route_param | semmle.label | call to route_param | +| ArelInjection.rb:49:7:49:10 | auth | semmle.label | auth | +| ArelInjection.rb:49:14:49:20 | call to headers | semmle.label | call to headers | +| ArelInjection.rb:49:14:49:36 | ...[...] | semmle.label | ...[...] | +| ArelInjection.rb:50:7:50:13 | session | semmle.label | session | +| ArelInjection.rb:50:17:50:23 | call to cookies | semmle.label | call to cookies | +| ArelInjection.rb:50:17:50:36 | ...[...] | semmle.label | ...[...] | +| ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | semmle.label | "SELECT * FROM users WHERE id ..." | +| ArelInjection.rb:59:7:59:13 | user_id | semmle.label | user_id | +| ArelInjection.rb:59:17:59:22 | call to params | semmle.label | call to params | +| ArelInjection.rb:59:17:59:32 | ...[...] | semmle.label | ...[...] | +| ArelInjection.rb:60:25:60:31 | user_id | semmle.label | user_id | +| ArelInjection.rb:67:9:67:15 | user_id | semmle.label | user_id | +| ArelInjection.rb:67:19:67:24 | call to params | semmle.label | call to params | +| ArelInjection.rb:67:19:67:29 | ...[...] | semmle.label | ...[...] | +| ArelInjection.rb:68:18:68:60 | "SELECT * FROM users WHERE id ..." | semmle.label | "SELECT * FROM users WHERE id ..." | | PgInjection.rb:6:5:6:8 | name | semmle.label | name | | PgInjection.rb:6:12:6:17 | call to params | semmle.label | call to params | | PgInjection.rb:6:12:6:24 | ...[...] | semmle.label | ...[...] | @@ -296,7 +326,12 @@ subpaths | ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:13:12:13:17 | call to params | ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:13:12:13:17 | call to params | user-provided value | | ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:13:12:13:17 | call to params | ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:13:12:13:17 | call to params | user-provided value | | ArelInjection.rb:23:14:23:52 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:22:9:22:14 | call to params | ArelInjection.rb:23:14:23:52 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:22:9:22:14 | call to params | user-provided value | -| ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:38:17:38:22 | call to params | ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:38:17:38:22 | call to params | user-provided value | +| ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:59:17:59:22 | call to params | ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:59:17:59:22 | call to params | user-provided value | +| ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:47:17:47:22 | call to params | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:47:17:47:22 | call to params | user-provided value | +| ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:48:18:48:38 | call to route_param | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:48:18:48:38 | call to route_param | user-provided value | +| ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:49:14:49:20 | call to headers | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:49:14:49:20 | call to headers | user-provided value | +| ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:50:17:50:23 | call to cookies | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:50:17:50:23 | call to cookies | user-provided value | +| ArelInjection.rb:68:18:68:60 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:67:19:67:24 | call to params | ArelInjection.rb:68:18:68:60 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:67:19:67:24 | call to params | user-provided value | | PgInjection.rb:14:15:14:18 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:14:15:14:18 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | | PgInjection.rb:15:21:15:24 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:15:21:15:24 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | | PgInjection.rb:20:22:20:25 | qry2 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:20:22:20:25 | qry2 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | From 459f00ab415e1263c0756a03516e51e9963adc52 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Sep 2025 11:25:11 +0000 Subject: [PATCH 012/160] Initial plan From e630bf86bdd0f9a678b234f04f11f4ba883b5571 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Sep 2025 11:44:05 +0000 Subject: [PATCH 013/160] Implement Rust non-HTTPS URL query (CWE-319) Co-authored-by: geoffw0 <40627776+geoffw0@users.noreply.github.com> --- .../rust-code-scanning.qls.expected | 1 + .../rust-security-and-quality.qls.expected | 1 + .../rust-security-extended.qls.expected | 1 + .../rust/security/UseOfHttpExtensions.qll | 60 + .../change-notes/2025-09-15-non-https-url.md | 4 + .../queries/security/CWE-319/UseOfHttp.qhelp | 48 + .../src/queries/security/CWE-319/UseOfHttp.ql | 42 + .../queries/security/CWE-319/UseOfHttpBad.rs | 10 + .../queries/security/CWE-319/UseOfHttpGood.rs | 10 + rust/ql/src/queries/summary/Stats.qll | 1 + .../query-tests/security/CWE-319/Cargo.lock | 1574 +++++++++++++++++ .../security/CWE-319/UseOfHttp.expected | 78 + .../security/CWE-319/UseOfHttp.qlref | 4 + .../test/query-tests/security/CWE-319/main.rs | 65 + .../query-tests/security/CWE-319/options.yml | 3 + 15 files changed, 1902 insertions(+) create mode 100644 rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll create mode 100644 rust/ql/src/change-notes/2025-09-15-non-https-url.md create mode 100644 rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp create mode 100644 rust/ql/src/queries/security/CWE-319/UseOfHttp.ql create mode 100644 rust/ql/src/queries/security/CWE-319/UseOfHttpBad.rs create mode 100644 rust/ql/src/queries/security/CWE-319/UseOfHttpGood.rs create mode 100644 rust/ql/test/query-tests/security/CWE-319/Cargo.lock create mode 100644 rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected create mode 100644 rust/ql/test/query-tests/security/CWE-319/UseOfHttp.qlref create mode 100644 rust/ql/test/query-tests/security/CWE-319/main.rs create mode 100644 rust/ql/test/query-tests/security/CWE-319/options.yml diff --git a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected index b601905e6a3..1b8e1015a1f 100644 --- a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected +++ b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected @@ -14,6 +14,7 @@ ql/rust/ql/src/queries/security/CWE-089/SqlInjection.ql ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql +ql/rust/ql/src/queries/security/CWE-319/UseOfHttp.ql ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql ql/rust/ql/src/queries/security/CWE-328/WeakSensitiveDataHashing.ql ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql diff --git a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected index 074cb2ec888..a2d2e2b820c 100644 --- a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected +++ b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected @@ -15,6 +15,7 @@ ql/rust/ql/src/queries/security/CWE-117/LogInjection.ql ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql +ql/rust/ql/src/queries/security/CWE-319/UseOfHttp.ql ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql ql/rust/ql/src/queries/security/CWE-328/WeakSensitiveDataHashing.ql ql/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql diff --git a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected index 38846e281eb..9000990ad84 100644 --- a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected +++ b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected @@ -15,6 +15,7 @@ ql/rust/ql/src/queries/security/CWE-117/LogInjection.ql ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql +ql/rust/ql/src/queries/security/CWE-319/UseOfHttp.ql ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql ql/rust/ql/src/queries/security/CWE-328/WeakSensitiveDataHashing.ql ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql diff --git a/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll b/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll new file mode 100644 index 00000000000..026880785b6 --- /dev/null +++ b/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll @@ -0,0 +1,60 @@ +/** + * Provides classes and predicates for reasoning about the use of + * non-HTTPS URLs in Rust code. + */ + +import rust +private import codeql.rust.dataflow.DataFlow +private import codeql.rust.dataflow.FlowSink +private import codeql.rust.elements.LiteralExprExt +private import codeql.rust.Concepts + +/** + * Provides default sources, sinks and barriers for detecting use of + * non-HTTPS URLs, as well as extension points for adding your own. + */ +module UseOfHttp { + /** + * A data flow source for use of non-HTTPS URLs. + */ + abstract class Source extends DataFlow::Node { } + + /** + * A data flow sink for use of non-HTTPS URLs. + */ + abstract class Sink extends QuerySink::Range { + override string getSinkType() { result = "UseOfHttp" } + } + + /** + * A barrier for use of non-HTTPS URLs. + */ + abstract class Barrier extends DataFlow::Node { } + + /** + * A string containing an HTTP URL. + */ + class HttpStringLiteral extends StringLiteralExpr { + HttpStringLiteral() { + exists(string s | this.getTextValue() = s | + // Match HTTP URLs that are not private/local + s.regexpMatch("\"http://.*\"") and + not s.regexpMatch("\"http://(localhost|127\\.0\\.0\\.1|192\\.168\\.[0-9]+\\.[0-9]+|10\\.[0-9]+\\.[0-9]+\\.[0-9]+|172\\.16\\.[0-9]+\\.[0-9]+|\\[::1\\]|\\[0:0:0:0:0:0:0:1\\]).*\"") + ) + } + } + + /** + * An HTTP string literal as a source. + */ + private class HttpStringLiteralAsSource extends Source { + HttpStringLiteralAsSource() { this.asExpr().getExpr() instanceof HttpStringLiteral } + } + + /** + * A sink for use of HTTP URLs from model data. + */ + private class ModelsAsDataSink extends Sink { + ModelsAsDataSink() { sinkNode(this, "request-url") } + } +} diff --git a/rust/ql/src/change-notes/2025-09-15-non-https-url.md b/rust/ql/src/change-notes/2025-09-15-non-https-url.md new file mode 100644 index 00000000000..c4ab664f732 --- /dev/null +++ b/rust/ql/src/change-notes/2025-09-15-non-https-url.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `rust/non-https-url`, for detecting the use of non-HTTPS URLs that can be intercepted by third parties. \ No newline at end of file diff --git a/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp b/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp new file mode 100644 index 00000000000..a8ca1d9c7c7 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp @@ -0,0 +1,48 @@ + + + + +

    Constructing URLs with the HTTP protocol can lead to unsecured connections.

    + +

    Furthermore, constructing URLs with the HTTP protocol can create problems if other parts of the +code expect HTTPS URLs. A typical pattern is to use libraries that expect secure connections, +which may fail or fall back to insecure behavior when provided with HTTP URLs instead of HTTPS URLs.

    + +
    + + +

    When you construct a URL for network requests, ensure that you use an HTTPS URL rather than an HTTP URL. +Then, any connections that are made using that URL are secure SSL/TLS connections.

    + +
    + + +

    The following example shows two ways of making a network request using a URL. When the request is +made using an HTTP URL rather than an HTTPS URL, the connection is unsecured and can be intercepted +by attackers. When the request is made using an HTTPS URL, the connection is a secure SSL/TLS connection.

    + + + +

    A better approach is to use HTTPS:

    + + + +
    + + +
  • +OWASP: +Transport Layer Protection Cheat Sheet. +
  • +
  • +OWASP Top 10: +A08:2021 - Software and Data Integrity Failures. +
  • +
  • Rust reqwest documentation: +reqwest crate. +
  • + +
    +
    \ No newline at end of file diff --git a/rust/ql/src/queries/security/CWE-319/UseOfHttp.ql b/rust/ql/src/queries/security/CWE-319/UseOfHttp.ql new file mode 100644 index 00000000000..4a464d90bbe --- /dev/null +++ b/rust/ql/src/queries/security/CWE-319/UseOfHttp.ql @@ -0,0 +1,42 @@ +/** + * @name Failure to use HTTPS URLs + * @description Non-HTTPS connections can be intercepted by third parties. + * @kind path-problem + * @problem.severity warning + * @security-severity 8.1 + * @precision high + * @id rust/non-https-url + * @tags security + * external/cwe/cwe-319 + * external/cwe/cwe-345 + */ + +import rust +import codeql.rust.dataflow.DataFlow +import codeql.rust.dataflow.TaintTracking +import codeql.rust.security.UseOfHttpExtensions + +/** + * A taint configuration for HTTP URL strings that flow to URL-using sinks. + */ +module UseOfHttpConfig implements DataFlow::ConfigSig { + import UseOfHttp + + predicate isSource(DataFlow::Node node) { node instanceof Source } + + predicate isSink(DataFlow::Node node) { node instanceof Sink } + + predicate isBarrier(DataFlow::Node barrier) { barrier instanceof Barrier } + + predicate observeDiffInformedIncrementalMode() { any() } +} + +module UseOfHttpFlow = TaintTracking::Global; + +import UseOfHttpFlow::PathGraph + +from UseOfHttpFlow::PathNode sourceNode, UseOfHttpFlow::PathNode sinkNode +where UseOfHttpFlow::flowPath(sourceNode, sinkNode) +select sinkNode.getNode(), sourceNode, sinkNode, + "This URL may be constructed with the HTTP protocol, from $@.", sourceNode.getNode(), + "this HTTP URL" diff --git a/rust/ql/src/queries/security/CWE-319/UseOfHttpBad.rs b/rust/ql/src/queries/security/CWE-319/UseOfHttpBad.rs new file mode 100644 index 00000000000..ada466cae5c --- /dev/null +++ b/rust/ql/src/queries/security/CWE-319/UseOfHttpBad.rs @@ -0,0 +1,10 @@ +// BAD: Using HTTP URL which can be intercepted +use reqwest; + +fn main() { + let url = "http://example.com/sensitive-data"; + + // This makes an insecure HTTP request that can be intercepted + let response = reqwest::blocking::get(url).unwrap(); + println!("Response: {}", response.text().unwrap()); +} \ No newline at end of file diff --git a/rust/ql/src/queries/security/CWE-319/UseOfHttpGood.rs b/rust/ql/src/queries/security/CWE-319/UseOfHttpGood.rs new file mode 100644 index 00000000000..22b94235fa1 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-319/UseOfHttpGood.rs @@ -0,0 +1,10 @@ +// GOOD: Using HTTPS URL which provides encryption +use reqwest; + +fn main() { + let url = "https://example.com/sensitive-data"; + + // This makes a secure HTTPS request that is encrypted + let response = reqwest::blocking::get(url).unwrap(); + println!("Response: {}", response.text().unwrap()); +} \ No newline at end of file diff --git a/rust/ql/src/queries/summary/Stats.qll b/rust/ql/src/queries/summary/Stats.qll index 7a1de4f1314..d49e1fdde5d 100644 --- a/rust/ql/src/queries/summary/Stats.qll +++ b/rust/ql/src/queries/summary/Stats.qll @@ -27,6 +27,7 @@ private import codeql.rust.security.LogInjectionExtensions private import codeql.rust.security.SqlInjectionExtensions private import codeql.rust.security.TaintedPathExtensions private import codeql.rust.security.UncontrolledAllocationSizeExtensions +private import codeql.rust.security.UseOfHttpExtensions private import codeql.rust.security.WeakSensitiveDataHashingExtensions private import codeql.rust.security.HardcodedCryptographicValueExtensions diff --git a/rust/ql/test/query-tests/security/CWE-319/Cargo.lock b/rust/ql/test/query-tests/security/CWE-319/Cargo.lock new file mode 100644 index 00000000000..ad4b5cebd22 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-319/Cargo.lock @@ -0,0 +1,1574 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cc" +version = "1.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "find-msvc-tools" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.5+wasi-0.2.4", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "h2" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "io-uring" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "zerovec", +] + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "reqwest" +version = "0.12.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.0", +] + +[[package]] +name = "rustls" +version = "0.23.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5a37813727b78798e53c2bec3f5e8fe12a6d6f8389bf9ca7802add4c9905ad8" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.0", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.223" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a505d71960adde88e293da5cb5eda57093379f64e61cf77bf0e6a63af07a7bac" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.223" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20f57cbd357666aa7b3ac84a90b4ea328f1d4ddb6772b430caa5d9e1309bb9e9" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.223" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d428d07faf17e306e699ec1e91996e5a165ba5d6bce5b5155173e91a8a01a56" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys 0.61.0", +] + +[[package]] +name = "test" +version = "0.0.1" +dependencies = [ + "reqwest", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.47.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "pin-project-lite", + "slab", + "socket2", + "windows-sys 0.59.0", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.5+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4494f6290a82f5fe584817a676a34b9d6763e8d9d18204009fb31dceca98fd4" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.0+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03fa2761397e5bd52002cd7e73110c71af2109aca4e521a9f40473fe685b0a24" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca85039a9b469b38336411d6d6ced91f3fc87109a2a27b0c197663f5144dffe" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + +[[package]] +name = "windows-registry" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" +dependencies = [ + "windows-link 0.1.3", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +dependencies = [ + "windows-link 0.2.0", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected new file mode 100644 index 00000000000..53cc8606cc8 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected @@ -0,0 +1,78 @@ +#select +| main.rs:12:22:12:43 | ...::get | main.rs:12:45:12:68 | "http://example.com/api" | main.rs:12:22:12:43 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:12:45:12:68 | "http://example.com/api" | this HTTP URL | +| main.rs:13:22:13:43 | ...::get | main.rs:13:45:13:73 | "http://api.example.com/data" | main.rs:13:22:13:43 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:13:45:13:73 | "http://api.example.com/data" | this HTTP URL | +| main.rs:25:21:25:42 | ...::get | main.rs:22:20:22:39 | "http://example.com" | main.rs:25:21:25:42 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:22:20:22:39 | "http://example.com" | this HTTP URL | +| main.rs:36:30:36:51 | ...::get | main.rs:33:20:33:28 | "http://" | main.rs:36:30:36:51 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:33:20:33:28 | "http://" | this HTTP URL | +| main.rs:60:21:60:42 | ...::get | main.rs:59:15:59:49 | "http://example.com/sensitive-... | main.rs:60:21:60:42 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:59:15:59:49 | "http://example.com/sensitive-... | this HTTP URL | +edges +| main.rs:12:45:12:68 | "http://example.com/api" | main.rs:12:22:12:43 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:13:45:13:73 | "http://api.example.com/data" | main.rs:13:22:13:43 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:22:9:22:16 | base_url | main.rs:24:28:24:53 | MacroExpr | provenance | | +| main.rs:22:20:22:39 | "http://example.com" | main.rs:22:9:22:16 | base_url | provenance | | +| main.rs:24:9:24:16 | full_url | main.rs:25:45:25:52 | full_url | provenance | | +| main.rs:24:20:24:26 | res | main.rs:24:28:24:53 | { ... } | provenance | | +| main.rs:24:28:24:53 | ...::format(...) | main.rs:24:20:24:26 | res | provenance | | +| main.rs:24:28:24:53 | ...::must_use(...) | main.rs:24:9:24:16 | full_url | provenance | | +| main.rs:24:28:24:53 | MacroExpr | main.rs:24:28:24:53 | ...::format(...) | provenance | MaD:2 | +| main.rs:24:28:24:53 | { ... } | main.rs:24:28:24:53 | ...::must_use(...) | provenance | MaD:3 | +| main.rs:25:44:25:52 | &full_url [&ref] | main.rs:25:21:25:42 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:25:45:25:52 | full_url | main.rs:25:44:25:52 | &full_url [&ref] | provenance | | +| main.rs:33:9:33:16 | protocol | main.rs:35:32:35:53 | MacroExpr | provenance | | +| main.rs:33:20:33:28 | "http://" | main.rs:33:9:33:16 | protocol | provenance | | +| main.rs:35:9:35:20 | insecure_url | main.rs:36:54:36:65 | insecure_url | provenance | | +| main.rs:35:24:35:30 | res | main.rs:35:32:35:53 | { ... } | provenance | | +| main.rs:35:32:35:53 | ...::format(...) | main.rs:35:24:35:30 | res | provenance | | +| main.rs:35:32:35:53 | ...::must_use(...) | main.rs:35:9:35:20 | insecure_url | provenance | | +| main.rs:35:32:35:53 | MacroExpr | main.rs:35:32:35:53 | ...::format(...) | provenance | MaD:2 | +| main.rs:35:32:35:53 | { ... } | main.rs:35:32:35:53 | ...::must_use(...) | provenance | MaD:3 | +| main.rs:36:53:36:65 | &insecure_url [&ref] | main.rs:36:30:36:51 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:36:54:36:65 | insecure_url | main.rs:36:53:36:65 | &insecure_url [&ref] | provenance | | +| main.rs:59:9:59:11 | url | main.rs:60:44:60:46 | url | provenance | | +| main.rs:59:15:59:49 | "http://example.com/sensitive-... | main.rs:59:9:59:11 | url | provenance | | +| main.rs:60:44:60:46 | url | main.rs:60:21:60:42 | ...::get | provenance | MaD:1 Sink:MaD:1 | +models +| 1 | Sink: reqwest::blocking::get; Argument[0]; request-url | +| 2 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | +| 3 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value | +nodes +| main.rs:12:22:12:43 | ...::get | semmle.label | ...::get | +| main.rs:12:45:12:68 | "http://example.com/api" | semmle.label | "http://example.com/api" | +| main.rs:13:22:13:43 | ...::get | semmle.label | ...::get | +| main.rs:13:45:13:73 | "http://api.example.com/data" | semmle.label | "http://api.example.com/data" | +| main.rs:22:9:22:16 | base_url | semmle.label | base_url | +| main.rs:22:20:22:39 | "http://example.com" | semmle.label | "http://example.com" | +| main.rs:24:9:24:16 | full_url | semmle.label | full_url | +| main.rs:24:20:24:26 | res | semmle.label | res | +| main.rs:24:28:24:53 | ...::format(...) | semmle.label | ...::format(...) | +| main.rs:24:28:24:53 | ...::must_use(...) | semmle.label | ...::must_use(...) | +| main.rs:24:28:24:53 | MacroExpr | semmle.label | MacroExpr | +| main.rs:24:28:24:53 | { ... } | semmle.label | { ... } | +| main.rs:25:21:25:42 | ...::get | semmle.label | ...::get | +| main.rs:25:44:25:52 | &full_url [&ref] | semmle.label | &full_url [&ref] | +| main.rs:25:45:25:52 | full_url | semmle.label | full_url | +| main.rs:33:9:33:16 | protocol | semmle.label | protocol | +| main.rs:33:20:33:28 | "http://" | semmle.label | "http://" | +| main.rs:35:9:35:20 | insecure_url | semmle.label | insecure_url | +| main.rs:35:24:35:30 | res | semmle.label | res | +| main.rs:35:32:35:53 | ...::format(...) | semmle.label | ...::format(...) | +| main.rs:35:32:35:53 | ...::must_use(...) | semmle.label | ...::must_use(...) | +| main.rs:35:32:35:53 | MacroExpr | semmle.label | MacroExpr | +| main.rs:35:32:35:53 | { ... } | semmle.label | { ... } | +| main.rs:36:30:36:51 | ...::get | semmle.label | ...::get | +| main.rs:36:53:36:65 | &insecure_url [&ref] | semmle.label | &insecure_url [&ref] | +| main.rs:36:54:36:65 | insecure_url | semmle.label | insecure_url | +| main.rs:59:9:59:11 | url | semmle.label | url | +| main.rs:59:15:59:49 | "http://example.com/sensitive-... | semmle.label | "http://example.com/sensitive-... | +| main.rs:60:21:60:42 | ...::get | semmle.label | ...::get | +| main.rs:60:44:60:46 | url | semmle.label | url | +subpaths +testFailures +| main.rs:22:20:22:39 | "http://example.com" | Unexpected result: Source | +| main.rs:22:42:22:71 | //... | Missing result: Alert[rust/non-https-url] | +| main.rs:25:21:25:42 | ...::get | Unexpected result: Alert | +| main.rs:33:20:33:28 | "http://" | Unexpected result: Source | +| main.rs:33:31:33:60 | //... | Missing result: Alert[rust/non-https-url] | +| main.rs:36:30:36:51 | ...::get | Unexpected result: Alert | +| main.rs:59:15:59:49 | "http://example.com/sensitive-... | Unexpected result: Source | +| main.rs:59:52:59:81 | //... | Missing result: Alert[rust/non-https-url] | +| main.rs:60:21:60:42 | ...::get | Unexpected result: Alert | diff --git a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.qlref b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.qlref new file mode 100644 index 00000000000..90b53330019 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.qlref @@ -0,0 +1,4 @@ +query: queries/security/CWE-319/UseOfHttp.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/rust/ql/test/query-tests/security/CWE-319/main.rs b/rust/ql/test/query-tests/security/CWE-319/main.rs new file mode 100644 index 00000000000..ae58967a49b --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-319/main.rs @@ -0,0 +1,65 @@ +use reqwest; +use std::env; + +fn main() { + test_direct_literals(); + test_dynamic_urls(); + test_localhost_exemptions(); +} + +fn test_direct_literals() { + // BAD: Direct HTTP URLs that should be flagged + let _response1 = reqwest::blocking::get("http://example.com/api").unwrap(); // $ Alert[rust/non-https-url] + let _response2 = reqwest::blocking::get("http://api.example.com/data").unwrap(); // $ Alert[rust/non-https-url] + + // GOOD: HTTPS URLs that should not be flagged + let _response3 = reqwest::blocking::get("https://example.com/api").unwrap(); + let _response4 = reqwest::blocking::get("https://api.example.com/data").unwrap(); +} + +fn test_dynamic_urls() { + // BAD: HTTP URLs constructed dynamically + let base_url = "http://example.com"; // $ Alert[rust/non-https-url] + let endpoint = "/api/users"; + let full_url = format!("{}{}", base_url, endpoint); + let _response = reqwest::blocking::get(&full_url).unwrap(); + + // GOOD: HTTPS URLs constructed dynamically + let secure_base = "https://example.com"; + let secure_full = format!("{}{}", secure_base, endpoint); + let _secure_response = reqwest::blocking::get(&secure_full).unwrap(); + + // BAD: HTTP protocol string + let protocol = "http://"; // $ Alert[rust/non-https-url] + let host = "api.example.com"; + let insecure_url = format!("{}{}", protocol, host); + let _insecure_response = reqwest::blocking::get(&insecure_url).unwrap(); + + // GOOD: HTTPS protocol string + let secure_protocol = "https://"; + let secure_url = format!("{}{}", secure_protocol, host); + let _secure_response2 = reqwest::blocking::get(&secure_url).unwrap(); +} + +fn test_localhost_exemptions() { + // GOOD: localhost URLs should not be flagged (local development) + let _local1 = reqwest::blocking::get("http://localhost:8080/api").unwrap(); + let _local2 = reqwest::blocking::get("http://127.0.0.1:3000/test").unwrap(); + let _local3 = reqwest::blocking::get("http://192.168.1.100/internal").unwrap(); + let _local4 = reqwest::blocking::get("http://10.0.0.1/admin").unwrap(); + + // Test IPv6 localhost variants + let _local5 = reqwest::blocking::get("http://[::1]:8080/api").unwrap(); + let _local6 = reqwest::blocking::get("http://[0:0:0:0:0:0:0:1]/test").unwrap(); +} + +// Additional test cases that mirror the Bad/Good examples +fn test_examples() { + // From UseOfHttpBad.rs - BAD case + let url = "http://example.com/sensitive-data"; // $ Alert[rust/non-https-url] + let _response = reqwest::blocking::get(url).unwrap(); + + // From UseOfHttpGood.rs - GOOD case + let secure_url = "https://example.com/sensitive-data"; + let _secure_response = reqwest::blocking::get(secure_url).unwrap(); +} \ No newline at end of file diff --git a/rust/ql/test/query-tests/security/CWE-319/options.yml b/rust/ql/test/query-tests/security/CWE-319/options.yml new file mode 100644 index 00000000000..aa57719603d --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-319/options.yml @@ -0,0 +1,3 @@ +qltest_cargo_check: true +qltest_dependencies: + - reqwest = { version = "0.12.9", features = ["blocking"] } \ No newline at end of file From 8442146a0fe0ec65aa9649a746045d8a209560d4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 15 Sep 2025 16:40:58 +0100 Subject: [PATCH 014/160] Rust: Add a couple of simple data flow test cases. --- .../dataflow/local/DataFlowStep.expected | 2041 +++++++++-------- .../dataflow/local/inline-flow.expected | 1051 ++++----- .../test/library-tests/dataflow/local/main.rs | 12 + 3 files changed, 1573 insertions(+), 1531 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 86bd270ba93..b395948f420 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -97,1031 +97,1050 @@ localStep | main.rs:70:5:70:5 | [SSA] i | main.rs:71:10:71:10 | i | | main.rs:70:5:70:5 | i | main.rs:70:5:70:5 | [SSA] i | | main.rs:70:9:70:17 | source(...) | main.rs:70:5:70:5 | i | -| main.rs:75:9:75:9 | [SSA] a | main.rs:76:5:76:5 | a | -| main.rs:75:9:75:9 | a | main.rs:75:9:75:9 | [SSA] a | -| main.rs:75:9:75:9 | a | main.rs:75:9:75:9 | a | -| main.rs:75:13:75:17 | { ... } | main.rs:75:9:75:9 | a | -| main.rs:75:15:75:15 | 0 | main.rs:75:13:75:17 | { ... } | -| main.rs:76:5:76:5 | a | main.rs:74:31:77:1 | { ... } | -| main.rs:79:22:79:22 | [SSA] b | main.rs:81:12:81:12 | b | -| main.rs:79:22:79:22 | b | main.rs:79:22:79:22 | [SSA] b | -| main.rs:79:22:79:22 | b | main.rs:79:22:79:22 | b | -| main.rs:79:22:79:28 | ...: bool | main.rs:79:22:79:22 | b | -| main.rs:80:9:80:9 | [SSA] a | main.rs:86:5:86:5 | a | -| main.rs:80:9:80:9 | a | main.rs:80:9:80:9 | [SSA] a | -| main.rs:80:9:80:9 | a | main.rs:80:9:80:9 | a | -| main.rs:80:13:85:5 | 'block: { ... } | main.rs:80:9:80:9 | a | -| main.rs:82:13:82:26 | break 'block 1 | main.rs:80:13:85:5 | 'block: { ... } | -| main.rs:82:26:82:26 | 1 | main.rs:82:13:82:26 | break 'block 1 | -| main.rs:84:9:84:9 | 2 | main.rs:80:13:85:5 | 'block: { ... } | -| main.rs:86:5:86:5 | a | main.rs:79:38:87:1 | { ... } | -| main.rs:89:22:89:22 | [SSA] b | main.rs:91:12:91:12 | b | -| main.rs:89:22:89:22 | b | main.rs:89:22:89:22 | [SSA] b | -| main.rs:89:22:89:22 | b | main.rs:89:22:89:22 | b | -| main.rs:89:22:89:28 | ...: bool | main.rs:89:22:89:22 | b | -| main.rs:90:9:90:9 | [SSA] a | main.rs:96:5:96:5 | a | -| main.rs:90:9:90:9 | a | main.rs:90:9:90:9 | [SSA] a | -| main.rs:90:9:90:9 | a | main.rs:90:9:90:9 | a | -| main.rs:90:13:95:5 | 'block: { ... } | main.rs:90:9:90:9 | a | -| main.rs:92:13:92:26 | break 'block 1 | main.rs:90:13:95:5 | 'block: { ... } | -| main.rs:92:26:92:26 | 1 | main.rs:92:13:92:26 | break 'block 1 | -| main.rs:94:9:94:22 | break 'block 2 | main.rs:90:13:95:5 | 'block: { ... } | -| main.rs:94:22:94:22 | 2 | main.rs:94:9:94:22 | break 'block 2 | -| main.rs:96:5:96:5 | a | main.rs:89:38:97:1 | { ... } | -| main.rs:103:9:103:9 | [SSA] i | main.rs:104:11:104:11 | i | -| main.rs:103:9:103:9 | i | main.rs:103:9:103:9 | [SSA] i | -| main.rs:103:9:103:9 | i | main.rs:103:9:103:9 | i | -| main.rs:103:13:103:31 | ...::new(...) | main.rs:103:9:103:9 | i | -| main.rs:104:11:104:11 | [post] receiver for i | main.rs:104:11:104:11 | [post] i | -| main.rs:104:11:104:11 | i | main.rs:104:11:104:11 | receiver for i | -| main.rs:111:9:111:9 | [SSA] a | main.rs:112:10:112:10 | a | -| main.rs:111:9:111:9 | a | main.rs:111:9:111:9 | [SSA] a | -| main.rs:111:9:111:9 | a | main.rs:111:9:111:9 | a | -| main.rs:111:13:111:26 | TupleExpr | main.rs:111:9:111:9 | a | -| main.rs:112:10:112:10 | [post] a | main.rs:113:10:113:10 | a | -| main.rs:112:10:112:10 | a | main.rs:113:10:113:10 | a | -| main.rs:117:9:117:9 | [SSA] a | main.rs:118:24:118:24 | a | -| main.rs:117:9:117:9 | a | main.rs:117:9:117:9 | [SSA] a | -| main.rs:117:9:117:9 | a | main.rs:117:9:117:9 | a | -| main.rs:117:13:117:30 | TupleExpr | main.rs:117:9:117:9 | a | -| main.rs:118:10:118:11 | [SSA] a0 | main.rs:119:10:119:11 | a0 | -| main.rs:118:10:118:11 | a0 | main.rs:118:10:118:11 | [SSA] a0 | -| main.rs:118:10:118:11 | a0 | main.rs:118:10:118:11 | a0 | -| main.rs:118:14:118:15 | [SSA] a1 | main.rs:120:10:120:11 | a1 | -| main.rs:118:14:118:15 | a1 | main.rs:118:14:118:15 | [SSA] a1 | -| main.rs:118:14:118:15 | a1 | main.rs:118:14:118:15 | a1 | -| main.rs:118:18:118:19 | [SSA] a2 | main.rs:121:10:121:11 | a2 | -| main.rs:118:18:118:19 | a2 | main.rs:118:18:118:19 | [SSA] a2 | -| main.rs:118:18:118:19 | a2 | main.rs:118:18:118:19 | a2 | -| main.rs:118:24:118:24 | a | main.rs:118:9:118:20 | TuplePat | -| main.rs:125:9:125:13 | mut a | main.rs:125:13:125:13 | a | -| main.rs:125:13:125:13 | [SSA] a | main.rs:126:10:126:10 | a | -| main.rs:125:13:125:13 | a | main.rs:125:13:125:13 | [SSA] a | -| main.rs:125:17:125:31 | TupleExpr | main.rs:125:9:125:13 | mut a | -| main.rs:126:10:126:10 | [post] a | main.rs:127:10:127:10 | a | -| main.rs:126:10:126:10 | a | main.rs:127:10:127:10 | a | -| main.rs:127:10:127:10 | [post] a | main.rs:128:5:128:5 | a | -| main.rs:127:10:127:10 | a | main.rs:128:5:128:5 | a | -| main.rs:128:5:128:5 | [post] a | main.rs:129:5:129:5 | a | -| main.rs:128:5:128:5 | a | main.rs:129:5:129:5 | a | -| main.rs:128:11:128:20 | source(...) | main.rs:128:5:128:7 | a.0 | -| main.rs:129:5:129:5 | [post] a | main.rs:130:10:130:10 | a | -| main.rs:129:5:129:5 | a | main.rs:130:10:130:10 | a | -| main.rs:129:11:129:11 | 2 | main.rs:129:5:129:7 | a.1 | -| main.rs:130:10:130:10 | [post] a | main.rs:131:10:131:10 | a | -| main.rs:130:10:130:10 | a | main.rs:131:10:131:10 | a | -| main.rs:135:9:135:9 | [SSA] a | main.rs:136:14:136:14 | a | -| main.rs:135:9:135:9 | a | main.rs:135:9:135:9 | [SSA] a | -| main.rs:135:9:135:9 | a | main.rs:135:9:135:9 | a | -| main.rs:135:13:135:27 | TupleExpr | main.rs:135:9:135:9 | a | -| main.rs:136:9:136:9 | [SSA] b | main.rs:137:10:137:10 | b | -| main.rs:136:9:136:9 | b | main.rs:136:9:136:9 | [SSA] b | -| main.rs:136:9:136:9 | b | main.rs:136:9:136:9 | b | -| main.rs:136:13:136:18 | TupleExpr | main.rs:136:9:136:9 | b | -| main.rs:137:10:137:10 | [post] b | main.rs:138:10:138:10 | b | -| main.rs:137:10:137:10 | b | main.rs:138:10:138:10 | b | -| main.rs:138:10:138:10 | [post] b | main.rs:139:10:139:10 | b | -| main.rs:138:10:138:10 | b | main.rs:139:10:139:10 | b | -| main.rs:151:9:151:9 | [SSA] p | main.rs:152:10:152:10 | p | -| main.rs:151:9:151:9 | p | main.rs:151:9:151:9 | [SSA] p | -| main.rs:151:9:151:9 | p | main.rs:151:9:151:9 | p | -| main.rs:151:13:151:40 | Point {...} | main.rs:151:9:151:9 | p | -| main.rs:152:10:152:10 | [post] p | main.rs:153:10:153:10 | p | -| main.rs:152:10:152:10 | p | main.rs:153:10:153:10 | p | -| main.rs:157:9:157:13 | mut p | main.rs:157:13:157:13 | p | -| main.rs:157:13:157:13 | [SSA] p | main.rs:158:10:158:10 | p | -| main.rs:157:13:157:13 | p | main.rs:157:13:157:13 | [SSA] p | -| main.rs:157:17:157:44 | Point {...} | main.rs:157:9:157:13 | mut p | -| main.rs:158:10:158:10 | [post] p | main.rs:159:5:159:5 | p | -| main.rs:158:10:158:10 | p | main.rs:159:5:159:5 | p | -| main.rs:159:5:159:5 | [post] p | main.rs:160:10:160:10 | p | -| main.rs:159:5:159:5 | p | main.rs:160:10:160:10 | p | -| main.rs:159:11:159:20 | source(...) | main.rs:159:5:159:7 | p.y | -| main.rs:164:9:164:9 | [SSA] p | main.rs:168:32:168:32 | p | -| main.rs:164:9:164:9 | p | main.rs:164:9:164:9 | [SSA] p | -| main.rs:164:9:164:9 | p | main.rs:164:9:164:9 | p | -| main.rs:164:13:167:5 | Point {...} | main.rs:164:9:164:9 | p | -| main.rs:168:20:168:20 | [SSA] a | main.rs:169:10:169:10 | a | -| main.rs:168:20:168:20 | a | main.rs:168:20:168:20 | [SSA] a | -| main.rs:168:20:168:20 | a | main.rs:168:20:168:20 | a | -| main.rs:168:26:168:26 | [SSA] b | main.rs:170:10:170:10 | b | -| main.rs:168:26:168:26 | b | main.rs:168:26:168:26 | [SSA] b | -| main.rs:168:26:168:26 | b | main.rs:168:26:168:26 | b | -| main.rs:168:32:168:32 | p | main.rs:168:9:168:28 | Point {...} | -| main.rs:179:9:179:9 | [SSA] p | main.rs:186:10:186:10 | p | -| main.rs:179:9:179:9 | p | main.rs:179:9:179:9 | [SSA] p | -| main.rs:179:9:179:9 | p | main.rs:179:9:179:9 | p | -| main.rs:179:13:185:5 | Point3D {...} | main.rs:179:9:179:9 | p | -| main.rs:186:10:186:10 | [post] p | main.rs:187:10:187:10 | p | -| main.rs:186:10:186:10 | p | main.rs:187:10:187:10 | p | -| main.rs:187:10:187:10 | [post] p | main.rs:188:10:188:10 | p | -| main.rs:187:10:187:10 | p | main.rs:188:10:188:10 | p | -| main.rs:192:9:192:9 | [SSA] y | main.rs:194:30:194:30 | y | -| main.rs:192:9:192:9 | y | main.rs:192:9:192:9 | [SSA] y | -| main.rs:192:9:192:9 | y | main.rs:192:9:192:9 | y | -| main.rs:192:13:192:22 | source(...) | main.rs:192:9:192:9 | y | -| main.rs:193:9:193:9 | [SSA] p | main.rs:197:11:197:11 | p | -| main.rs:193:9:193:9 | p | main.rs:193:9:193:9 | [SSA] p | -| main.rs:193:9:193:9 | p | main.rs:193:9:193:9 | p | -| main.rs:193:13:196:5 | Point3D {...} | main.rs:193:9:193:9 | p | -| main.rs:197:5:206:5 | match p { ... } | main.rs:191:26:207:1 | { ... } | -| main.rs:197:11:197:11 | p | main.rs:198:9:201:9 | Point3D {...} | -| main.rs:199:28:199:28 | [SSA] x | main.rs:202:18:202:18 | x | -| main.rs:199:28:199:28 | x | main.rs:199:28:199:28 | [SSA] x | -| main.rs:199:28:199:28 | x | main.rs:199:28:199:28 | x | -| main.rs:199:31:199:31 | [SSA] y | main.rs:203:18:203:18 | y | -| main.rs:199:31:199:31 | y | main.rs:199:31:199:31 | [SSA] y | -| main.rs:199:31:199:31 | y | main.rs:199:31:199:31 | y | -| main.rs:200:13:200:13 | [SSA] z | main.rs:204:18:204:18 | z | -| main.rs:200:13:200:13 | z | main.rs:200:13:200:13 | [SSA] z | -| main.rs:200:13:200:13 | z | main.rs:200:13:200:13 | z | -| main.rs:201:14:205:9 | { ... } | main.rs:197:5:206:5 | match p { ... } | -| main.rs:212:9:212:9 | [SSA] s | main.rs:213:10:213:10 | s | -| main.rs:212:9:212:9 | s | main.rs:212:9:212:9 | [SSA] s | -| main.rs:212:9:212:9 | s | main.rs:212:9:212:9 | s | -| main.rs:212:13:212:40 | MyTupleStruct(...) | main.rs:212:9:212:9 | s | -| main.rs:213:10:213:10 | [post] s | main.rs:214:10:214:10 | s | -| main.rs:213:10:213:10 | s | main.rs:214:10:214:10 | s | -| main.rs:214:10:214:10 | [post] s | main.rs:216:11:216:11 | s | -| main.rs:214:10:214:10 | s | main.rs:216:11:216:11 | s | -| main.rs:216:5:221:5 | match s { ... } | main.rs:211:19:222:1 | { ... } | -| main.rs:216:11:216:11 | s | main.rs:217:9:217:27 | MyTupleStruct(...) | -| main.rs:217:23:217:23 | [SSA] x | main.rs:218:18:218:18 | x | -| main.rs:217:23:217:23 | x | main.rs:217:23:217:23 | [SSA] x | -| main.rs:217:23:217:23 | x | main.rs:217:23:217:23 | x | -| main.rs:217:26:217:26 | [SSA] y | main.rs:219:18:219:18 | y | -| main.rs:217:26:217:26 | y | main.rs:217:26:217:26 | [SSA] y | -| main.rs:217:26:217:26 | y | main.rs:217:26:217:26 | y | -| main.rs:217:32:220:9 | { ... } | main.rs:216:5:221:5 | match s { ... } | -| main.rs:228:9:228:10 | [SSA] s1 | main.rs:230:11:230:12 | s1 | -| main.rs:228:9:228:10 | s1 | main.rs:228:9:228:10 | [SSA] s1 | -| main.rs:228:9:228:10 | s1 | main.rs:228:9:228:10 | s1 | -| main.rs:228:14:228:37 | ...::Some(...) | main.rs:228:9:228:10 | s1 | -| main.rs:229:9:229:10 | [SSA] s2 | main.rs:234:11:234:12 | s2 | -| main.rs:229:9:229:10 | s2 | main.rs:229:9:229:10 | [SSA] s2 | -| main.rs:229:9:229:10 | s2 | main.rs:229:9:229:10 | s2 | -| main.rs:229:14:229:28 | ...::Some(...) | main.rs:229:9:229:10 | s2 | -| main.rs:230:11:230:12 | s1 | main.rs:231:9:231:23 | ...::Some(...) | -| main.rs:230:11:230:12 | s1 | main.rs:232:9:232:20 | ...::None | -| main.rs:231:22:231:22 | [SSA] n | main.rs:231:33:231:33 | n | -| main.rs:231:22:231:22 | n | main.rs:231:22:231:22 | [SSA] n | -| main.rs:231:22:231:22 | n | main.rs:231:22:231:22 | n | -| main.rs:231:28:231:34 | sink(...) | main.rs:230:5:233:5 | match s1 { ... } | -| main.rs:232:25:232:31 | sink(...) | main.rs:230:5:233:5 | match s1 { ... } | -| main.rs:234:5:237:5 | match s2 { ... } | main.rs:227:37:238:1 | { ... } | -| main.rs:234:11:234:12 | s2 | main.rs:235:9:235:23 | ...::Some(...) | -| main.rs:234:11:234:12 | s2 | main.rs:236:9:236:20 | ...::None | -| main.rs:235:22:235:22 | [SSA] n | main.rs:235:33:235:33 | n | -| main.rs:235:22:235:22 | n | main.rs:235:22:235:22 | [SSA] n | -| main.rs:235:22:235:22 | n | main.rs:235:22:235:22 | n | -| main.rs:235:28:235:34 | sink(...) | main.rs:234:5:237:5 | match s2 { ... } | -| main.rs:236:25:236:31 | sink(...) | main.rs:234:5:237:5 | match s2 { ... } | -| main.rs:241:9:241:10 | [SSA] s1 | main.rs:243:11:243:12 | s1 | -| main.rs:241:9:241:10 | s1 | main.rs:241:9:241:10 | [SSA] s1 | -| main.rs:241:9:241:10 | s1 | main.rs:241:9:241:10 | s1 | -| main.rs:241:14:241:29 | Some(...) | main.rs:241:9:241:10 | s1 | -| main.rs:242:9:242:10 | [SSA] s2 | main.rs:247:11:247:12 | s2 | -| main.rs:242:9:242:10 | s2 | main.rs:242:9:242:10 | [SSA] s2 | -| main.rs:242:9:242:10 | s2 | main.rs:242:9:242:10 | s2 | -| main.rs:242:14:242:20 | Some(...) | main.rs:242:9:242:10 | s2 | -| main.rs:243:11:243:12 | s1 | main.rs:244:9:244:15 | Some(...) | -| main.rs:243:11:243:12 | s1 | main.rs:245:9:245:12 | None | -| main.rs:244:14:244:14 | [SSA] n | main.rs:244:25:244:25 | n | -| main.rs:244:14:244:14 | n | main.rs:244:14:244:14 | [SSA] n | -| main.rs:244:14:244:14 | n | main.rs:244:14:244:14 | n | -| main.rs:244:20:244:26 | sink(...) | main.rs:243:5:246:5 | match s1 { ... } | -| main.rs:245:17:245:23 | sink(...) | main.rs:243:5:246:5 | match s1 { ... } | -| main.rs:247:5:250:5 | match s2 { ... } | main.rs:240:39:251:1 | { ... } | -| main.rs:247:11:247:12 | s2 | main.rs:248:9:248:15 | Some(...) | -| main.rs:247:11:247:12 | s2 | main.rs:249:9:249:12 | None | -| main.rs:248:14:248:14 | [SSA] n | main.rs:248:25:248:25 | n | -| main.rs:248:14:248:14 | n | main.rs:248:14:248:14 | [SSA] n | -| main.rs:248:14:248:14 | n | main.rs:248:14:248:14 | n | -| main.rs:248:20:248:26 | sink(...) | main.rs:247:5:250:5 | match s2 { ... } | -| main.rs:249:17:249:23 | sink(...) | main.rs:247:5:250:5 | match s2 { ... } | -| main.rs:254:9:254:10 | [SSA] s1 | main.rs:255:22:255:23 | s1 | -| main.rs:254:9:254:10 | s1 | main.rs:254:9:254:10 | [SSA] s1 | -| main.rs:254:9:254:10 | s1 | main.rs:254:9:254:10 | s1 | -| main.rs:254:14:254:29 | Some(...) | main.rs:254:9:254:10 | s1 | -| main.rs:255:5:262:5 | if ... {...} | main.rs:253:25:263:1 | { ... } | -| main.rs:255:17:255:17 | [SSA] n | main.rs:257:18:257:18 | n | -| main.rs:255:17:255:17 | n | main.rs:255:17:255:17 | [SSA] n | -| main.rs:255:17:255:17 | n | main.rs:255:17:255:17 | n | -| main.rs:255:22:255:23 | s1 | main.rs:255:12:255:18 | Some(...) | -| main.rs:257:18:257:18 | [post] n | main.rs:261:14:261:14 | n | -| main.rs:257:18:257:18 | n | main.rs:261:14:261:14 | n | -| main.rs:258:13:258:16 | true | main.rs:256:12:259:9 | { ... } | -| main.rs:260:5:262:5 | { ... } | main.rs:255:5:262:5 | if ... {...} | -| main.rs:266:9:266:10 | [SSA] s1 | main.rs:267:10:267:11 | s1 | +| main.rs:72:5:72:5 | [SSA] i | main.rs:73:10:73:10 | i | +| main.rs:72:5:72:5 | i | main.rs:72:5:72:5 | [SSA] i | +| main.rs:72:9:72:9 | 2 | main.rs:72:5:72:5 | i | +| main.rs:75:9:75:13 | mut j | main.rs:75:13:75:13 | j | +| main.rs:75:17:75:17 | 3 | main.rs:75:9:75:13 | mut j | +| main.rs:76:9:76:9 | [SSA] k | main.rs:77:9:77:9 | k | +| main.rs:76:9:76:9 | k | main.rs:76:9:76:9 | [SSA] k | +| main.rs:76:9:76:9 | k | main.rs:76:9:76:9 | k | +| main.rs:76:13:76:21 | source(...) | main.rs:76:9:76:9 | k | +| main.rs:77:5:77:5 | [SSA] j | main.rs:78:10:78:10 | j | +| main.rs:77:5:77:5 | j | main.rs:77:5:77:5 | [SSA] j | +| main.rs:77:9:77:9 | k | main.rs:77:5:77:5 | j | +| main.rs:77:9:77:9 | k | main.rs:79:10:79:10 | k | +| main.rs:81:9:81:13 | mut l | main.rs:81:13:81:13 | l | +| main.rs:81:17:81:25 | source(...) | main.rs:81:9:81:13 | mut l | +| main.rs:82:5:82:5 | [SSA] l | main.rs:82:9:82:9 | l | +| main.rs:82:5:82:5 | l | main.rs:82:5:82:5 | [SSA] l | +| main.rs:82:9:82:9 | l | main.rs:82:5:82:5 | l | +| main.rs:82:9:82:9 | l | main.rs:83:10:83:10 | l | +| main.rs:87:9:87:9 | [SSA] a | main.rs:88:5:88:5 | a | +| main.rs:87:9:87:9 | a | main.rs:87:9:87:9 | [SSA] a | +| main.rs:87:9:87:9 | a | main.rs:87:9:87:9 | a | +| main.rs:87:13:87:17 | { ... } | main.rs:87:9:87:9 | a | +| main.rs:87:15:87:15 | 0 | main.rs:87:13:87:17 | { ... } | +| main.rs:88:5:88:5 | a | main.rs:86:31:89:1 | { ... } | +| main.rs:91:22:91:22 | [SSA] b | main.rs:93:12:93:12 | b | +| main.rs:91:22:91:22 | b | main.rs:91:22:91:22 | [SSA] b | +| main.rs:91:22:91:22 | b | main.rs:91:22:91:22 | b | +| main.rs:91:22:91:28 | ...: bool | main.rs:91:22:91:22 | b | +| main.rs:92:9:92:9 | [SSA] a | main.rs:98:5:98:5 | a | +| main.rs:92:9:92:9 | a | main.rs:92:9:92:9 | [SSA] a | +| main.rs:92:9:92:9 | a | main.rs:92:9:92:9 | a | +| main.rs:92:13:97:5 | 'block: { ... } | main.rs:92:9:92:9 | a | +| main.rs:94:13:94:26 | break 'block 1 | main.rs:92:13:97:5 | 'block: { ... } | +| main.rs:94:26:94:26 | 1 | main.rs:94:13:94:26 | break 'block 1 | +| main.rs:96:9:96:9 | 2 | main.rs:92:13:97:5 | 'block: { ... } | +| main.rs:98:5:98:5 | a | main.rs:91:38:99:1 | { ... } | +| main.rs:101:22:101:22 | [SSA] b | main.rs:103:12:103:12 | b | +| main.rs:101:22:101:22 | b | main.rs:101:22:101:22 | [SSA] b | +| main.rs:101:22:101:22 | b | main.rs:101:22:101:22 | b | +| main.rs:101:22:101:28 | ...: bool | main.rs:101:22:101:22 | b | +| main.rs:102:9:102:9 | [SSA] a | main.rs:108:5:108:5 | a | +| main.rs:102:9:102:9 | a | main.rs:102:9:102:9 | [SSA] a | +| main.rs:102:9:102:9 | a | main.rs:102:9:102:9 | a | +| main.rs:102:13:107:5 | 'block: { ... } | main.rs:102:9:102:9 | a | +| main.rs:104:13:104:26 | break 'block 1 | main.rs:102:13:107:5 | 'block: { ... } | +| main.rs:104:26:104:26 | 1 | main.rs:104:13:104:26 | break 'block 1 | +| main.rs:106:9:106:22 | break 'block 2 | main.rs:102:13:107:5 | 'block: { ... } | +| main.rs:106:22:106:22 | 2 | main.rs:106:9:106:22 | break 'block 2 | +| main.rs:108:5:108:5 | a | main.rs:101:38:109:1 | { ... } | +| main.rs:115:9:115:9 | [SSA] i | main.rs:116:11:116:11 | i | +| main.rs:115:9:115:9 | i | main.rs:115:9:115:9 | [SSA] i | +| main.rs:115:9:115:9 | i | main.rs:115:9:115:9 | i | +| main.rs:115:13:115:31 | ...::new(...) | main.rs:115:9:115:9 | i | +| main.rs:116:11:116:11 | [post] receiver for i | main.rs:116:11:116:11 | [post] i | +| main.rs:116:11:116:11 | i | main.rs:116:11:116:11 | receiver for i | +| main.rs:123:9:123:9 | [SSA] a | main.rs:124:10:124:10 | a | +| main.rs:123:9:123:9 | a | main.rs:123:9:123:9 | [SSA] a | +| main.rs:123:9:123:9 | a | main.rs:123:9:123:9 | a | +| main.rs:123:13:123:26 | TupleExpr | main.rs:123:9:123:9 | a | +| main.rs:124:10:124:10 | [post] a | main.rs:125:10:125:10 | a | +| main.rs:124:10:124:10 | a | main.rs:125:10:125:10 | a | +| main.rs:129:9:129:9 | [SSA] a | main.rs:130:24:130:24 | a | +| main.rs:129:9:129:9 | a | main.rs:129:9:129:9 | [SSA] a | +| main.rs:129:9:129:9 | a | main.rs:129:9:129:9 | a | +| main.rs:129:13:129:30 | TupleExpr | main.rs:129:9:129:9 | a | +| main.rs:130:10:130:11 | [SSA] a0 | main.rs:131:10:131:11 | a0 | +| main.rs:130:10:130:11 | a0 | main.rs:130:10:130:11 | [SSA] a0 | +| main.rs:130:10:130:11 | a0 | main.rs:130:10:130:11 | a0 | +| main.rs:130:14:130:15 | [SSA] a1 | main.rs:132:10:132:11 | a1 | +| main.rs:130:14:130:15 | a1 | main.rs:130:14:130:15 | [SSA] a1 | +| main.rs:130:14:130:15 | a1 | main.rs:130:14:130:15 | a1 | +| main.rs:130:18:130:19 | [SSA] a2 | main.rs:133:10:133:11 | a2 | +| main.rs:130:18:130:19 | a2 | main.rs:130:18:130:19 | [SSA] a2 | +| main.rs:130:18:130:19 | a2 | main.rs:130:18:130:19 | a2 | +| main.rs:130:24:130:24 | a | main.rs:130:9:130:20 | TuplePat | +| main.rs:137:9:137:13 | mut a | main.rs:137:13:137:13 | a | +| main.rs:137:13:137:13 | [SSA] a | main.rs:138:10:138:10 | a | +| main.rs:137:13:137:13 | a | main.rs:137:13:137:13 | [SSA] a | +| main.rs:137:17:137:31 | TupleExpr | main.rs:137:9:137:13 | mut a | +| main.rs:138:10:138:10 | [post] a | main.rs:139:10:139:10 | a | +| main.rs:138:10:138:10 | a | main.rs:139:10:139:10 | a | +| main.rs:139:10:139:10 | [post] a | main.rs:140:5:140:5 | a | +| main.rs:139:10:139:10 | a | main.rs:140:5:140:5 | a | +| main.rs:140:5:140:5 | [post] a | main.rs:141:5:141:5 | a | +| main.rs:140:5:140:5 | a | main.rs:141:5:141:5 | a | +| main.rs:140:11:140:20 | source(...) | main.rs:140:5:140:7 | a.0 | +| main.rs:141:5:141:5 | [post] a | main.rs:142:10:142:10 | a | +| main.rs:141:5:141:5 | a | main.rs:142:10:142:10 | a | +| main.rs:141:11:141:11 | 2 | main.rs:141:5:141:7 | a.1 | +| main.rs:142:10:142:10 | [post] a | main.rs:143:10:143:10 | a | +| main.rs:142:10:142:10 | a | main.rs:143:10:143:10 | a | +| main.rs:147:9:147:9 | [SSA] a | main.rs:148:14:148:14 | a | +| main.rs:147:9:147:9 | a | main.rs:147:9:147:9 | [SSA] a | +| main.rs:147:9:147:9 | a | main.rs:147:9:147:9 | a | +| main.rs:147:13:147:27 | TupleExpr | main.rs:147:9:147:9 | a | +| main.rs:148:9:148:9 | [SSA] b | main.rs:149:10:149:10 | b | +| main.rs:148:9:148:9 | b | main.rs:148:9:148:9 | [SSA] b | +| main.rs:148:9:148:9 | b | main.rs:148:9:148:9 | b | +| main.rs:148:13:148:18 | TupleExpr | main.rs:148:9:148:9 | b | +| main.rs:149:10:149:10 | [post] b | main.rs:150:10:150:10 | b | +| main.rs:149:10:149:10 | b | main.rs:150:10:150:10 | b | +| main.rs:150:10:150:10 | [post] b | main.rs:151:10:151:10 | b | +| main.rs:150:10:150:10 | b | main.rs:151:10:151:10 | b | +| main.rs:163:9:163:9 | [SSA] p | main.rs:164:10:164:10 | p | +| main.rs:163:9:163:9 | p | main.rs:163:9:163:9 | [SSA] p | +| main.rs:163:9:163:9 | p | main.rs:163:9:163:9 | p | +| main.rs:163:13:163:40 | Point {...} | main.rs:163:9:163:9 | p | +| main.rs:164:10:164:10 | [post] p | main.rs:165:10:165:10 | p | +| main.rs:164:10:164:10 | p | main.rs:165:10:165:10 | p | +| main.rs:169:9:169:13 | mut p | main.rs:169:13:169:13 | p | +| main.rs:169:13:169:13 | [SSA] p | main.rs:170:10:170:10 | p | +| main.rs:169:13:169:13 | p | main.rs:169:13:169:13 | [SSA] p | +| main.rs:169:17:169:44 | Point {...} | main.rs:169:9:169:13 | mut p | +| main.rs:170:10:170:10 | [post] p | main.rs:171:5:171:5 | p | +| main.rs:170:10:170:10 | p | main.rs:171:5:171:5 | p | +| main.rs:171:5:171:5 | [post] p | main.rs:172:10:172:10 | p | +| main.rs:171:5:171:5 | p | main.rs:172:10:172:10 | p | +| main.rs:171:11:171:20 | source(...) | main.rs:171:5:171:7 | p.y | +| main.rs:176:9:176:9 | [SSA] p | main.rs:180:32:180:32 | p | +| main.rs:176:9:176:9 | p | main.rs:176:9:176:9 | [SSA] p | +| main.rs:176:9:176:9 | p | main.rs:176:9:176:9 | p | +| main.rs:176:13:179:5 | Point {...} | main.rs:176:9:176:9 | p | +| main.rs:180:20:180:20 | [SSA] a | main.rs:181:10:181:10 | a | +| main.rs:180:20:180:20 | a | main.rs:180:20:180:20 | [SSA] a | +| main.rs:180:20:180:20 | a | main.rs:180:20:180:20 | a | +| main.rs:180:26:180:26 | [SSA] b | main.rs:182:10:182:10 | b | +| main.rs:180:26:180:26 | b | main.rs:180:26:180:26 | [SSA] b | +| main.rs:180:26:180:26 | b | main.rs:180:26:180:26 | b | +| main.rs:180:32:180:32 | p | main.rs:180:9:180:28 | Point {...} | +| main.rs:191:9:191:9 | [SSA] p | main.rs:198:10:198:10 | p | +| main.rs:191:9:191:9 | p | main.rs:191:9:191:9 | [SSA] p | +| main.rs:191:9:191:9 | p | main.rs:191:9:191:9 | p | +| main.rs:191:13:197:5 | Point3D {...} | main.rs:191:9:191:9 | p | +| main.rs:198:10:198:10 | [post] p | main.rs:199:10:199:10 | p | +| main.rs:198:10:198:10 | p | main.rs:199:10:199:10 | p | +| main.rs:199:10:199:10 | [post] p | main.rs:200:10:200:10 | p | +| main.rs:199:10:199:10 | p | main.rs:200:10:200:10 | p | +| main.rs:204:9:204:9 | [SSA] y | main.rs:206:30:206:30 | y | +| main.rs:204:9:204:9 | y | main.rs:204:9:204:9 | [SSA] y | +| main.rs:204:9:204:9 | y | main.rs:204:9:204:9 | y | +| main.rs:204:13:204:22 | source(...) | main.rs:204:9:204:9 | y | +| main.rs:205:9:205:9 | [SSA] p | main.rs:209:11:209:11 | p | +| main.rs:205:9:205:9 | p | main.rs:205:9:205:9 | [SSA] p | +| main.rs:205:9:205:9 | p | main.rs:205:9:205:9 | p | +| main.rs:205:13:208:5 | Point3D {...} | main.rs:205:9:205:9 | p | +| main.rs:209:5:218:5 | match p { ... } | main.rs:203:26:219:1 | { ... } | +| main.rs:209:11:209:11 | p | main.rs:210:9:213:9 | Point3D {...} | +| main.rs:211:28:211:28 | [SSA] x | main.rs:214:18:214:18 | x | +| main.rs:211:28:211:28 | x | main.rs:211:28:211:28 | [SSA] x | +| main.rs:211:28:211:28 | x | main.rs:211:28:211:28 | x | +| main.rs:211:31:211:31 | [SSA] y | main.rs:215:18:215:18 | y | +| main.rs:211:31:211:31 | y | main.rs:211:31:211:31 | [SSA] y | +| main.rs:211:31:211:31 | y | main.rs:211:31:211:31 | y | +| main.rs:212:13:212:13 | [SSA] z | main.rs:216:18:216:18 | z | +| main.rs:212:13:212:13 | z | main.rs:212:13:212:13 | [SSA] z | +| main.rs:212:13:212:13 | z | main.rs:212:13:212:13 | z | +| main.rs:213:14:217:9 | { ... } | main.rs:209:5:218:5 | match p { ... } | +| main.rs:224:9:224:9 | [SSA] s | main.rs:225:10:225:10 | s | +| main.rs:224:9:224:9 | s | main.rs:224:9:224:9 | [SSA] s | +| main.rs:224:9:224:9 | s | main.rs:224:9:224:9 | s | +| main.rs:224:13:224:40 | MyTupleStruct(...) | main.rs:224:9:224:9 | s | +| main.rs:225:10:225:10 | [post] s | main.rs:226:10:226:10 | s | +| main.rs:225:10:225:10 | s | main.rs:226:10:226:10 | s | +| main.rs:226:10:226:10 | [post] s | main.rs:228:11:228:11 | s | +| main.rs:226:10:226:10 | s | main.rs:228:11:228:11 | s | +| main.rs:228:5:233:5 | match s { ... } | main.rs:223:19:234:1 | { ... } | +| main.rs:228:11:228:11 | s | main.rs:229:9:229:27 | MyTupleStruct(...) | +| main.rs:229:23:229:23 | [SSA] x | main.rs:230:18:230:18 | x | +| main.rs:229:23:229:23 | x | main.rs:229:23:229:23 | [SSA] x | +| main.rs:229:23:229:23 | x | main.rs:229:23:229:23 | x | +| main.rs:229:26:229:26 | [SSA] y | main.rs:231:18:231:18 | y | +| main.rs:229:26:229:26 | y | main.rs:229:26:229:26 | [SSA] y | +| main.rs:229:26:229:26 | y | main.rs:229:26:229:26 | y | +| main.rs:229:32:232:9 | { ... } | main.rs:228:5:233:5 | match s { ... } | +| main.rs:240:9:240:10 | [SSA] s1 | main.rs:242:11:242:12 | s1 | +| main.rs:240:9:240:10 | s1 | main.rs:240:9:240:10 | [SSA] s1 | +| main.rs:240:9:240:10 | s1 | main.rs:240:9:240:10 | s1 | +| main.rs:240:14:240:37 | ...::Some(...) | main.rs:240:9:240:10 | s1 | +| main.rs:241:9:241:10 | [SSA] s2 | main.rs:246:11:246:12 | s2 | +| main.rs:241:9:241:10 | s2 | main.rs:241:9:241:10 | [SSA] s2 | +| main.rs:241:9:241:10 | s2 | main.rs:241:9:241:10 | s2 | +| main.rs:241:14:241:28 | ...::Some(...) | main.rs:241:9:241:10 | s2 | +| main.rs:242:11:242:12 | s1 | main.rs:243:9:243:23 | ...::Some(...) | +| main.rs:242:11:242:12 | s1 | main.rs:244:9:244:20 | ...::None | +| main.rs:243:22:243:22 | [SSA] n | main.rs:243:33:243:33 | n | +| main.rs:243:22:243:22 | n | main.rs:243:22:243:22 | [SSA] n | +| main.rs:243:22:243:22 | n | main.rs:243:22:243:22 | n | +| main.rs:243:28:243:34 | sink(...) | main.rs:242:5:245:5 | match s1 { ... } | +| main.rs:244:25:244:31 | sink(...) | main.rs:242:5:245:5 | match s1 { ... } | +| main.rs:246:5:249:5 | match s2 { ... } | main.rs:239:37:250:1 | { ... } | +| main.rs:246:11:246:12 | s2 | main.rs:247:9:247:23 | ...::Some(...) | +| main.rs:246:11:246:12 | s2 | main.rs:248:9:248:20 | ...::None | +| main.rs:247:22:247:22 | [SSA] n | main.rs:247:33:247:33 | n | +| main.rs:247:22:247:22 | n | main.rs:247:22:247:22 | [SSA] n | +| main.rs:247:22:247:22 | n | main.rs:247:22:247:22 | n | +| main.rs:247:28:247:34 | sink(...) | main.rs:246:5:249:5 | match s2 { ... } | +| main.rs:248:25:248:31 | sink(...) | main.rs:246:5:249:5 | match s2 { ... } | +| main.rs:253:9:253:10 | [SSA] s1 | main.rs:255:11:255:12 | s1 | +| main.rs:253:9:253:10 | s1 | main.rs:253:9:253:10 | [SSA] s1 | +| main.rs:253:9:253:10 | s1 | main.rs:253:9:253:10 | s1 | +| main.rs:253:14:253:29 | Some(...) | main.rs:253:9:253:10 | s1 | +| main.rs:254:9:254:10 | [SSA] s2 | main.rs:259:11:259:12 | s2 | +| main.rs:254:9:254:10 | s2 | main.rs:254:9:254:10 | [SSA] s2 | +| main.rs:254:9:254:10 | s2 | main.rs:254:9:254:10 | s2 | +| main.rs:254:14:254:20 | Some(...) | main.rs:254:9:254:10 | s2 | +| main.rs:255:11:255:12 | s1 | main.rs:256:9:256:15 | Some(...) | +| main.rs:255:11:255:12 | s1 | main.rs:257:9:257:12 | None | +| main.rs:256:14:256:14 | [SSA] n | main.rs:256:25:256:25 | n | +| main.rs:256:14:256:14 | n | main.rs:256:14:256:14 | [SSA] n | +| main.rs:256:14:256:14 | n | main.rs:256:14:256:14 | n | +| main.rs:256:20:256:26 | sink(...) | main.rs:255:5:258:5 | match s1 { ... } | +| main.rs:257:17:257:23 | sink(...) | main.rs:255:5:258:5 | match s1 { ... } | +| main.rs:259:5:262:5 | match s2 { ... } | main.rs:252:39:263:1 | { ... } | +| main.rs:259:11:259:12 | s2 | main.rs:260:9:260:15 | Some(...) | +| main.rs:259:11:259:12 | s2 | main.rs:261:9:261:12 | None | +| main.rs:260:14:260:14 | [SSA] n | main.rs:260:25:260:25 | n | +| main.rs:260:14:260:14 | n | main.rs:260:14:260:14 | [SSA] n | +| main.rs:260:14:260:14 | n | main.rs:260:14:260:14 | n | +| main.rs:260:20:260:26 | sink(...) | main.rs:259:5:262:5 | match s2 { ... } | +| main.rs:261:17:261:23 | sink(...) | main.rs:259:5:262:5 | match s2 { ... } | +| main.rs:266:9:266:10 | [SSA] s1 | main.rs:267:22:267:23 | s1 | | main.rs:266:9:266:10 | s1 | main.rs:266:9:266:10 | [SSA] s1 | | main.rs:266:9:266:10 | s1 | main.rs:266:9:266:10 | s1 | | main.rs:266:14:266:29 | Some(...) | main.rs:266:9:266:10 | s1 | -| main.rs:267:10:267:11 | [post] receiver for s1 | main.rs:267:10:267:11 | [post] s1 | -| main.rs:267:10:267:11 | s1 | main.rs:267:10:267:11 | receiver for s1 | -| main.rs:271:9:271:10 | [SSA] s1 | main.rs:272:10:272:11 | s1 | -| main.rs:271:9:271:10 | s1 | main.rs:271:9:271:10 | [SSA] s1 | -| main.rs:271:9:271:10 | s1 | main.rs:271:9:271:10 | s1 | -| main.rs:271:14:271:29 | Some(...) | main.rs:271:9:271:10 | s1 | -| main.rs:272:10:272:11 | [post] receiver for s1 | main.rs:272:10:272:11 | [post] s1 | -| main.rs:272:10:272:11 | s1 | main.rs:272:10:272:11 | receiver for s1 | -| main.rs:274:9:274:10 | [SSA] s2 | main.rs:275:10:275:11 | s2 | -| main.rs:274:9:274:10 | s2 | main.rs:274:9:274:10 | [SSA] s2 | -| main.rs:274:9:274:10 | s2 | main.rs:274:9:274:10 | s2 | -| main.rs:274:14:274:20 | Some(...) | main.rs:274:9:274:10 | s2 | -| main.rs:275:10:275:11 | [post] receiver for s2 | main.rs:275:10:275:11 | [post] s2 | -| main.rs:275:10:275:11 | s2 | main.rs:275:10:275:11 | receiver for s2 | -| main.rs:279:9:279:10 | [SSA] s1 | main.rs:280:10:280:11 | s1 | -| main.rs:279:9:279:10 | s1 | main.rs:279:9:279:10 | [SSA] s1 | -| main.rs:279:9:279:10 | s1 | main.rs:279:9:279:10 | s1 | -| main.rs:279:14:279:29 | Some(...) | main.rs:279:9:279:10 | s1 | -| main.rs:280:10:280:11 | [post] receiver for s1 | main.rs:280:10:280:11 | [post] s1 | -| main.rs:280:10:280:11 | s1 | main.rs:280:10:280:11 | receiver for s1 | -| main.rs:282:9:282:10 | [SSA] s2 | main.rs:283:10:283:11 | s2 | -| main.rs:282:9:282:10 | s2 | main.rs:282:9:282:10 | [SSA] s2 | -| main.rs:282:9:282:10 | s2 | main.rs:282:9:282:10 | s2 | -| main.rs:282:14:282:17 | None | main.rs:282:9:282:10 | s2 | -| main.rs:283:10:283:11 | [post] receiver for s2 | main.rs:283:10:283:11 | [post] s2 | -| main.rs:283:10:283:11 | s2 | main.rs:283:10:283:11 | receiver for s2 | -| main.rs:287:9:287:10 | [SSA] s1 | main.rs:289:14:289:15 | s1 | -| main.rs:287:9:287:10 | s1 | main.rs:287:9:287:10 | [SSA] s1 | -| main.rs:287:9:287:10 | s1 | main.rs:287:9:287:10 | s1 | -| main.rs:287:14:287:29 | Some(...) | main.rs:287:9:287:10 | s1 | -| main.rs:288:9:288:10 | [SSA] s2 | main.rs:291:10:291:11 | s2 | -| main.rs:288:9:288:10 | s2 | main.rs:288:9:288:10 | [SSA] s2 | -| main.rs:288:9:288:10 | s2 | main.rs:288:9:288:10 | s2 | -| main.rs:288:14:288:20 | Some(...) | main.rs:288:9:288:10 | s2 | -| main.rs:289:9:289:10 | [SSA] i1 | main.rs:290:10:290:11 | i1 | -| main.rs:289:9:289:10 | i1 | main.rs:289:9:289:10 | [SSA] i1 | -| main.rs:289:9:289:10 | i1 | main.rs:289:9:289:10 | i1 | -| main.rs:289:14:289:16 | TryExpr | main.rs:289:9:289:10 | i1 | -| main.rs:292:5:292:11 | Some(...) | main.rs:286:41:293:1 | { ... } | -| main.rs:296:9:296:10 | [SSA] r1 | main.rs:297:28:297:29 | r1 | -| main.rs:296:9:296:10 | r1 | main.rs:296:9:296:10 | [SSA] r1 | -| main.rs:296:9:296:10 | r1 | main.rs:296:9:296:10 | r1 | -| main.rs:296:32:296:45 | Ok(...) | main.rs:296:9:296:10 | r1 | -| main.rs:297:9:297:11 | [SSA] o1a | main.rs:299:10:299:12 | o1a | -| main.rs:297:9:297:11 | o1a | main.rs:297:9:297:11 | [SSA] o1a | -| main.rs:297:9:297:11 | o1a | main.rs:297:9:297:11 | o1a | -| main.rs:297:28:297:29 | [post] r1 | main.rs:298:28:298:29 | r1 | -| main.rs:297:28:297:29 | [post] receiver for r1 | main.rs:297:28:297:29 | [post] r1 | -| main.rs:297:28:297:29 | r1 | main.rs:297:28:297:29 | receiver for r1 | -| main.rs:297:28:297:29 | r1 | main.rs:298:28:298:29 | r1 | -| main.rs:297:28:297:34 | r1.ok() | main.rs:297:9:297:11 | o1a | -| main.rs:298:9:298:11 | [SSA] o1b | main.rs:300:10:300:12 | o1b | -| main.rs:298:9:298:11 | o1b | main.rs:298:9:298:11 | [SSA] o1b | -| main.rs:298:9:298:11 | o1b | main.rs:298:9:298:11 | o1b | -| main.rs:298:28:298:29 | [post] receiver for r1 | main.rs:298:28:298:29 | [post] r1 | -| main.rs:298:28:298:29 | r1 | main.rs:298:28:298:29 | receiver for r1 | -| main.rs:298:28:298:35 | r1.err() | main.rs:298:9:298:11 | o1b | -| main.rs:299:10:299:12 | [post] receiver for o1a | main.rs:299:10:299:12 | [post] o1a | -| main.rs:299:10:299:12 | o1a | main.rs:299:10:299:12 | receiver for o1a | -| main.rs:300:10:300:12 | [post] receiver for o1b | main.rs:300:10:300:12 | [post] o1b | -| main.rs:300:10:300:12 | o1b | main.rs:300:10:300:12 | receiver for o1b | -| main.rs:302:9:302:10 | [SSA] r2 | main.rs:303:28:303:29 | r2 | -| main.rs:302:9:302:10 | r2 | main.rs:302:9:302:10 | [SSA] r2 | -| main.rs:302:9:302:10 | r2 | main.rs:302:9:302:10 | r2 | -| main.rs:302:32:302:46 | Err(...) | main.rs:302:9:302:10 | r2 | -| main.rs:303:9:303:11 | [SSA] o2a | main.rs:305:10:305:12 | o2a | -| main.rs:303:9:303:11 | o2a | main.rs:303:9:303:11 | [SSA] o2a | -| main.rs:303:9:303:11 | o2a | main.rs:303:9:303:11 | o2a | -| main.rs:303:28:303:29 | [post] r2 | main.rs:304:28:304:29 | r2 | -| main.rs:303:28:303:29 | [post] receiver for r2 | main.rs:303:28:303:29 | [post] r2 | -| main.rs:303:28:303:29 | r2 | main.rs:303:28:303:29 | receiver for r2 | -| main.rs:303:28:303:29 | r2 | main.rs:304:28:304:29 | r2 | -| main.rs:303:28:303:34 | r2.ok() | main.rs:303:9:303:11 | o2a | -| main.rs:304:9:304:11 | [SSA] o2b | main.rs:306:10:306:12 | o2b | -| main.rs:304:9:304:11 | o2b | main.rs:304:9:304:11 | [SSA] o2b | -| main.rs:304:9:304:11 | o2b | main.rs:304:9:304:11 | o2b | -| main.rs:304:28:304:29 | [post] receiver for r2 | main.rs:304:28:304:29 | [post] r2 | -| main.rs:304:28:304:29 | r2 | main.rs:304:28:304:29 | receiver for r2 | -| main.rs:304:28:304:35 | r2.err() | main.rs:304:9:304:11 | o2b | -| main.rs:305:10:305:12 | [post] receiver for o2a | main.rs:305:10:305:12 | [post] o2a | -| main.rs:305:10:305:12 | o2a | main.rs:305:10:305:12 | receiver for o2a | -| main.rs:306:10:306:12 | [post] receiver for o2b | main.rs:306:10:306:12 | [post] o2b | -| main.rs:306:10:306:12 | o2b | main.rs:306:10:306:12 | receiver for o2b | -| main.rs:310:9:310:10 | [SSA] s1 | main.rs:313:14:313:15 | s1 | -| main.rs:310:9:310:10 | s1 | main.rs:310:9:310:10 | [SSA] s1 | -| main.rs:310:9:310:10 | s1 | main.rs:310:9:310:10 | s1 | -| main.rs:310:32:310:45 | Ok(...) | main.rs:310:9:310:10 | s1 | -| main.rs:311:9:311:10 | [SSA] s2 | main.rs:314:14:314:15 | s2 | -| main.rs:311:9:311:10 | s2 | main.rs:311:9:311:10 | [SSA] s2 | -| main.rs:311:9:311:10 | s2 | main.rs:311:9:311:10 | s2 | -| main.rs:311:32:311:36 | Ok(...) | main.rs:311:9:311:10 | s2 | -| main.rs:312:9:312:10 | [SSA] s3 | main.rs:317:14:317:15 | s3 | -| main.rs:312:9:312:10 | s3 | main.rs:312:9:312:10 | [SSA] s3 | -| main.rs:312:9:312:10 | s3 | main.rs:312:9:312:10 | s3 | -| main.rs:312:32:312:46 | Err(...) | main.rs:312:9:312:10 | s3 | -| main.rs:313:9:313:10 | [SSA] i1 | main.rs:315:10:315:11 | i1 | -| main.rs:313:9:313:10 | i1 | main.rs:313:9:313:10 | [SSA] i1 | -| main.rs:313:9:313:10 | i1 | main.rs:313:9:313:10 | i1 | -| main.rs:313:14:313:16 | TryExpr | main.rs:313:9:313:10 | i1 | -| main.rs:314:9:314:10 | [SSA] i2 | main.rs:316:10:316:11 | i2 | -| main.rs:314:9:314:10 | i2 | main.rs:314:9:314:10 | [SSA] i2 | -| main.rs:314:9:314:10 | i2 | main.rs:314:9:314:10 | i2 | -| main.rs:314:14:314:16 | TryExpr | main.rs:314:9:314:10 | i2 | -| main.rs:317:9:317:10 | [SSA] i3 | main.rs:318:10:318:11 | i3 | -| main.rs:317:9:317:10 | i3 | main.rs:317:9:317:10 | [SSA] i3 | -| main.rs:317:9:317:10 | i3 | main.rs:317:9:317:10 | i3 | -| main.rs:317:14:317:16 | TryExpr | main.rs:317:9:317:10 | i3 | -| main.rs:319:5:319:9 | Ok(...) | main.rs:309:46:320:1 | { ... } | -| main.rs:323:9:323:10 | [SSA] s1 | main.rs:324:10:324:11 | s1 | -| main.rs:323:9:323:10 | s1 | main.rs:323:9:323:10 | [SSA] s1 | -| main.rs:323:9:323:10 | s1 | main.rs:323:9:323:10 | s1 | -| main.rs:323:32:323:45 | Ok(...) | main.rs:323:9:323:10 | s1 | -| main.rs:324:10:324:11 | [post] receiver for s1 | main.rs:324:10:324:11 | [post] s1 | -| main.rs:324:10:324:11 | [post] s1 | main.rs:325:10:325:11 | s1 | -| main.rs:324:10:324:11 | s1 | main.rs:324:10:324:11 | receiver for s1 | -| main.rs:324:10:324:11 | s1 | main.rs:325:10:325:11 | s1 | -| main.rs:325:10:325:11 | [post] receiver for s1 | main.rs:325:10:325:11 | [post] s1 | -| main.rs:325:10:325:11 | s1 | main.rs:325:10:325:11 | receiver for s1 | -| main.rs:327:9:327:10 | [SSA] s2 | main.rs:328:10:328:11 | s2 | -| main.rs:327:9:327:10 | s2 | main.rs:327:9:327:10 | [SSA] s2 | -| main.rs:327:9:327:10 | s2 | main.rs:327:9:327:10 | s2 | -| main.rs:327:32:327:46 | Err(...) | main.rs:327:9:327:10 | s2 | -| main.rs:328:10:328:11 | [post] receiver for s2 | main.rs:328:10:328:11 | [post] s2 | -| main.rs:328:10:328:11 | [post] s2 | main.rs:329:10:329:11 | s2 | -| main.rs:328:10:328:11 | s2 | main.rs:328:10:328:11 | receiver for s2 | -| main.rs:328:10:328:11 | s2 | main.rs:329:10:329:11 | s2 | -| main.rs:329:10:329:11 | [post] receiver for s2 | main.rs:329:10:329:11 | [post] s2 | -| main.rs:329:10:329:11 | s2 | main.rs:329:10:329:11 | receiver for s2 | -| main.rs:338:9:338:10 | [SSA] s1 | main.rs:340:11:340:12 | s1 | -| main.rs:338:9:338:10 | s1 | main.rs:338:9:338:10 | [SSA] s1 | -| main.rs:338:9:338:10 | s1 | main.rs:338:9:338:10 | s1 | -| main.rs:338:14:338:39 | ...::A(...) | main.rs:338:9:338:10 | s1 | -| main.rs:339:9:339:10 | [SSA] s2 | main.rs:347:11:347:12 | s2 | +| main.rs:267:5:274:5 | if ... {...} | main.rs:265:25:275:1 | { ... } | +| main.rs:267:17:267:17 | [SSA] n | main.rs:269:18:269:18 | n | +| main.rs:267:17:267:17 | n | main.rs:267:17:267:17 | [SSA] n | +| main.rs:267:17:267:17 | n | main.rs:267:17:267:17 | n | +| main.rs:267:22:267:23 | s1 | main.rs:267:12:267:18 | Some(...) | +| main.rs:269:18:269:18 | [post] n | main.rs:273:14:273:14 | n | +| main.rs:269:18:269:18 | n | main.rs:273:14:273:14 | n | +| main.rs:270:13:270:16 | true | main.rs:268:12:271:9 | { ... } | +| main.rs:272:5:274:5 | { ... } | main.rs:267:5:274:5 | if ... {...} | +| main.rs:278:9:278:10 | [SSA] s1 | main.rs:279:10:279:11 | s1 | +| main.rs:278:9:278:10 | s1 | main.rs:278:9:278:10 | [SSA] s1 | +| main.rs:278:9:278:10 | s1 | main.rs:278:9:278:10 | s1 | +| main.rs:278:14:278:29 | Some(...) | main.rs:278:9:278:10 | s1 | +| main.rs:279:10:279:11 | [post] receiver for s1 | main.rs:279:10:279:11 | [post] s1 | +| main.rs:279:10:279:11 | s1 | main.rs:279:10:279:11 | receiver for s1 | +| main.rs:283:9:283:10 | [SSA] s1 | main.rs:284:10:284:11 | s1 | +| main.rs:283:9:283:10 | s1 | main.rs:283:9:283:10 | [SSA] s1 | +| main.rs:283:9:283:10 | s1 | main.rs:283:9:283:10 | s1 | +| main.rs:283:14:283:29 | Some(...) | main.rs:283:9:283:10 | s1 | +| main.rs:284:10:284:11 | [post] receiver for s1 | main.rs:284:10:284:11 | [post] s1 | +| main.rs:284:10:284:11 | s1 | main.rs:284:10:284:11 | receiver for s1 | +| main.rs:286:9:286:10 | [SSA] s2 | main.rs:287:10:287:11 | s2 | +| main.rs:286:9:286:10 | s2 | main.rs:286:9:286:10 | [SSA] s2 | +| main.rs:286:9:286:10 | s2 | main.rs:286:9:286:10 | s2 | +| main.rs:286:14:286:20 | Some(...) | main.rs:286:9:286:10 | s2 | +| main.rs:287:10:287:11 | [post] receiver for s2 | main.rs:287:10:287:11 | [post] s2 | +| main.rs:287:10:287:11 | s2 | main.rs:287:10:287:11 | receiver for s2 | +| main.rs:291:9:291:10 | [SSA] s1 | main.rs:292:10:292:11 | s1 | +| main.rs:291:9:291:10 | s1 | main.rs:291:9:291:10 | [SSA] s1 | +| main.rs:291:9:291:10 | s1 | main.rs:291:9:291:10 | s1 | +| main.rs:291:14:291:29 | Some(...) | main.rs:291:9:291:10 | s1 | +| main.rs:292:10:292:11 | [post] receiver for s1 | main.rs:292:10:292:11 | [post] s1 | +| main.rs:292:10:292:11 | s1 | main.rs:292:10:292:11 | receiver for s1 | +| main.rs:294:9:294:10 | [SSA] s2 | main.rs:295:10:295:11 | s2 | +| main.rs:294:9:294:10 | s2 | main.rs:294:9:294:10 | [SSA] s2 | +| main.rs:294:9:294:10 | s2 | main.rs:294:9:294:10 | s2 | +| main.rs:294:14:294:17 | None | main.rs:294:9:294:10 | s2 | +| main.rs:295:10:295:11 | [post] receiver for s2 | main.rs:295:10:295:11 | [post] s2 | +| main.rs:295:10:295:11 | s2 | main.rs:295:10:295:11 | receiver for s2 | +| main.rs:299:9:299:10 | [SSA] s1 | main.rs:301:14:301:15 | s1 | +| main.rs:299:9:299:10 | s1 | main.rs:299:9:299:10 | [SSA] s1 | +| main.rs:299:9:299:10 | s1 | main.rs:299:9:299:10 | s1 | +| main.rs:299:14:299:29 | Some(...) | main.rs:299:9:299:10 | s1 | +| main.rs:300:9:300:10 | [SSA] s2 | main.rs:303:10:303:11 | s2 | +| main.rs:300:9:300:10 | s2 | main.rs:300:9:300:10 | [SSA] s2 | +| main.rs:300:9:300:10 | s2 | main.rs:300:9:300:10 | s2 | +| main.rs:300:14:300:20 | Some(...) | main.rs:300:9:300:10 | s2 | +| main.rs:301:9:301:10 | [SSA] i1 | main.rs:302:10:302:11 | i1 | +| main.rs:301:9:301:10 | i1 | main.rs:301:9:301:10 | [SSA] i1 | +| main.rs:301:9:301:10 | i1 | main.rs:301:9:301:10 | i1 | +| main.rs:301:14:301:16 | TryExpr | main.rs:301:9:301:10 | i1 | +| main.rs:304:5:304:11 | Some(...) | main.rs:298:41:305:1 | { ... } | +| main.rs:308:9:308:10 | [SSA] r1 | main.rs:309:28:309:29 | r1 | +| main.rs:308:9:308:10 | r1 | main.rs:308:9:308:10 | [SSA] r1 | +| main.rs:308:9:308:10 | r1 | main.rs:308:9:308:10 | r1 | +| main.rs:308:32:308:45 | Ok(...) | main.rs:308:9:308:10 | r1 | +| main.rs:309:9:309:11 | [SSA] o1a | main.rs:311:10:311:12 | o1a | +| main.rs:309:9:309:11 | o1a | main.rs:309:9:309:11 | [SSA] o1a | +| main.rs:309:9:309:11 | o1a | main.rs:309:9:309:11 | o1a | +| main.rs:309:28:309:29 | [post] r1 | main.rs:310:28:310:29 | r1 | +| main.rs:309:28:309:29 | [post] receiver for r1 | main.rs:309:28:309:29 | [post] r1 | +| main.rs:309:28:309:29 | r1 | main.rs:309:28:309:29 | receiver for r1 | +| main.rs:309:28:309:29 | r1 | main.rs:310:28:310:29 | r1 | +| main.rs:309:28:309:34 | r1.ok() | main.rs:309:9:309:11 | o1a | +| main.rs:310:9:310:11 | [SSA] o1b | main.rs:312:10:312:12 | o1b | +| main.rs:310:9:310:11 | o1b | main.rs:310:9:310:11 | [SSA] o1b | +| main.rs:310:9:310:11 | o1b | main.rs:310:9:310:11 | o1b | +| main.rs:310:28:310:29 | [post] receiver for r1 | main.rs:310:28:310:29 | [post] r1 | +| main.rs:310:28:310:29 | r1 | main.rs:310:28:310:29 | receiver for r1 | +| main.rs:310:28:310:35 | r1.err() | main.rs:310:9:310:11 | o1b | +| main.rs:311:10:311:12 | [post] receiver for o1a | main.rs:311:10:311:12 | [post] o1a | +| main.rs:311:10:311:12 | o1a | main.rs:311:10:311:12 | receiver for o1a | +| main.rs:312:10:312:12 | [post] receiver for o1b | main.rs:312:10:312:12 | [post] o1b | +| main.rs:312:10:312:12 | o1b | main.rs:312:10:312:12 | receiver for o1b | +| main.rs:314:9:314:10 | [SSA] r2 | main.rs:315:28:315:29 | r2 | +| main.rs:314:9:314:10 | r2 | main.rs:314:9:314:10 | [SSA] r2 | +| main.rs:314:9:314:10 | r2 | main.rs:314:9:314:10 | r2 | +| main.rs:314:32:314:46 | Err(...) | main.rs:314:9:314:10 | r2 | +| main.rs:315:9:315:11 | [SSA] o2a | main.rs:317:10:317:12 | o2a | +| main.rs:315:9:315:11 | o2a | main.rs:315:9:315:11 | [SSA] o2a | +| main.rs:315:9:315:11 | o2a | main.rs:315:9:315:11 | o2a | +| main.rs:315:28:315:29 | [post] r2 | main.rs:316:28:316:29 | r2 | +| main.rs:315:28:315:29 | [post] receiver for r2 | main.rs:315:28:315:29 | [post] r2 | +| main.rs:315:28:315:29 | r2 | main.rs:315:28:315:29 | receiver for r2 | +| main.rs:315:28:315:29 | r2 | main.rs:316:28:316:29 | r2 | +| main.rs:315:28:315:34 | r2.ok() | main.rs:315:9:315:11 | o2a | +| main.rs:316:9:316:11 | [SSA] o2b | main.rs:318:10:318:12 | o2b | +| main.rs:316:9:316:11 | o2b | main.rs:316:9:316:11 | [SSA] o2b | +| main.rs:316:9:316:11 | o2b | main.rs:316:9:316:11 | o2b | +| main.rs:316:28:316:29 | [post] receiver for r2 | main.rs:316:28:316:29 | [post] r2 | +| main.rs:316:28:316:29 | r2 | main.rs:316:28:316:29 | receiver for r2 | +| main.rs:316:28:316:35 | r2.err() | main.rs:316:9:316:11 | o2b | +| main.rs:317:10:317:12 | [post] receiver for o2a | main.rs:317:10:317:12 | [post] o2a | +| main.rs:317:10:317:12 | o2a | main.rs:317:10:317:12 | receiver for o2a | +| main.rs:318:10:318:12 | [post] receiver for o2b | main.rs:318:10:318:12 | [post] o2b | +| main.rs:318:10:318:12 | o2b | main.rs:318:10:318:12 | receiver for o2b | +| main.rs:322:9:322:10 | [SSA] s1 | main.rs:325:14:325:15 | s1 | +| main.rs:322:9:322:10 | s1 | main.rs:322:9:322:10 | [SSA] s1 | +| main.rs:322:9:322:10 | s1 | main.rs:322:9:322:10 | s1 | +| main.rs:322:32:322:45 | Ok(...) | main.rs:322:9:322:10 | s1 | +| main.rs:323:9:323:10 | [SSA] s2 | main.rs:326:14:326:15 | s2 | +| main.rs:323:9:323:10 | s2 | main.rs:323:9:323:10 | [SSA] s2 | +| main.rs:323:9:323:10 | s2 | main.rs:323:9:323:10 | s2 | +| main.rs:323:32:323:36 | Ok(...) | main.rs:323:9:323:10 | s2 | +| main.rs:324:9:324:10 | [SSA] s3 | main.rs:329:14:329:15 | s3 | +| main.rs:324:9:324:10 | s3 | main.rs:324:9:324:10 | [SSA] s3 | +| main.rs:324:9:324:10 | s3 | main.rs:324:9:324:10 | s3 | +| main.rs:324:32:324:46 | Err(...) | main.rs:324:9:324:10 | s3 | +| main.rs:325:9:325:10 | [SSA] i1 | main.rs:327:10:327:11 | i1 | +| main.rs:325:9:325:10 | i1 | main.rs:325:9:325:10 | [SSA] i1 | +| main.rs:325:9:325:10 | i1 | main.rs:325:9:325:10 | i1 | +| main.rs:325:14:325:16 | TryExpr | main.rs:325:9:325:10 | i1 | +| main.rs:326:9:326:10 | [SSA] i2 | main.rs:328:10:328:11 | i2 | +| main.rs:326:9:326:10 | i2 | main.rs:326:9:326:10 | [SSA] i2 | +| main.rs:326:9:326:10 | i2 | main.rs:326:9:326:10 | i2 | +| main.rs:326:14:326:16 | TryExpr | main.rs:326:9:326:10 | i2 | +| main.rs:329:9:329:10 | [SSA] i3 | main.rs:330:10:330:11 | i3 | +| main.rs:329:9:329:10 | i3 | main.rs:329:9:329:10 | [SSA] i3 | +| main.rs:329:9:329:10 | i3 | main.rs:329:9:329:10 | i3 | +| main.rs:329:14:329:16 | TryExpr | main.rs:329:9:329:10 | i3 | +| main.rs:331:5:331:9 | Ok(...) | main.rs:321:46:332:1 | { ... } | +| main.rs:335:9:335:10 | [SSA] s1 | main.rs:336:10:336:11 | s1 | +| main.rs:335:9:335:10 | s1 | main.rs:335:9:335:10 | [SSA] s1 | +| main.rs:335:9:335:10 | s1 | main.rs:335:9:335:10 | s1 | +| main.rs:335:32:335:45 | Ok(...) | main.rs:335:9:335:10 | s1 | +| main.rs:336:10:336:11 | [post] receiver for s1 | main.rs:336:10:336:11 | [post] s1 | +| main.rs:336:10:336:11 | [post] s1 | main.rs:337:10:337:11 | s1 | +| main.rs:336:10:336:11 | s1 | main.rs:336:10:336:11 | receiver for s1 | +| main.rs:336:10:336:11 | s1 | main.rs:337:10:337:11 | s1 | +| main.rs:337:10:337:11 | [post] receiver for s1 | main.rs:337:10:337:11 | [post] s1 | +| main.rs:337:10:337:11 | s1 | main.rs:337:10:337:11 | receiver for s1 | +| main.rs:339:9:339:10 | [SSA] s2 | main.rs:340:10:340:11 | s2 | | main.rs:339:9:339:10 | s2 | main.rs:339:9:339:10 | [SSA] s2 | | main.rs:339:9:339:10 | s2 | main.rs:339:9:339:10 | s2 | -| main.rs:339:14:339:30 | ...::B(...) | main.rs:339:9:339:10 | s2 | -| main.rs:340:11:340:12 | s1 | main.rs:341:9:341:25 | ...::A(...) | -| main.rs:340:11:340:12 | s1 | main.rs:342:9:342:25 | ...::B(...) | -| main.rs:340:11:340:12 | s1 | main.rs:344:11:344:12 | s1 | -| main.rs:341:24:341:24 | [SSA] n | main.rs:341:35:341:35 | n | -| main.rs:341:24:341:24 | n | main.rs:341:24:341:24 | [SSA] n | -| main.rs:341:24:341:24 | n | main.rs:341:24:341:24 | n | -| main.rs:341:30:341:36 | sink(...) | main.rs:340:5:343:5 | match s1 { ... } | -| main.rs:342:24:342:24 | [SSA] n | main.rs:342:35:342:35 | n | -| main.rs:342:24:342:24 | n | main.rs:342:24:342:24 | [SSA] n | -| main.rs:342:24:342:24 | n | main.rs:342:24:342:24 | n | -| main.rs:342:30:342:36 | sink(...) | main.rs:340:5:343:5 | match s1 { ... } | -| main.rs:344:11:344:12 | s1 | main.rs:345:9:345:45 | ... \| ... | -| main.rs:345:9:345:45 | ... \| ... | main.rs:345:9:345:25 | ...::A(...) | -| main.rs:345:9:345:45 | ... \| ... | main.rs:345:29:345:45 | ...::B(...) | -| main.rs:345:24:345:24 | [SSA] n | main.rs:345:55:345:55 | n | -| main.rs:345:24:345:24 | n | main.rs:345:24:345:24 | [SSA] n | -| main.rs:345:24:345:24 | n | main.rs:345:24:345:24 | n | -| main.rs:345:44:345:44 | [SSA] n | main.rs:345:55:345:55 | n | -| main.rs:345:44:345:44 | n | main.rs:345:44:345:44 | [SSA] n | -| main.rs:345:44:345:44 | n | main.rs:345:44:345:44 | n | -| main.rs:345:50:345:56 | sink(...) | main.rs:344:5:346:5 | match s1 { ... } | -| main.rs:347:5:350:5 | match s2 { ... } | main.rs:337:48:351:1 | { ... } | -| main.rs:347:11:347:12 | s2 | main.rs:348:9:348:25 | ...::A(...) | -| main.rs:347:11:347:12 | s2 | main.rs:349:9:349:25 | ...::B(...) | -| main.rs:348:24:348:24 | [SSA] n | main.rs:348:35:348:35 | n | -| main.rs:348:24:348:24 | n | main.rs:348:24:348:24 | [SSA] n | -| main.rs:348:24:348:24 | n | main.rs:348:24:348:24 | n | -| main.rs:348:30:348:36 | sink(...) | main.rs:347:5:350:5 | match s2 { ... } | -| main.rs:349:24:349:24 | [SSA] n | main.rs:349:35:349:35 | n | -| main.rs:349:24:349:24 | n | main.rs:349:24:349:24 | [SSA] n | -| main.rs:349:24:349:24 | n | main.rs:349:24:349:24 | n | -| main.rs:349:30:349:36 | sink(...) | main.rs:347:5:350:5 | match s2 { ... } | -| main.rs:356:9:356:10 | [SSA] s1 | main.rs:358:11:358:12 | s1 | -| main.rs:356:9:356:10 | s1 | main.rs:356:9:356:10 | [SSA] s1 | -| main.rs:356:9:356:10 | s1 | main.rs:356:9:356:10 | s1 | -| main.rs:356:14:356:26 | A(...) | main.rs:356:9:356:10 | s1 | -| main.rs:357:9:357:10 | [SSA] s2 | main.rs:365:11:365:12 | s2 | -| main.rs:357:9:357:10 | s2 | main.rs:357:9:357:10 | [SSA] s2 | -| main.rs:357:9:357:10 | s2 | main.rs:357:9:357:10 | s2 | -| main.rs:357:14:357:17 | B(...) | main.rs:357:9:357:10 | s2 | -| main.rs:358:11:358:12 | s1 | main.rs:359:9:359:12 | A(...) | -| main.rs:358:11:358:12 | s1 | main.rs:360:9:360:12 | B(...) | -| main.rs:358:11:358:12 | s1 | main.rs:362:11:362:12 | s1 | -| main.rs:359:11:359:11 | [SSA] n | main.rs:359:22:359:22 | n | -| main.rs:359:11:359:11 | n | main.rs:359:11:359:11 | [SSA] n | -| main.rs:359:11:359:11 | n | main.rs:359:11:359:11 | n | -| main.rs:359:17:359:23 | sink(...) | main.rs:358:5:361:5 | match s1 { ... } | -| main.rs:360:11:360:11 | [SSA] n | main.rs:360:22:360:22 | n | -| main.rs:360:11:360:11 | n | main.rs:360:11:360:11 | [SSA] n | -| main.rs:360:11:360:11 | n | main.rs:360:11:360:11 | n | -| main.rs:360:17:360:23 | sink(...) | main.rs:358:5:361:5 | match s1 { ... } | -| main.rs:362:11:362:12 | s1 | main.rs:363:9:363:19 | ... \| ... | -| main.rs:363:9:363:19 | ... \| ... | main.rs:363:9:363:12 | A(...) | -| main.rs:363:9:363:19 | ... \| ... | main.rs:363:16:363:19 | B(...) | -| main.rs:363:11:363:11 | [SSA] n | main.rs:363:29:363:29 | n | -| main.rs:363:11:363:11 | n | main.rs:363:11:363:11 | [SSA] n | -| main.rs:363:11:363:11 | n | main.rs:363:11:363:11 | n | -| main.rs:363:18:363:18 | [SSA] n | main.rs:363:29:363:29 | n | -| main.rs:363:18:363:18 | n | main.rs:363:18:363:18 | [SSA] n | -| main.rs:363:18:363:18 | n | main.rs:363:18:363:18 | n | -| main.rs:363:24:363:30 | sink(...) | main.rs:362:5:364:5 | match s1 { ... } | -| main.rs:365:5:368:5 | match s2 { ... } | main.rs:355:50:369:1 | { ... } | -| main.rs:365:11:365:12 | s2 | main.rs:366:9:366:12 | A(...) | -| main.rs:365:11:365:12 | s2 | main.rs:367:9:367:12 | B(...) | -| main.rs:366:11:366:11 | [SSA] n | main.rs:366:22:366:22 | n | -| main.rs:366:11:366:11 | n | main.rs:366:11:366:11 | [SSA] n | -| main.rs:366:11:366:11 | n | main.rs:366:11:366:11 | n | -| main.rs:366:17:366:23 | sink(...) | main.rs:365:5:368:5 | match s2 { ... } | -| main.rs:367:11:367:11 | [SSA] n | main.rs:367:22:367:22 | n | -| main.rs:367:11:367:11 | n | main.rs:367:11:367:11 | [SSA] n | -| main.rs:367:11:367:11 | n | main.rs:367:11:367:11 | n | -| main.rs:367:17:367:23 | sink(...) | main.rs:365:5:368:5 | match s2 { ... } | -| main.rs:377:9:377:10 | [SSA] s1 | main.rs:381:11:381:12 | s1 | -| main.rs:377:9:377:10 | s1 | main.rs:377:9:377:10 | [SSA] s1 | -| main.rs:377:9:377:10 | s1 | main.rs:377:9:377:10 | s1 | -| main.rs:377:14:379:5 | ...::C {...} | main.rs:377:9:377:10 | s1 | -| main.rs:380:9:380:10 | [SSA] s2 | main.rs:388:11:388:12 | s2 | -| main.rs:380:9:380:10 | s2 | main.rs:380:9:380:10 | [SSA] s2 | -| main.rs:380:9:380:10 | s2 | main.rs:380:9:380:10 | s2 | -| main.rs:380:14:380:43 | ...::D {...} | main.rs:380:9:380:10 | s2 | -| main.rs:381:11:381:12 | s1 | main.rs:382:9:382:38 | ...::C {...} | -| main.rs:381:11:381:12 | s1 | main.rs:383:9:383:38 | ...::D {...} | -| main.rs:381:11:381:12 | s1 | main.rs:385:11:385:12 | s1 | -| main.rs:382:36:382:36 | [SSA] n | main.rs:382:48:382:48 | n | -| main.rs:382:36:382:36 | n | main.rs:382:36:382:36 | [SSA] n | -| main.rs:382:36:382:36 | n | main.rs:382:36:382:36 | n | -| main.rs:382:43:382:49 | sink(...) | main.rs:381:5:384:5 | match s1 { ... } | -| main.rs:383:36:383:36 | [SSA] n | main.rs:383:48:383:48 | n | -| main.rs:383:36:383:36 | n | main.rs:383:36:383:36 | [SSA] n | -| main.rs:383:36:383:36 | n | main.rs:383:36:383:36 | n | -| main.rs:383:43:383:49 | sink(...) | main.rs:381:5:384:5 | match s1 { ... } | -| main.rs:385:11:385:12 | s1 | main.rs:386:9:386:71 | ... \| ... | -| main.rs:386:9:386:71 | ... \| ... | main.rs:386:9:386:38 | ...::C {...} | -| main.rs:386:9:386:71 | ... \| ... | main.rs:386:42:386:71 | ...::D {...} | -| main.rs:386:36:386:36 | [SSA] n | main.rs:386:81:386:81 | n | -| main.rs:386:36:386:36 | n | main.rs:386:36:386:36 | [SSA] n | -| main.rs:386:36:386:36 | n | main.rs:386:36:386:36 | n | -| main.rs:386:69:386:69 | [SSA] n | main.rs:386:81:386:81 | n | -| main.rs:386:69:386:69 | n | main.rs:386:69:386:69 | [SSA] n | -| main.rs:386:69:386:69 | n | main.rs:386:69:386:69 | n | -| main.rs:386:76:386:82 | sink(...) | main.rs:385:5:387:5 | match s1 { ... } | -| main.rs:388:5:391:5 | match s2 { ... } | main.rs:376:49:392:1 | { ... } | -| main.rs:388:11:388:12 | s2 | main.rs:389:9:389:38 | ...::C {...} | -| main.rs:388:11:388:12 | s2 | main.rs:390:9:390:38 | ...::D {...} | -| main.rs:389:36:389:36 | [SSA] n | main.rs:389:48:389:48 | n | -| main.rs:389:36:389:36 | n | main.rs:389:36:389:36 | [SSA] n | -| main.rs:389:36:389:36 | n | main.rs:389:36:389:36 | n | -| main.rs:389:43:389:49 | sink(...) | main.rs:388:5:391:5 | match s2 { ... } | -| main.rs:390:36:390:36 | [SSA] n | main.rs:390:48:390:48 | n | -| main.rs:390:36:390:36 | n | main.rs:390:36:390:36 | [SSA] n | -| main.rs:390:36:390:36 | n | main.rs:390:36:390:36 | n | -| main.rs:390:43:390:49 | sink(...) | main.rs:388:5:391:5 | match s2 { ... } | -| main.rs:397:9:397:10 | [SSA] s1 | main.rs:401:11:401:12 | s1 | -| main.rs:397:9:397:10 | s1 | main.rs:397:9:397:10 | [SSA] s1 | -| main.rs:397:9:397:10 | s1 | main.rs:397:9:397:10 | s1 | -| main.rs:397:14:399:5 | C {...} | main.rs:397:9:397:10 | s1 | -| main.rs:400:9:400:10 | [SSA] s2 | main.rs:408:11:408:12 | s2 | -| main.rs:400:9:400:10 | s2 | main.rs:400:9:400:10 | [SSA] s2 | -| main.rs:400:9:400:10 | s2 | main.rs:400:9:400:10 | s2 | -| main.rs:400:14:400:29 | D {...} | main.rs:400:9:400:10 | s2 | -| main.rs:401:11:401:12 | s1 | main.rs:402:9:402:24 | C {...} | -| main.rs:401:11:401:12 | s1 | main.rs:403:9:403:24 | D {...} | -| main.rs:401:11:401:12 | s1 | main.rs:405:11:405:12 | s1 | -| main.rs:402:22:402:22 | [SSA] n | main.rs:402:34:402:34 | n | -| main.rs:402:22:402:22 | n | main.rs:402:22:402:22 | [SSA] n | -| main.rs:402:22:402:22 | n | main.rs:402:22:402:22 | n | -| main.rs:402:29:402:35 | sink(...) | main.rs:401:5:404:5 | match s1 { ... } | -| main.rs:403:22:403:22 | [SSA] n | main.rs:403:34:403:34 | n | -| main.rs:403:22:403:22 | n | main.rs:403:22:403:22 | [SSA] n | -| main.rs:403:22:403:22 | n | main.rs:403:22:403:22 | n | -| main.rs:403:29:403:35 | sink(...) | main.rs:401:5:404:5 | match s1 { ... } | -| main.rs:405:11:405:12 | s1 | main.rs:406:9:406:43 | ... \| ... | -| main.rs:406:9:406:43 | ... \| ... | main.rs:406:9:406:24 | C {...} | -| main.rs:406:9:406:43 | ... \| ... | main.rs:406:28:406:43 | D {...} | -| main.rs:406:22:406:22 | [SSA] n | main.rs:406:53:406:53 | n | -| main.rs:406:22:406:22 | n | main.rs:406:22:406:22 | [SSA] n | -| main.rs:406:22:406:22 | n | main.rs:406:22:406:22 | n | -| main.rs:406:41:406:41 | [SSA] n | main.rs:406:53:406:53 | n | -| main.rs:406:41:406:41 | n | main.rs:406:41:406:41 | [SSA] n | -| main.rs:406:41:406:41 | n | main.rs:406:41:406:41 | n | -| main.rs:406:48:406:54 | sink(...) | main.rs:405:5:407:5 | match s1 { ... } | -| main.rs:408:5:411:5 | match s2 { ... } | main.rs:396:51:412:1 | { ... } | -| main.rs:408:11:408:12 | s2 | main.rs:409:9:409:24 | C {...} | -| main.rs:408:11:408:12 | s2 | main.rs:410:9:410:24 | D {...} | -| main.rs:409:22:409:22 | [SSA] n | main.rs:409:34:409:34 | n | -| main.rs:409:22:409:22 | n | main.rs:409:22:409:22 | [SSA] n | -| main.rs:409:22:409:22 | n | main.rs:409:22:409:22 | n | -| main.rs:409:29:409:35 | sink(...) | main.rs:408:5:411:5 | match s2 { ... } | -| main.rs:410:22:410:22 | [SSA] n | main.rs:410:34:410:34 | n | -| main.rs:410:22:410:22 | n | main.rs:410:22:410:22 | [SSA] n | -| main.rs:410:22:410:22 | n | main.rs:410:22:410:22 | n | -| main.rs:410:29:410:35 | sink(...) | main.rs:408:5:411:5 | match s2 { ... } | -| main.rs:418:9:418:12 | [SSA] arr1 | main.rs:419:14:419:17 | arr1 | -| main.rs:418:9:418:12 | arr1 | main.rs:418:9:418:12 | [SSA] arr1 | -| main.rs:418:9:418:12 | arr1 | main.rs:418:9:418:12 | arr1 | -| main.rs:418:16:418:33 | [...] | main.rs:418:9:418:12 | arr1 | -| main.rs:419:9:419:10 | [SSA] n1 | main.rs:420:10:420:11 | n1 | -| main.rs:419:9:419:10 | n1 | main.rs:419:9:419:10 | [SSA] n1 | -| main.rs:419:9:419:10 | n1 | main.rs:419:9:419:10 | n1 | -| main.rs:419:14:419:20 | arr1[2] | main.rs:419:9:419:10 | n1 | -| main.rs:422:9:422:12 | [SSA] arr2 | main.rs:423:14:423:17 | arr2 | -| main.rs:422:9:422:12 | arr2 | main.rs:422:9:422:12 | [SSA] arr2 | -| main.rs:422:9:422:12 | arr2 | main.rs:422:9:422:12 | arr2 | -| main.rs:422:16:422:31 | [...; 10] | main.rs:422:9:422:12 | arr2 | -| main.rs:423:9:423:10 | [SSA] n2 | main.rs:424:10:424:11 | n2 | -| main.rs:423:9:423:10 | n2 | main.rs:423:9:423:10 | [SSA] n2 | -| main.rs:423:9:423:10 | n2 | main.rs:423:9:423:10 | n2 | -| main.rs:423:14:423:20 | arr2[4] | main.rs:423:9:423:10 | n2 | -| main.rs:426:9:426:12 | [SSA] arr3 | main.rs:427:14:427:17 | arr3 | -| main.rs:426:9:426:12 | arr3 | main.rs:426:9:426:12 | [SSA] arr3 | -| main.rs:426:9:426:12 | arr3 | main.rs:426:9:426:12 | arr3 | -| main.rs:426:16:426:24 | [...] | main.rs:426:9:426:12 | arr3 | -| main.rs:427:9:427:10 | [SSA] n3 | main.rs:428:10:428:11 | n3 | -| main.rs:427:9:427:10 | n3 | main.rs:427:9:427:10 | [SSA] n3 | -| main.rs:427:9:427:10 | n3 | main.rs:427:9:427:10 | n3 | -| main.rs:427:14:427:20 | arr3[2] | main.rs:427:9:427:10 | n3 | -| main.rs:432:9:432:12 | [SSA] arr1 | main.rs:433:15:433:18 | arr1 | -| main.rs:432:9:432:12 | arr1 | main.rs:432:9:432:12 | [SSA] arr1 | -| main.rs:432:9:432:12 | arr1 | main.rs:432:9:432:12 | arr1 | -| main.rs:432:16:432:33 | [...] | main.rs:432:9:432:12 | arr1 | -| main.rs:433:9:433:10 | [SSA] n1 | main.rs:434:14:434:15 | n1 | -| main.rs:433:9:433:10 | n1 | main.rs:433:9:433:10 | [SSA] n1 | -| main.rs:433:9:433:10 | n1 | main.rs:433:9:433:10 | n1 | -| main.rs:437:9:437:12 | [SSA] arr2 | main.rs:438:15:438:18 | arr2 | -| main.rs:437:9:437:12 | arr2 | main.rs:437:9:437:12 | [SSA] arr2 | -| main.rs:437:9:437:12 | arr2 | main.rs:437:9:437:12 | arr2 | -| main.rs:437:16:437:24 | [...] | main.rs:437:9:437:12 | arr2 | -| main.rs:438:5:440:5 | for ... in ... { ... } | main.rs:431:21:441:1 | { ... } | -| main.rs:438:9:438:10 | [SSA] n2 | main.rs:439:14:439:15 | n2 | -| main.rs:438:9:438:10 | n2 | main.rs:438:9:438:10 | [SSA] n2 | -| main.rs:438:9:438:10 | n2 | main.rs:438:9:438:10 | n2 | -| main.rs:444:9:444:12 | [SSA] arr1 | main.rs:445:11:445:14 | arr1 | +| main.rs:339:32:339:46 | Err(...) | main.rs:339:9:339:10 | s2 | +| main.rs:340:10:340:11 | [post] receiver for s2 | main.rs:340:10:340:11 | [post] s2 | +| main.rs:340:10:340:11 | [post] s2 | main.rs:341:10:341:11 | s2 | +| main.rs:340:10:340:11 | s2 | main.rs:340:10:340:11 | receiver for s2 | +| main.rs:340:10:340:11 | s2 | main.rs:341:10:341:11 | s2 | +| main.rs:341:10:341:11 | [post] receiver for s2 | main.rs:341:10:341:11 | [post] s2 | +| main.rs:341:10:341:11 | s2 | main.rs:341:10:341:11 | receiver for s2 | +| main.rs:350:9:350:10 | [SSA] s1 | main.rs:352:11:352:12 | s1 | +| main.rs:350:9:350:10 | s1 | main.rs:350:9:350:10 | [SSA] s1 | +| main.rs:350:9:350:10 | s1 | main.rs:350:9:350:10 | s1 | +| main.rs:350:14:350:39 | ...::A(...) | main.rs:350:9:350:10 | s1 | +| main.rs:351:9:351:10 | [SSA] s2 | main.rs:359:11:359:12 | s2 | +| main.rs:351:9:351:10 | s2 | main.rs:351:9:351:10 | [SSA] s2 | +| main.rs:351:9:351:10 | s2 | main.rs:351:9:351:10 | s2 | +| main.rs:351:14:351:30 | ...::B(...) | main.rs:351:9:351:10 | s2 | +| main.rs:352:11:352:12 | s1 | main.rs:353:9:353:25 | ...::A(...) | +| main.rs:352:11:352:12 | s1 | main.rs:354:9:354:25 | ...::B(...) | +| main.rs:352:11:352:12 | s1 | main.rs:356:11:356:12 | s1 | +| main.rs:353:24:353:24 | [SSA] n | main.rs:353:35:353:35 | n | +| main.rs:353:24:353:24 | n | main.rs:353:24:353:24 | [SSA] n | +| main.rs:353:24:353:24 | n | main.rs:353:24:353:24 | n | +| main.rs:353:30:353:36 | sink(...) | main.rs:352:5:355:5 | match s1 { ... } | +| main.rs:354:24:354:24 | [SSA] n | main.rs:354:35:354:35 | n | +| main.rs:354:24:354:24 | n | main.rs:354:24:354:24 | [SSA] n | +| main.rs:354:24:354:24 | n | main.rs:354:24:354:24 | n | +| main.rs:354:30:354:36 | sink(...) | main.rs:352:5:355:5 | match s1 { ... } | +| main.rs:356:11:356:12 | s1 | main.rs:357:9:357:45 | ... \| ... | +| main.rs:357:9:357:45 | ... \| ... | main.rs:357:9:357:25 | ...::A(...) | +| main.rs:357:9:357:45 | ... \| ... | main.rs:357:29:357:45 | ...::B(...) | +| main.rs:357:24:357:24 | [SSA] n | main.rs:357:55:357:55 | n | +| main.rs:357:24:357:24 | n | main.rs:357:24:357:24 | [SSA] n | +| main.rs:357:24:357:24 | n | main.rs:357:24:357:24 | n | +| main.rs:357:44:357:44 | [SSA] n | main.rs:357:55:357:55 | n | +| main.rs:357:44:357:44 | n | main.rs:357:44:357:44 | [SSA] n | +| main.rs:357:44:357:44 | n | main.rs:357:44:357:44 | n | +| main.rs:357:50:357:56 | sink(...) | main.rs:356:5:358:5 | match s1 { ... } | +| main.rs:359:5:362:5 | match s2 { ... } | main.rs:349:48:363:1 | { ... } | +| main.rs:359:11:359:12 | s2 | main.rs:360:9:360:25 | ...::A(...) | +| main.rs:359:11:359:12 | s2 | main.rs:361:9:361:25 | ...::B(...) | +| main.rs:360:24:360:24 | [SSA] n | main.rs:360:35:360:35 | n | +| main.rs:360:24:360:24 | n | main.rs:360:24:360:24 | [SSA] n | +| main.rs:360:24:360:24 | n | main.rs:360:24:360:24 | n | +| main.rs:360:30:360:36 | sink(...) | main.rs:359:5:362:5 | match s2 { ... } | +| main.rs:361:24:361:24 | [SSA] n | main.rs:361:35:361:35 | n | +| main.rs:361:24:361:24 | n | main.rs:361:24:361:24 | [SSA] n | +| main.rs:361:24:361:24 | n | main.rs:361:24:361:24 | n | +| main.rs:361:30:361:36 | sink(...) | main.rs:359:5:362:5 | match s2 { ... } | +| main.rs:368:9:368:10 | [SSA] s1 | main.rs:370:11:370:12 | s1 | +| main.rs:368:9:368:10 | s1 | main.rs:368:9:368:10 | [SSA] s1 | +| main.rs:368:9:368:10 | s1 | main.rs:368:9:368:10 | s1 | +| main.rs:368:14:368:26 | A(...) | main.rs:368:9:368:10 | s1 | +| main.rs:369:9:369:10 | [SSA] s2 | main.rs:377:11:377:12 | s2 | +| main.rs:369:9:369:10 | s2 | main.rs:369:9:369:10 | [SSA] s2 | +| main.rs:369:9:369:10 | s2 | main.rs:369:9:369:10 | s2 | +| main.rs:369:14:369:17 | B(...) | main.rs:369:9:369:10 | s2 | +| main.rs:370:11:370:12 | s1 | main.rs:371:9:371:12 | A(...) | +| main.rs:370:11:370:12 | s1 | main.rs:372:9:372:12 | B(...) | +| main.rs:370:11:370:12 | s1 | main.rs:374:11:374:12 | s1 | +| main.rs:371:11:371:11 | [SSA] n | main.rs:371:22:371:22 | n | +| main.rs:371:11:371:11 | n | main.rs:371:11:371:11 | [SSA] n | +| main.rs:371:11:371:11 | n | main.rs:371:11:371:11 | n | +| main.rs:371:17:371:23 | sink(...) | main.rs:370:5:373:5 | match s1 { ... } | +| main.rs:372:11:372:11 | [SSA] n | main.rs:372:22:372:22 | n | +| main.rs:372:11:372:11 | n | main.rs:372:11:372:11 | [SSA] n | +| main.rs:372:11:372:11 | n | main.rs:372:11:372:11 | n | +| main.rs:372:17:372:23 | sink(...) | main.rs:370:5:373:5 | match s1 { ... } | +| main.rs:374:11:374:12 | s1 | main.rs:375:9:375:19 | ... \| ... | +| main.rs:375:9:375:19 | ... \| ... | main.rs:375:9:375:12 | A(...) | +| main.rs:375:9:375:19 | ... \| ... | main.rs:375:16:375:19 | B(...) | +| main.rs:375:11:375:11 | [SSA] n | main.rs:375:29:375:29 | n | +| main.rs:375:11:375:11 | n | main.rs:375:11:375:11 | [SSA] n | +| main.rs:375:11:375:11 | n | main.rs:375:11:375:11 | n | +| main.rs:375:18:375:18 | [SSA] n | main.rs:375:29:375:29 | n | +| main.rs:375:18:375:18 | n | main.rs:375:18:375:18 | [SSA] n | +| main.rs:375:18:375:18 | n | main.rs:375:18:375:18 | n | +| main.rs:375:24:375:30 | sink(...) | main.rs:374:5:376:5 | match s1 { ... } | +| main.rs:377:5:380:5 | match s2 { ... } | main.rs:367:50:381:1 | { ... } | +| main.rs:377:11:377:12 | s2 | main.rs:378:9:378:12 | A(...) | +| main.rs:377:11:377:12 | s2 | main.rs:379:9:379:12 | B(...) | +| main.rs:378:11:378:11 | [SSA] n | main.rs:378:22:378:22 | n | +| main.rs:378:11:378:11 | n | main.rs:378:11:378:11 | [SSA] n | +| main.rs:378:11:378:11 | n | main.rs:378:11:378:11 | n | +| main.rs:378:17:378:23 | sink(...) | main.rs:377:5:380:5 | match s2 { ... } | +| main.rs:379:11:379:11 | [SSA] n | main.rs:379:22:379:22 | n | +| main.rs:379:11:379:11 | n | main.rs:379:11:379:11 | [SSA] n | +| main.rs:379:11:379:11 | n | main.rs:379:11:379:11 | n | +| main.rs:379:17:379:23 | sink(...) | main.rs:377:5:380:5 | match s2 { ... } | +| main.rs:389:9:389:10 | [SSA] s1 | main.rs:393:11:393:12 | s1 | +| main.rs:389:9:389:10 | s1 | main.rs:389:9:389:10 | [SSA] s1 | +| main.rs:389:9:389:10 | s1 | main.rs:389:9:389:10 | s1 | +| main.rs:389:14:391:5 | ...::C {...} | main.rs:389:9:389:10 | s1 | +| main.rs:392:9:392:10 | [SSA] s2 | main.rs:400:11:400:12 | s2 | +| main.rs:392:9:392:10 | s2 | main.rs:392:9:392:10 | [SSA] s2 | +| main.rs:392:9:392:10 | s2 | main.rs:392:9:392:10 | s2 | +| main.rs:392:14:392:43 | ...::D {...} | main.rs:392:9:392:10 | s2 | +| main.rs:393:11:393:12 | s1 | main.rs:394:9:394:38 | ...::C {...} | +| main.rs:393:11:393:12 | s1 | main.rs:395:9:395:38 | ...::D {...} | +| main.rs:393:11:393:12 | s1 | main.rs:397:11:397:12 | s1 | +| main.rs:394:36:394:36 | [SSA] n | main.rs:394:48:394:48 | n | +| main.rs:394:36:394:36 | n | main.rs:394:36:394:36 | [SSA] n | +| main.rs:394:36:394:36 | n | main.rs:394:36:394:36 | n | +| main.rs:394:43:394:49 | sink(...) | main.rs:393:5:396:5 | match s1 { ... } | +| main.rs:395:36:395:36 | [SSA] n | main.rs:395:48:395:48 | n | +| main.rs:395:36:395:36 | n | main.rs:395:36:395:36 | [SSA] n | +| main.rs:395:36:395:36 | n | main.rs:395:36:395:36 | n | +| main.rs:395:43:395:49 | sink(...) | main.rs:393:5:396:5 | match s1 { ... } | +| main.rs:397:11:397:12 | s1 | main.rs:398:9:398:71 | ... \| ... | +| main.rs:398:9:398:71 | ... \| ... | main.rs:398:9:398:38 | ...::C {...} | +| main.rs:398:9:398:71 | ... \| ... | main.rs:398:42:398:71 | ...::D {...} | +| main.rs:398:36:398:36 | [SSA] n | main.rs:398:81:398:81 | n | +| main.rs:398:36:398:36 | n | main.rs:398:36:398:36 | [SSA] n | +| main.rs:398:36:398:36 | n | main.rs:398:36:398:36 | n | +| main.rs:398:69:398:69 | [SSA] n | main.rs:398:81:398:81 | n | +| main.rs:398:69:398:69 | n | main.rs:398:69:398:69 | [SSA] n | +| main.rs:398:69:398:69 | n | main.rs:398:69:398:69 | n | +| main.rs:398:76:398:82 | sink(...) | main.rs:397:5:399:5 | match s1 { ... } | +| main.rs:400:5:403:5 | match s2 { ... } | main.rs:388:49:404:1 | { ... } | +| main.rs:400:11:400:12 | s2 | main.rs:401:9:401:38 | ...::C {...} | +| main.rs:400:11:400:12 | s2 | main.rs:402:9:402:38 | ...::D {...} | +| main.rs:401:36:401:36 | [SSA] n | main.rs:401:48:401:48 | n | +| main.rs:401:36:401:36 | n | main.rs:401:36:401:36 | [SSA] n | +| main.rs:401:36:401:36 | n | main.rs:401:36:401:36 | n | +| main.rs:401:43:401:49 | sink(...) | main.rs:400:5:403:5 | match s2 { ... } | +| main.rs:402:36:402:36 | [SSA] n | main.rs:402:48:402:48 | n | +| main.rs:402:36:402:36 | n | main.rs:402:36:402:36 | [SSA] n | +| main.rs:402:36:402:36 | n | main.rs:402:36:402:36 | n | +| main.rs:402:43:402:49 | sink(...) | main.rs:400:5:403:5 | match s2 { ... } | +| main.rs:409:9:409:10 | [SSA] s1 | main.rs:413:11:413:12 | s1 | +| main.rs:409:9:409:10 | s1 | main.rs:409:9:409:10 | [SSA] s1 | +| main.rs:409:9:409:10 | s1 | main.rs:409:9:409:10 | s1 | +| main.rs:409:14:411:5 | C {...} | main.rs:409:9:409:10 | s1 | +| main.rs:412:9:412:10 | [SSA] s2 | main.rs:420:11:420:12 | s2 | +| main.rs:412:9:412:10 | s2 | main.rs:412:9:412:10 | [SSA] s2 | +| main.rs:412:9:412:10 | s2 | main.rs:412:9:412:10 | s2 | +| main.rs:412:14:412:29 | D {...} | main.rs:412:9:412:10 | s2 | +| main.rs:413:11:413:12 | s1 | main.rs:414:9:414:24 | C {...} | +| main.rs:413:11:413:12 | s1 | main.rs:415:9:415:24 | D {...} | +| main.rs:413:11:413:12 | s1 | main.rs:417:11:417:12 | s1 | +| main.rs:414:22:414:22 | [SSA] n | main.rs:414:34:414:34 | n | +| main.rs:414:22:414:22 | n | main.rs:414:22:414:22 | [SSA] n | +| main.rs:414:22:414:22 | n | main.rs:414:22:414:22 | n | +| main.rs:414:29:414:35 | sink(...) | main.rs:413:5:416:5 | match s1 { ... } | +| main.rs:415:22:415:22 | [SSA] n | main.rs:415:34:415:34 | n | +| main.rs:415:22:415:22 | n | main.rs:415:22:415:22 | [SSA] n | +| main.rs:415:22:415:22 | n | main.rs:415:22:415:22 | n | +| main.rs:415:29:415:35 | sink(...) | main.rs:413:5:416:5 | match s1 { ... } | +| main.rs:417:11:417:12 | s1 | main.rs:418:9:418:43 | ... \| ... | +| main.rs:418:9:418:43 | ... \| ... | main.rs:418:9:418:24 | C {...} | +| main.rs:418:9:418:43 | ... \| ... | main.rs:418:28:418:43 | D {...} | +| main.rs:418:22:418:22 | [SSA] n | main.rs:418:53:418:53 | n | +| main.rs:418:22:418:22 | n | main.rs:418:22:418:22 | [SSA] n | +| main.rs:418:22:418:22 | n | main.rs:418:22:418:22 | n | +| main.rs:418:41:418:41 | [SSA] n | main.rs:418:53:418:53 | n | +| main.rs:418:41:418:41 | n | main.rs:418:41:418:41 | [SSA] n | +| main.rs:418:41:418:41 | n | main.rs:418:41:418:41 | n | +| main.rs:418:48:418:54 | sink(...) | main.rs:417:5:419:5 | match s1 { ... } | +| main.rs:420:5:423:5 | match s2 { ... } | main.rs:408:51:424:1 | { ... } | +| main.rs:420:11:420:12 | s2 | main.rs:421:9:421:24 | C {...} | +| main.rs:420:11:420:12 | s2 | main.rs:422:9:422:24 | D {...} | +| main.rs:421:22:421:22 | [SSA] n | main.rs:421:34:421:34 | n | +| main.rs:421:22:421:22 | n | main.rs:421:22:421:22 | [SSA] n | +| main.rs:421:22:421:22 | n | main.rs:421:22:421:22 | n | +| main.rs:421:29:421:35 | sink(...) | main.rs:420:5:423:5 | match s2 { ... } | +| main.rs:422:22:422:22 | [SSA] n | main.rs:422:34:422:34 | n | +| main.rs:422:22:422:22 | n | main.rs:422:22:422:22 | [SSA] n | +| main.rs:422:22:422:22 | n | main.rs:422:22:422:22 | n | +| main.rs:422:29:422:35 | sink(...) | main.rs:420:5:423:5 | match s2 { ... } | +| main.rs:430:9:430:12 | [SSA] arr1 | main.rs:431:14:431:17 | arr1 | +| main.rs:430:9:430:12 | arr1 | main.rs:430:9:430:12 | [SSA] arr1 | +| main.rs:430:9:430:12 | arr1 | main.rs:430:9:430:12 | arr1 | +| main.rs:430:16:430:33 | [...] | main.rs:430:9:430:12 | arr1 | +| main.rs:431:9:431:10 | [SSA] n1 | main.rs:432:10:432:11 | n1 | +| main.rs:431:9:431:10 | n1 | main.rs:431:9:431:10 | [SSA] n1 | +| main.rs:431:9:431:10 | n1 | main.rs:431:9:431:10 | n1 | +| main.rs:431:14:431:20 | arr1[2] | main.rs:431:9:431:10 | n1 | +| main.rs:434:9:434:12 | [SSA] arr2 | main.rs:435:14:435:17 | arr2 | +| main.rs:434:9:434:12 | arr2 | main.rs:434:9:434:12 | [SSA] arr2 | +| main.rs:434:9:434:12 | arr2 | main.rs:434:9:434:12 | arr2 | +| main.rs:434:16:434:31 | [...; 10] | main.rs:434:9:434:12 | arr2 | +| main.rs:435:9:435:10 | [SSA] n2 | main.rs:436:10:436:11 | n2 | +| main.rs:435:9:435:10 | n2 | main.rs:435:9:435:10 | [SSA] n2 | +| main.rs:435:9:435:10 | n2 | main.rs:435:9:435:10 | n2 | +| main.rs:435:14:435:20 | arr2[4] | main.rs:435:9:435:10 | n2 | +| main.rs:438:9:438:12 | [SSA] arr3 | main.rs:439:14:439:17 | arr3 | +| main.rs:438:9:438:12 | arr3 | main.rs:438:9:438:12 | [SSA] arr3 | +| main.rs:438:9:438:12 | arr3 | main.rs:438:9:438:12 | arr3 | +| main.rs:438:16:438:24 | [...] | main.rs:438:9:438:12 | arr3 | +| main.rs:439:9:439:10 | [SSA] n3 | main.rs:440:10:440:11 | n3 | +| main.rs:439:9:439:10 | n3 | main.rs:439:9:439:10 | [SSA] n3 | +| main.rs:439:9:439:10 | n3 | main.rs:439:9:439:10 | n3 | +| main.rs:439:14:439:20 | arr3[2] | main.rs:439:9:439:10 | n3 | +| main.rs:444:9:444:12 | [SSA] arr1 | main.rs:445:15:445:18 | arr1 | | main.rs:444:9:444:12 | arr1 | main.rs:444:9:444:12 | [SSA] arr1 | | main.rs:444:9:444:12 | arr1 | main.rs:444:9:444:12 | arr1 | | main.rs:444:16:444:33 | [...] | main.rs:444:9:444:12 | arr1 | -| main.rs:445:5:451:5 | match arr1 { ... } | main.rs:443:26:452:1 | { ... } | -| main.rs:445:11:445:14 | arr1 | main.rs:446:9:446:17 | SlicePat | -| main.rs:446:10:446:10 | [SSA] a | main.rs:447:18:447:18 | a | -| main.rs:446:10:446:10 | a | main.rs:446:10:446:10 | [SSA] a | -| main.rs:446:10:446:10 | a | main.rs:446:10:446:10 | a | -| main.rs:446:13:446:13 | [SSA] b | main.rs:448:18:448:18 | b | -| main.rs:446:13:446:13 | b | main.rs:446:13:446:13 | [SSA] b | -| main.rs:446:13:446:13 | b | main.rs:446:13:446:13 | b | -| main.rs:446:16:446:16 | [SSA] c | main.rs:449:18:449:18 | c | -| main.rs:446:16:446:16 | c | main.rs:446:16:446:16 | [SSA] c | -| main.rs:446:16:446:16 | c | main.rs:446:16:446:16 | c | -| main.rs:446:22:450:9 | { ... } | main.rs:445:5:451:5 | match arr1 { ... } | -| main.rs:455:9:455:19 | mut mut_arr | main.rs:455:13:455:19 | mut_arr | -| main.rs:455:13:455:19 | [SSA] mut_arr | main.rs:456:10:456:16 | mut_arr | -| main.rs:455:13:455:19 | mut_arr | main.rs:455:13:455:19 | [SSA] mut_arr | -| main.rs:455:23:455:31 | [...] | main.rs:455:9:455:19 | mut mut_arr | -| main.rs:456:10:456:16 | [post] mut_arr | main.rs:458:5:458:11 | mut_arr | -| main.rs:456:10:456:16 | mut_arr | main.rs:458:5:458:11 | mut_arr | -| main.rs:458:5:458:11 | [post] mut_arr | main.rs:459:13:459:19 | mut_arr | -| main.rs:458:5:458:11 | mut_arr | main.rs:459:13:459:19 | mut_arr | -| main.rs:458:18:458:27 | source(...) | main.rs:458:5:458:14 | mut_arr[1] | -| main.rs:459:9:459:9 | [SSA] d | main.rs:460:10:460:10 | d | -| main.rs:459:9:459:9 | d | main.rs:459:9:459:9 | [SSA] d | -| main.rs:459:9:459:9 | d | main.rs:459:9:459:9 | d | -| main.rs:459:13:459:19 | [post] mut_arr | main.rs:461:10:461:16 | mut_arr | -| main.rs:459:13:459:19 | mut_arr | main.rs:461:10:461:16 | mut_arr | -| main.rs:459:13:459:22 | mut_arr[1] | main.rs:459:9:459:9 | d | -| main.rs:466:39:466:43 | [SSA] names | main.rs:468:25:468:29 | names | -| main.rs:466:39:466:43 | names | main.rs:466:39:466:43 | [SSA] names | -| main.rs:466:39:466:43 | names | main.rs:466:39:466:43 | names | -| main.rs:466:39:466:72 | ...: Vec::<...> | main.rs:466:39:466:43 | names | -| main.rs:467:9:467:20 | default_name | main.rs:467:9:467:20 | [SSA] default_name | -| main.rs:467:9:467:20 | default_name | main.rs:467:9:467:20 | default_name | -| main.rs:467:24:467:33 | [post] receiver for source(...) | main.rs:467:24:467:33 | [post] source(...) | -| main.rs:467:24:467:33 | source(...) | main.rs:467:24:467:33 | receiver for source(...) | -| main.rs:467:24:467:45 | ... .to_string() | main.rs:467:9:467:20 | default_name | -| main.rs:467:24:467:45 | ... .to_string() | main.rs:468:9:468:20 | SSA phi read(default_name) | -| main.rs:468:5:474:5 | for ... in ... { ... } | main.rs:466:75:475:1 | { ... } | -| main.rs:468:9:468:20 | SSA phi read(default_name) | main.rs:470:41:470:67 | default_name | -| main.rs:468:10:468:13 | [SSA] cond | main.rs:469:12:469:15 | cond | -| main.rs:468:10:468:13 | cond | main.rs:468:10:468:13 | [SSA] cond | -| main.rs:468:10:468:13 | cond | main.rs:468:10:468:13 | cond | -| main.rs:468:16:468:19 | [SSA] name | main.rs:470:21:470:24 | name | -| main.rs:468:16:468:19 | name | main.rs:468:16:468:19 | [SSA] name | -| main.rs:468:16:468:19 | name | main.rs:468:16:468:19 | name | -| main.rs:469:9:473:9 | if cond {...} | main.rs:468:31:474:5 | { ... } | -| main.rs:470:17:470:17 | [SSA] n | main.rs:471:18:471:18 | n | -| main.rs:470:17:470:17 | n | main.rs:470:17:470:17 | [SSA] n | -| main.rs:470:17:470:17 | n | main.rs:470:17:470:17 | n | -| main.rs:470:21:470:24 | [post] receiver for name | main.rs:470:21:470:24 | [post] name | -| main.rs:470:21:470:24 | name | main.rs:470:21:470:24 | receiver for name | -| main.rs:470:21:470:68 | name.unwrap_or_else(...) | main.rs:470:17:470:17 | n | -| main.rs:470:41:470:67 | [post] default_name | main.rs:468:9:468:20 | SSA phi read(default_name) | -| main.rs:470:41:470:67 | closure self in \|...\| ... | main.rs:470:44:470:55 | this | -| main.rs:470:41:470:67 | default_name | main.rs:468:9:468:20 | SSA phi read(default_name) | -| main.rs:470:44:470:55 | [post] receiver for default_name | main.rs:470:44:470:55 | [post] default_name | -| main.rs:470:44:470:55 | default_name | main.rs:470:44:470:55 | receiver for default_name | -| main.rs:471:18:471:18 | [post] receiver for n | main.rs:471:18:471:18 | [post] n | -| main.rs:471:18:471:18 | n | main.rs:471:18:471:18 | receiver for n | -| main.rs:484:9:484:9 | [SSA] s | main.rs:485:10:485:10 | s | -| main.rs:484:9:484:9 | s | main.rs:484:9:484:9 | [SSA] s | -| main.rs:484:9:484:9 | s | main.rs:484:9:484:9 | s | -| main.rs:484:13:484:27 | MacroExpr | main.rs:484:9:484:9 | s | -| main.rs:484:25:484:26 | source(...) | main.rs:484:13:484:27 | MacroExpr | -| main.rs:488:16:488:16 | [SSA] s | main.rs:489:20:489:20 | s | -| main.rs:488:16:488:16 | s | main.rs:488:16:488:16 | [SSA] s | -| main.rs:488:16:488:16 | s | main.rs:488:16:488:16 | s | -| main.rs:488:16:488:24 | ...: String | main.rs:488:16:488:16 | s | -| main.rs:489:14:489:20 | FormatArgsExpr | main.rs:489:14:489:20 | MacroExpr | -| main.rs:489:14:489:20 | MacroBlockExpr | main.rs:489:5:489:21 | MacroExpr | -| main.rs:489:14:489:20 | [post] MacroExpr | main.rs:489:14:489:20 | [post] FormatArgsExpr | -| main.rs:489:14:489:20 | { ... } | main.rs:489:14:489:20 | MacroBlockExpr | -| main.rs:493:9:493:9 | [SSA] a | main.rs:494:13:494:13 | a | -| main.rs:493:9:493:9 | a | main.rs:493:9:493:9 | [SSA] a | -| main.rs:493:9:493:9 | a | main.rs:493:9:493:9 | a | -| main.rs:493:13:493:22 | source(...) | main.rs:493:9:493:9 | a | -| main.rs:494:9:494:9 | [SSA] b | main.rs:495:13:495:13 | b | -| main.rs:494:9:494:9 | b | main.rs:494:9:494:9 | [SSA] b | -| main.rs:494:9:494:9 | b | main.rs:494:9:494:9 | b | -| main.rs:494:13:494:13 | [post] a | main.rs:498:10:498:10 | a | -| main.rs:494:13:494:13 | [post] receiver for a | main.rs:494:13:494:13 | [post] a | -| main.rs:494:13:494:13 | a | main.rs:494:13:494:13 | receiver for a | -| main.rs:494:13:494:13 | a | main.rs:498:10:498:10 | a | -| main.rs:494:13:494:25 | a.to_string() | main.rs:494:9:494:9 | b | -| main.rs:495:9:495:9 | [SSA] c | main.rs:500:10:500:10 | c | -| main.rs:495:9:495:9 | c | main.rs:495:9:495:9 | [SSA] c | -| main.rs:495:9:495:9 | c | main.rs:495:9:495:9 | c | -| main.rs:495:13:495:13 | [post] b | main.rs:496:18:496:18 | b | -| main.rs:495:13:495:13 | [post] receiver for b | main.rs:495:13:495:13 | [post] b | -| main.rs:495:13:495:13 | b | main.rs:495:13:495:13 | receiver for b | -| main.rs:495:13:495:13 | b | main.rs:496:18:496:18 | b | -| main.rs:495:13:495:28 | [post] receiver for b.parse() | main.rs:495:13:495:28 | [post] b.parse() | -| main.rs:495:13:495:28 | b.parse() | main.rs:495:13:495:28 | receiver for b.parse() | -| main.rs:495:13:495:37 | ... .unwrap() | main.rs:495:9:495:9 | c | -| main.rs:496:9:496:9 | [SSA] d | main.rs:501:10:501:10 | d | -| main.rs:496:9:496:9 | d | main.rs:496:9:496:9 | [SSA] d | -| main.rs:496:9:496:9 | d | main.rs:496:9:496:9 | d | -| main.rs:496:18:496:18 | [post] b | main.rs:499:17:499:17 | b | -| main.rs:496:18:496:18 | [post] receiver for b | main.rs:496:18:496:18 | [post] b | -| main.rs:496:18:496:18 | b | main.rs:496:18:496:18 | receiver for b | -| main.rs:496:18:496:18 | b | main.rs:499:17:499:17 | b | -| main.rs:496:18:496:26 | [post] receiver for b.parse() | main.rs:496:18:496:26 | [post] b.parse() | -| main.rs:496:18:496:26 | b.parse() | main.rs:496:18:496:26 | receiver for b.parse() | -| main.rs:496:18:496:35 | ... .unwrap() | main.rs:496:9:496:9 | d | -| main.rs:505:9:505:10 | [SSA] vs | main.rs:507:10:507:11 | vs | -| main.rs:505:9:505:10 | vs | main.rs:505:9:505:10 | [SSA] vs | -| main.rs:505:9:505:10 | vs | main.rs:505:9:505:10 | vs | -| main.rs:505:14:505:34 | [...] | main.rs:505:9:505:10 | vs | -| main.rs:507:10:507:11 | [post] vs | main.rs:508:11:508:12 | vs | -| main.rs:507:10:507:11 | vs | main.rs:508:11:508:12 | vs | -| main.rs:508:11:508:12 | [post] receiver for vs | main.rs:508:11:508:12 | [post] vs | -| main.rs:508:11:508:12 | [post] vs | main.rs:509:11:509:12 | vs | -| main.rs:508:11:508:12 | vs | main.rs:508:11:508:12 | receiver for vs | -| main.rs:508:11:508:12 | vs | main.rs:509:11:509:12 | vs | -| main.rs:508:11:508:19 | [post] receiver for vs.iter() | main.rs:508:11:508:19 | [post] vs.iter() | -| main.rs:508:11:508:19 | vs.iter() | main.rs:508:11:508:19 | receiver for vs.iter() | -| main.rs:508:11:508:26 | ... .next() | main.rs:508:11:508:26 | receiver for ... .next() | -| main.rs:508:11:508:26 | [post] receiver for ... .next() | main.rs:508:11:508:26 | [post] ... .next() | -| main.rs:508:11:508:35 | ... .unwrap() | main.rs:508:11:508:35 | receiver for ... .unwrap() | -| main.rs:508:11:508:35 | [post] receiver for ... .unwrap() | main.rs:508:11:508:35 | [post] ... .unwrap() | -| main.rs:509:11:509:12 | [post] receiver for vs | main.rs:509:11:509:12 | [post] vs | -| main.rs:509:11:509:12 | [post] vs | main.rs:511:14:511:15 | vs | -| main.rs:509:11:509:12 | vs | main.rs:509:11:509:12 | receiver for vs | -| main.rs:509:11:509:12 | vs | main.rs:511:14:511:15 | vs | -| main.rs:509:11:509:19 | [post] receiver for vs.iter() | main.rs:509:11:509:19 | [post] vs.iter() | -| main.rs:509:11:509:19 | vs.iter() | main.rs:509:11:509:19 | receiver for vs.iter() | -| main.rs:509:11:509:26 | ... .nth(...) | main.rs:509:11:509:26 | receiver for ... .nth(...) | -| main.rs:509:11:509:26 | [post] receiver for ... .nth(...) | main.rs:509:11:509:26 | [post] ... .nth(...) | -| main.rs:509:11:509:35 | ... .unwrap() | main.rs:509:11:509:35 | receiver for ... .unwrap() | -| main.rs:509:11:509:35 | [post] receiver for ... .unwrap() | main.rs:509:11:509:35 | [post] ... .unwrap() | -| main.rs:511:9:511:9 | [SSA] v | main.rs:512:14:512:14 | v | -| main.rs:511:9:511:9 | v | main.rs:511:9:511:9 | [SSA] v | -| main.rs:511:9:511:9 | v | main.rs:511:9:511:9 | v | -| main.rs:511:14:511:15 | vs | main.rs:514:15:514:16 | vs | -| main.rs:514:10:514:10 | [SSA] v | main.rs:515:14:515:14 | v | -| main.rs:514:10:514:10 | v | main.rs:514:10:514:10 | [SSA] v | -| main.rs:514:10:514:10 | v | main.rs:514:10:514:10 | v | -| main.rs:514:15:514:16 | [post] receiver for vs | main.rs:514:15:514:16 | [post] vs | -| main.rs:514:15:514:16 | [post] vs | main.rs:518:26:518:27 | vs | -| main.rs:514:15:514:16 | vs | main.rs:514:15:514:16 | receiver for vs | -| main.rs:514:15:514:16 | vs | main.rs:518:26:518:27 | vs | -| main.rs:518:9:518:11 | [SSA] vs2 | main.rs:519:15:519:17 | vs2 | -| main.rs:518:9:518:11 | vs2 | main.rs:518:9:518:11 | [SSA] vs2 | -| main.rs:518:9:518:11 | vs2 | main.rs:518:9:518:11 | vs2 | -| main.rs:518:26:518:27 | [post] receiver for vs | main.rs:518:26:518:27 | [post] vs | -| main.rs:518:26:518:27 | [post] vs | main.rs:523:5:523:6 | vs | -| main.rs:518:26:518:27 | vs | main.rs:518:26:518:27 | receiver for vs | -| main.rs:518:26:518:27 | vs | main.rs:523:5:523:6 | vs | -| main.rs:518:26:518:34 | [post] receiver for vs.iter() | main.rs:518:26:518:34 | [post] vs.iter() | -| main.rs:518:26:518:34 | vs.iter() | main.rs:518:26:518:34 | receiver for vs.iter() | -| main.rs:518:26:518:44 | ... .collect() | main.rs:518:9:518:11 | vs2 | -| main.rs:519:10:519:10 | [SSA] v | main.rs:520:14:520:14 | v | -| main.rs:519:10:519:10 | v | main.rs:519:10:519:10 | [SSA] v | -| main.rs:519:10:519:10 | v | main.rs:519:10:519:10 | v | -| main.rs:523:5:523:6 | [post] receiver for vs | main.rs:523:5:523:6 | [post] vs | -| main.rs:523:5:523:6 | [post] vs | main.rs:524:5:524:6 | vs | -| main.rs:523:5:523:6 | vs | main.rs:523:5:523:6 | receiver for vs | -| main.rs:523:5:523:6 | vs | main.rs:524:5:524:6 | vs | -| main.rs:523:5:523:13 | [post] receiver for vs.iter() | main.rs:523:5:523:13 | [post] vs.iter() | -| main.rs:523:5:523:13 | vs.iter() | main.rs:523:5:523:13 | receiver for vs.iter() | -| main.rs:523:20:523:20 | ... | main.rs:523:20:523:20 | x | -| main.rs:523:20:523:20 | [SSA] x | main.rs:523:29:523:29 | x | -| main.rs:523:20:523:20 | x | main.rs:523:20:523:20 | [SSA] x | -| main.rs:523:20:523:20 | x | main.rs:523:20:523:20 | x | -| main.rs:523:29:523:29 | [post] receiver for x | main.rs:523:29:523:29 | [post] x | -| main.rs:523:29:523:29 | x | main.rs:523:29:523:29 | receiver for x | -| main.rs:524:5:524:6 | [post] receiver for vs | main.rs:524:5:524:6 | [post] vs | -| main.rs:524:5:524:6 | [post] vs | main.rs:526:14:526:15 | vs | -| main.rs:524:5:524:6 | vs | main.rs:524:5:524:6 | receiver for vs | -| main.rs:524:5:524:6 | vs | main.rs:526:14:526:15 | vs | -| main.rs:524:5:524:13 | [post] receiver for vs.iter() | main.rs:524:5:524:13 | [post] vs.iter() | -| main.rs:524:5:524:13 | vs.iter() | main.rs:524:5:524:13 | receiver for vs.iter() | -| main.rs:524:25:524:25 | ... | main.rs:524:25:524:25 | x | -| main.rs:524:25:524:25 | [SSA] x | main.rs:524:34:524:34 | x | -| main.rs:524:25:524:25 | x | main.rs:524:25:524:25 | [SSA] x | -| main.rs:524:25:524:25 | x | main.rs:524:25:524:25 | x | -| main.rs:524:34:524:34 | [post] receiver for x | main.rs:524:34:524:34 | [post] x | -| main.rs:524:34:524:34 | x | main.rs:524:34:524:34 | receiver for x | -| main.rs:526:9:526:9 | [SSA] v | main.rs:527:14:527:14 | v | -| main.rs:526:9:526:9 | v | main.rs:526:9:526:9 | [SSA] v | -| main.rs:526:9:526:9 | v | main.rs:526:9:526:9 | v | -| main.rs:526:14:526:15 | [post] receiver for vs | main.rs:526:14:526:15 | [post] vs | -| main.rs:526:14:526:15 | vs | main.rs:526:14:526:15 | receiver for vs | -| main.rs:530:9:530:18 | mut vs_mut | main.rs:530:13:530:18 | vs_mut | -| main.rs:530:13:530:18 | [SSA] vs_mut | main.rs:532:10:532:15 | vs_mut | -| main.rs:530:13:530:18 | vs_mut | main.rs:530:13:530:18 | [SSA] vs_mut | -| main.rs:530:22:530:42 | [...] | main.rs:530:9:530:18 | mut vs_mut | -| main.rs:532:10:532:15 | [post] vs_mut | main.rs:533:11:533:16 | [SSA] vs_mut | -| main.rs:532:10:532:15 | [post] vs_mut | main.rs:533:11:533:16 | vs_mut | -| main.rs:532:10:532:15 | vs_mut | main.rs:533:11:533:16 | [SSA] vs_mut | -| main.rs:532:10:532:15 | vs_mut | main.rs:533:11:533:16 | vs_mut | -| main.rs:533:11:533:16 | [SSA] vs_mut | main.rs:534:11:534:16 | [SSA] vs_mut | -| main.rs:533:11:533:16 | [SSA] vs_mut | main.rs:534:11:534:16 | vs_mut | -| main.rs:533:11:533:16 | [post] receiver for vs_mut | main.rs:533:11:533:16 | [post] vs_mut | -| main.rs:533:11:533:16 | [post] vs_mut | main.rs:534:11:534:16 | [SSA] vs_mut | -| main.rs:533:11:533:16 | [post] vs_mut | main.rs:534:11:534:16 | vs_mut | -| main.rs:533:11:533:16 | vs_mut | main.rs:533:11:533:16 | receiver for vs_mut | -| main.rs:533:11:533:16 | vs_mut | main.rs:534:11:534:16 | [SSA] vs_mut | -| main.rs:533:11:533:16 | vs_mut | main.rs:534:11:534:16 | vs_mut | -| main.rs:533:11:533:23 | [post] receiver for vs_mut.iter() | main.rs:533:11:533:23 | [post] vs_mut.iter() | -| main.rs:533:11:533:23 | vs_mut.iter() | main.rs:533:11:533:23 | receiver for vs_mut.iter() | -| main.rs:533:11:533:30 | ... .next() | main.rs:533:11:533:30 | receiver for ... .next() | -| main.rs:533:11:533:30 | [post] receiver for ... .next() | main.rs:533:11:533:30 | [post] ... .next() | -| main.rs:533:11:533:39 | ... .unwrap() | main.rs:533:11:533:39 | receiver for ... .unwrap() | -| main.rs:533:11:533:39 | [post] receiver for ... .unwrap() | main.rs:533:11:533:39 | [post] ... .unwrap() | -| main.rs:534:11:534:16 | [SSA] vs_mut | main.rs:536:19:536:24 | vs_mut | -| main.rs:534:11:534:16 | [post] receiver for vs_mut | main.rs:534:11:534:16 | [post] vs_mut | -| main.rs:534:11:534:16 | [post] vs_mut | main.rs:536:19:536:24 | vs_mut | -| main.rs:534:11:534:16 | vs_mut | main.rs:534:11:534:16 | receiver for vs_mut | -| main.rs:534:11:534:16 | vs_mut | main.rs:536:19:536:24 | vs_mut | -| main.rs:534:11:534:23 | [post] receiver for vs_mut.iter() | main.rs:534:11:534:23 | [post] vs_mut.iter() | -| main.rs:534:11:534:23 | vs_mut.iter() | main.rs:534:11:534:23 | receiver for vs_mut.iter() | -| main.rs:534:11:534:30 | ... .nth(...) | main.rs:534:11:534:30 | receiver for ... .nth(...) | -| main.rs:534:11:534:30 | [post] receiver for ... .nth(...) | main.rs:534:11:534:30 | [post] ... .nth(...) | -| main.rs:534:11:534:39 | ... .unwrap() | main.rs:534:11:534:39 | receiver for ... .unwrap() | -| main.rs:534:11:534:39 | [post] receiver for ... .unwrap() | main.rs:534:11:534:39 | [post] ... .unwrap() | -| main.rs:536:5:538:5 | for ... in ... { ... } | main.rs:504:16:539:1 | { ... } | -| main.rs:536:14:536:14 | [SSA] v | main.rs:537:14:537:14 | v | -| main.rs:536:14:536:14 | v | main.rs:536:14:536:14 | [SSA] v | -| main.rs:536:14:536:14 | v | main.rs:536:14:536:14 | v | -| main.rs:536:19:536:24 | [post] receiver for vs_mut | main.rs:536:19:536:24 | [post] vs_mut | -| main.rs:536:19:536:24 | vs_mut | main.rs:536:19:536:24 | receiver for vs_mut | -| main.rs:542:9:542:9 | [SSA] a | main.rs:547:10:547:10 | a | -| main.rs:542:9:542:9 | a | main.rs:542:9:542:9 | [SSA] a | -| main.rs:542:9:542:9 | a | main.rs:542:9:542:9 | a | -| main.rs:542:13:542:22 | source(...) | main.rs:542:9:542:9 | a | -| main.rs:543:9:543:9 | [SSA] b | main.rs:548:15:548:15 | b | -| main.rs:543:9:543:9 | b | main.rs:543:9:543:9 | [SSA] b | -| main.rs:543:9:543:9 | b | main.rs:543:9:543:9 | b | -| main.rs:543:13:543:22 | source(...) | main.rs:543:9:543:9 | b | -| main.rs:544:9:544:9 | [SSA] c | main.rs:545:18:545:18 | c | -| main.rs:544:9:544:9 | c | main.rs:544:9:544:9 | [SSA] c | -| main.rs:544:9:544:9 | c | main.rs:544:9:544:9 | c | -| main.rs:544:13:544:22 | source(...) | main.rs:544:9:544:9 | c | -| main.rs:545:9:545:13 | [SSA] c_ref | main.rs:549:14:549:18 | c_ref | -| main.rs:545:9:545:13 | c_ref | main.rs:545:9:545:13 | [SSA] c_ref | -| main.rs:545:9:545:13 | c_ref | main.rs:545:9:545:13 | c_ref | -| main.rs:545:17:545:18 | &c | main.rs:545:9:545:13 | c_ref | -| main.rs:549:14:549:18 | [post] c_ref | main.rs:550:11:550:15 | c_ref | -| main.rs:549:14:549:18 | c_ref | main.rs:550:11:550:15 | c_ref | -| main.rs:550:11:550:15 | [post] receiver for c_ref | main.rs:550:11:550:15 | [post] c_ref | -| main.rs:550:11:550:15 | c_ref | main.rs:550:11:550:15 | receiver for c_ref | -| main.rs:554:9:554:9 | [SSA] a | main.rs:556:10:556:10 | a | +| main.rs:445:9:445:10 | [SSA] n1 | main.rs:446:14:446:15 | n1 | +| main.rs:445:9:445:10 | n1 | main.rs:445:9:445:10 | [SSA] n1 | +| main.rs:445:9:445:10 | n1 | main.rs:445:9:445:10 | n1 | +| main.rs:449:9:449:12 | [SSA] arr2 | main.rs:450:15:450:18 | arr2 | +| main.rs:449:9:449:12 | arr2 | main.rs:449:9:449:12 | [SSA] arr2 | +| main.rs:449:9:449:12 | arr2 | main.rs:449:9:449:12 | arr2 | +| main.rs:449:16:449:24 | [...] | main.rs:449:9:449:12 | arr2 | +| main.rs:450:5:452:5 | for ... in ... { ... } | main.rs:443:21:453:1 | { ... } | +| main.rs:450:9:450:10 | [SSA] n2 | main.rs:451:14:451:15 | n2 | +| main.rs:450:9:450:10 | n2 | main.rs:450:9:450:10 | [SSA] n2 | +| main.rs:450:9:450:10 | n2 | main.rs:450:9:450:10 | n2 | +| main.rs:456:9:456:12 | [SSA] arr1 | main.rs:457:11:457:14 | arr1 | +| main.rs:456:9:456:12 | arr1 | main.rs:456:9:456:12 | [SSA] arr1 | +| main.rs:456:9:456:12 | arr1 | main.rs:456:9:456:12 | arr1 | +| main.rs:456:16:456:33 | [...] | main.rs:456:9:456:12 | arr1 | +| main.rs:457:5:463:5 | match arr1 { ... } | main.rs:455:26:464:1 | { ... } | +| main.rs:457:11:457:14 | arr1 | main.rs:458:9:458:17 | SlicePat | +| main.rs:458:10:458:10 | [SSA] a | main.rs:459:18:459:18 | a | +| main.rs:458:10:458:10 | a | main.rs:458:10:458:10 | [SSA] a | +| main.rs:458:10:458:10 | a | main.rs:458:10:458:10 | a | +| main.rs:458:13:458:13 | [SSA] b | main.rs:460:18:460:18 | b | +| main.rs:458:13:458:13 | b | main.rs:458:13:458:13 | [SSA] b | +| main.rs:458:13:458:13 | b | main.rs:458:13:458:13 | b | +| main.rs:458:16:458:16 | [SSA] c | main.rs:461:18:461:18 | c | +| main.rs:458:16:458:16 | c | main.rs:458:16:458:16 | [SSA] c | +| main.rs:458:16:458:16 | c | main.rs:458:16:458:16 | c | +| main.rs:458:22:462:9 | { ... } | main.rs:457:5:463:5 | match arr1 { ... } | +| main.rs:467:9:467:19 | mut mut_arr | main.rs:467:13:467:19 | mut_arr | +| main.rs:467:13:467:19 | [SSA] mut_arr | main.rs:468:10:468:16 | mut_arr | +| main.rs:467:13:467:19 | mut_arr | main.rs:467:13:467:19 | [SSA] mut_arr | +| main.rs:467:23:467:31 | [...] | main.rs:467:9:467:19 | mut mut_arr | +| main.rs:468:10:468:16 | [post] mut_arr | main.rs:470:5:470:11 | mut_arr | +| main.rs:468:10:468:16 | mut_arr | main.rs:470:5:470:11 | mut_arr | +| main.rs:470:5:470:11 | [post] mut_arr | main.rs:471:13:471:19 | mut_arr | +| main.rs:470:5:470:11 | mut_arr | main.rs:471:13:471:19 | mut_arr | +| main.rs:470:18:470:27 | source(...) | main.rs:470:5:470:14 | mut_arr[1] | +| main.rs:471:9:471:9 | [SSA] d | main.rs:472:10:472:10 | d | +| main.rs:471:9:471:9 | d | main.rs:471:9:471:9 | [SSA] d | +| main.rs:471:9:471:9 | d | main.rs:471:9:471:9 | d | +| main.rs:471:13:471:19 | [post] mut_arr | main.rs:473:10:473:16 | mut_arr | +| main.rs:471:13:471:19 | mut_arr | main.rs:473:10:473:16 | mut_arr | +| main.rs:471:13:471:22 | mut_arr[1] | main.rs:471:9:471:9 | d | +| main.rs:478:39:478:43 | [SSA] names | main.rs:480:25:480:29 | names | +| main.rs:478:39:478:43 | names | main.rs:478:39:478:43 | [SSA] names | +| main.rs:478:39:478:43 | names | main.rs:478:39:478:43 | names | +| main.rs:478:39:478:72 | ...: Vec::<...> | main.rs:478:39:478:43 | names | +| main.rs:479:9:479:20 | default_name | main.rs:479:9:479:20 | [SSA] default_name | +| main.rs:479:9:479:20 | default_name | main.rs:479:9:479:20 | default_name | +| main.rs:479:24:479:33 | [post] receiver for source(...) | main.rs:479:24:479:33 | [post] source(...) | +| main.rs:479:24:479:33 | source(...) | main.rs:479:24:479:33 | receiver for source(...) | +| main.rs:479:24:479:45 | ... .to_string() | main.rs:479:9:479:20 | default_name | +| main.rs:479:24:479:45 | ... .to_string() | main.rs:480:9:480:20 | SSA phi read(default_name) | +| main.rs:480:5:486:5 | for ... in ... { ... } | main.rs:478:75:487:1 | { ... } | +| main.rs:480:9:480:20 | SSA phi read(default_name) | main.rs:482:41:482:67 | default_name | +| main.rs:480:10:480:13 | [SSA] cond | main.rs:481:12:481:15 | cond | +| main.rs:480:10:480:13 | cond | main.rs:480:10:480:13 | [SSA] cond | +| main.rs:480:10:480:13 | cond | main.rs:480:10:480:13 | cond | +| main.rs:480:16:480:19 | [SSA] name | main.rs:482:21:482:24 | name | +| main.rs:480:16:480:19 | name | main.rs:480:16:480:19 | [SSA] name | +| main.rs:480:16:480:19 | name | main.rs:480:16:480:19 | name | +| main.rs:481:9:485:9 | if cond {...} | main.rs:480:31:486:5 | { ... } | +| main.rs:482:17:482:17 | [SSA] n | main.rs:483:18:483:18 | n | +| main.rs:482:17:482:17 | n | main.rs:482:17:482:17 | [SSA] n | +| main.rs:482:17:482:17 | n | main.rs:482:17:482:17 | n | +| main.rs:482:21:482:24 | [post] receiver for name | main.rs:482:21:482:24 | [post] name | +| main.rs:482:21:482:24 | name | main.rs:482:21:482:24 | receiver for name | +| main.rs:482:21:482:68 | name.unwrap_or_else(...) | main.rs:482:17:482:17 | n | +| main.rs:482:41:482:67 | [post] default_name | main.rs:480:9:480:20 | SSA phi read(default_name) | +| main.rs:482:41:482:67 | closure self in \|...\| ... | main.rs:482:44:482:55 | this | +| main.rs:482:41:482:67 | default_name | main.rs:480:9:480:20 | SSA phi read(default_name) | +| main.rs:482:44:482:55 | [post] receiver for default_name | main.rs:482:44:482:55 | [post] default_name | +| main.rs:482:44:482:55 | default_name | main.rs:482:44:482:55 | receiver for default_name | +| main.rs:483:18:483:18 | [post] receiver for n | main.rs:483:18:483:18 | [post] n | +| main.rs:483:18:483:18 | n | main.rs:483:18:483:18 | receiver for n | +| main.rs:496:9:496:9 | [SSA] s | main.rs:497:10:497:10 | s | +| main.rs:496:9:496:9 | s | main.rs:496:9:496:9 | [SSA] s | +| main.rs:496:9:496:9 | s | main.rs:496:9:496:9 | s | +| main.rs:496:13:496:27 | MacroExpr | main.rs:496:9:496:9 | s | +| main.rs:496:25:496:26 | source(...) | main.rs:496:13:496:27 | MacroExpr | +| main.rs:500:16:500:16 | [SSA] s | main.rs:501:20:501:20 | s | +| main.rs:500:16:500:16 | s | main.rs:500:16:500:16 | [SSA] s | +| main.rs:500:16:500:16 | s | main.rs:500:16:500:16 | s | +| main.rs:500:16:500:24 | ...: String | main.rs:500:16:500:16 | s | +| main.rs:501:14:501:20 | FormatArgsExpr | main.rs:501:14:501:20 | MacroExpr | +| main.rs:501:14:501:20 | MacroBlockExpr | main.rs:501:5:501:21 | MacroExpr | +| main.rs:501:14:501:20 | [post] MacroExpr | main.rs:501:14:501:20 | [post] FormatArgsExpr | +| main.rs:501:14:501:20 | { ... } | main.rs:501:14:501:20 | MacroBlockExpr | +| main.rs:505:9:505:9 | [SSA] a | main.rs:506:13:506:13 | a | +| main.rs:505:9:505:9 | a | main.rs:505:9:505:9 | [SSA] a | +| main.rs:505:9:505:9 | a | main.rs:505:9:505:9 | a | +| main.rs:505:13:505:22 | source(...) | main.rs:505:9:505:9 | a | +| main.rs:506:9:506:9 | [SSA] b | main.rs:507:13:507:13 | b | +| main.rs:506:9:506:9 | b | main.rs:506:9:506:9 | [SSA] b | +| main.rs:506:9:506:9 | b | main.rs:506:9:506:9 | b | +| main.rs:506:13:506:13 | [post] a | main.rs:510:10:510:10 | a | +| main.rs:506:13:506:13 | [post] receiver for a | main.rs:506:13:506:13 | [post] a | +| main.rs:506:13:506:13 | a | main.rs:506:13:506:13 | receiver for a | +| main.rs:506:13:506:13 | a | main.rs:510:10:510:10 | a | +| main.rs:506:13:506:25 | a.to_string() | main.rs:506:9:506:9 | b | +| main.rs:507:9:507:9 | [SSA] c | main.rs:512:10:512:10 | c | +| main.rs:507:9:507:9 | c | main.rs:507:9:507:9 | [SSA] c | +| main.rs:507:9:507:9 | c | main.rs:507:9:507:9 | c | +| main.rs:507:13:507:13 | [post] b | main.rs:508:18:508:18 | b | +| main.rs:507:13:507:13 | [post] receiver for b | main.rs:507:13:507:13 | [post] b | +| main.rs:507:13:507:13 | b | main.rs:507:13:507:13 | receiver for b | +| main.rs:507:13:507:13 | b | main.rs:508:18:508:18 | b | +| main.rs:507:13:507:28 | [post] receiver for b.parse() | main.rs:507:13:507:28 | [post] b.parse() | +| main.rs:507:13:507:28 | b.parse() | main.rs:507:13:507:28 | receiver for b.parse() | +| main.rs:507:13:507:37 | ... .unwrap() | main.rs:507:9:507:9 | c | +| main.rs:508:9:508:9 | [SSA] d | main.rs:513:10:513:10 | d | +| main.rs:508:9:508:9 | d | main.rs:508:9:508:9 | [SSA] d | +| main.rs:508:9:508:9 | d | main.rs:508:9:508:9 | d | +| main.rs:508:18:508:18 | [post] b | main.rs:511:17:511:17 | b | +| main.rs:508:18:508:18 | [post] receiver for b | main.rs:508:18:508:18 | [post] b | +| main.rs:508:18:508:18 | b | main.rs:508:18:508:18 | receiver for b | +| main.rs:508:18:508:18 | b | main.rs:511:17:511:17 | b | +| main.rs:508:18:508:26 | [post] receiver for b.parse() | main.rs:508:18:508:26 | [post] b.parse() | +| main.rs:508:18:508:26 | b.parse() | main.rs:508:18:508:26 | receiver for b.parse() | +| main.rs:508:18:508:35 | ... .unwrap() | main.rs:508:9:508:9 | d | +| main.rs:517:9:517:10 | [SSA] vs | main.rs:519:10:519:11 | vs | +| main.rs:517:9:517:10 | vs | main.rs:517:9:517:10 | [SSA] vs | +| main.rs:517:9:517:10 | vs | main.rs:517:9:517:10 | vs | +| main.rs:517:14:517:34 | [...] | main.rs:517:9:517:10 | vs | +| main.rs:519:10:519:11 | [post] vs | main.rs:520:11:520:12 | vs | +| main.rs:519:10:519:11 | vs | main.rs:520:11:520:12 | vs | +| main.rs:520:11:520:12 | [post] receiver for vs | main.rs:520:11:520:12 | [post] vs | +| main.rs:520:11:520:12 | [post] vs | main.rs:521:11:521:12 | vs | +| main.rs:520:11:520:12 | vs | main.rs:520:11:520:12 | receiver for vs | +| main.rs:520:11:520:12 | vs | main.rs:521:11:521:12 | vs | +| main.rs:520:11:520:19 | [post] receiver for vs.iter() | main.rs:520:11:520:19 | [post] vs.iter() | +| main.rs:520:11:520:19 | vs.iter() | main.rs:520:11:520:19 | receiver for vs.iter() | +| main.rs:520:11:520:26 | ... .next() | main.rs:520:11:520:26 | receiver for ... .next() | +| main.rs:520:11:520:26 | [post] receiver for ... .next() | main.rs:520:11:520:26 | [post] ... .next() | +| main.rs:520:11:520:35 | ... .unwrap() | main.rs:520:11:520:35 | receiver for ... .unwrap() | +| main.rs:520:11:520:35 | [post] receiver for ... .unwrap() | main.rs:520:11:520:35 | [post] ... .unwrap() | +| main.rs:521:11:521:12 | [post] receiver for vs | main.rs:521:11:521:12 | [post] vs | +| main.rs:521:11:521:12 | [post] vs | main.rs:523:14:523:15 | vs | +| main.rs:521:11:521:12 | vs | main.rs:521:11:521:12 | receiver for vs | +| main.rs:521:11:521:12 | vs | main.rs:523:14:523:15 | vs | +| main.rs:521:11:521:19 | [post] receiver for vs.iter() | main.rs:521:11:521:19 | [post] vs.iter() | +| main.rs:521:11:521:19 | vs.iter() | main.rs:521:11:521:19 | receiver for vs.iter() | +| main.rs:521:11:521:26 | ... .nth(...) | main.rs:521:11:521:26 | receiver for ... .nth(...) | +| main.rs:521:11:521:26 | [post] receiver for ... .nth(...) | main.rs:521:11:521:26 | [post] ... .nth(...) | +| main.rs:521:11:521:35 | ... .unwrap() | main.rs:521:11:521:35 | receiver for ... .unwrap() | +| main.rs:521:11:521:35 | [post] receiver for ... .unwrap() | main.rs:521:11:521:35 | [post] ... .unwrap() | +| main.rs:523:9:523:9 | [SSA] v | main.rs:524:14:524:14 | v | +| main.rs:523:9:523:9 | v | main.rs:523:9:523:9 | [SSA] v | +| main.rs:523:9:523:9 | v | main.rs:523:9:523:9 | v | +| main.rs:523:14:523:15 | vs | main.rs:526:15:526:16 | vs | +| main.rs:526:10:526:10 | [SSA] v | main.rs:527:14:527:14 | v | +| main.rs:526:10:526:10 | v | main.rs:526:10:526:10 | [SSA] v | +| main.rs:526:10:526:10 | v | main.rs:526:10:526:10 | v | +| main.rs:526:15:526:16 | [post] receiver for vs | main.rs:526:15:526:16 | [post] vs | +| main.rs:526:15:526:16 | [post] vs | main.rs:530:26:530:27 | vs | +| main.rs:526:15:526:16 | vs | main.rs:526:15:526:16 | receiver for vs | +| main.rs:526:15:526:16 | vs | main.rs:530:26:530:27 | vs | +| main.rs:530:9:530:11 | [SSA] vs2 | main.rs:531:15:531:17 | vs2 | +| main.rs:530:9:530:11 | vs2 | main.rs:530:9:530:11 | [SSA] vs2 | +| main.rs:530:9:530:11 | vs2 | main.rs:530:9:530:11 | vs2 | +| main.rs:530:26:530:27 | [post] receiver for vs | main.rs:530:26:530:27 | [post] vs | +| main.rs:530:26:530:27 | [post] vs | main.rs:535:5:535:6 | vs | +| main.rs:530:26:530:27 | vs | main.rs:530:26:530:27 | receiver for vs | +| main.rs:530:26:530:27 | vs | main.rs:535:5:535:6 | vs | +| main.rs:530:26:530:34 | [post] receiver for vs.iter() | main.rs:530:26:530:34 | [post] vs.iter() | +| main.rs:530:26:530:34 | vs.iter() | main.rs:530:26:530:34 | receiver for vs.iter() | +| main.rs:530:26:530:44 | ... .collect() | main.rs:530:9:530:11 | vs2 | +| main.rs:531:10:531:10 | [SSA] v | main.rs:532:14:532:14 | v | +| main.rs:531:10:531:10 | v | main.rs:531:10:531:10 | [SSA] v | +| main.rs:531:10:531:10 | v | main.rs:531:10:531:10 | v | +| main.rs:535:5:535:6 | [post] receiver for vs | main.rs:535:5:535:6 | [post] vs | +| main.rs:535:5:535:6 | [post] vs | main.rs:536:5:536:6 | vs | +| main.rs:535:5:535:6 | vs | main.rs:535:5:535:6 | receiver for vs | +| main.rs:535:5:535:6 | vs | main.rs:536:5:536:6 | vs | +| main.rs:535:5:535:13 | [post] receiver for vs.iter() | main.rs:535:5:535:13 | [post] vs.iter() | +| main.rs:535:5:535:13 | vs.iter() | main.rs:535:5:535:13 | receiver for vs.iter() | +| main.rs:535:20:535:20 | ... | main.rs:535:20:535:20 | x | +| main.rs:535:20:535:20 | [SSA] x | main.rs:535:29:535:29 | x | +| main.rs:535:20:535:20 | x | main.rs:535:20:535:20 | [SSA] x | +| main.rs:535:20:535:20 | x | main.rs:535:20:535:20 | x | +| main.rs:535:29:535:29 | [post] receiver for x | main.rs:535:29:535:29 | [post] x | +| main.rs:535:29:535:29 | x | main.rs:535:29:535:29 | receiver for x | +| main.rs:536:5:536:6 | [post] receiver for vs | main.rs:536:5:536:6 | [post] vs | +| main.rs:536:5:536:6 | [post] vs | main.rs:538:14:538:15 | vs | +| main.rs:536:5:536:6 | vs | main.rs:536:5:536:6 | receiver for vs | +| main.rs:536:5:536:6 | vs | main.rs:538:14:538:15 | vs | +| main.rs:536:5:536:13 | [post] receiver for vs.iter() | main.rs:536:5:536:13 | [post] vs.iter() | +| main.rs:536:5:536:13 | vs.iter() | main.rs:536:5:536:13 | receiver for vs.iter() | +| main.rs:536:25:536:25 | ... | main.rs:536:25:536:25 | x | +| main.rs:536:25:536:25 | [SSA] x | main.rs:536:34:536:34 | x | +| main.rs:536:25:536:25 | x | main.rs:536:25:536:25 | [SSA] x | +| main.rs:536:25:536:25 | x | main.rs:536:25:536:25 | x | +| main.rs:536:34:536:34 | [post] receiver for x | main.rs:536:34:536:34 | [post] x | +| main.rs:536:34:536:34 | x | main.rs:536:34:536:34 | receiver for x | +| main.rs:538:9:538:9 | [SSA] v | main.rs:539:14:539:14 | v | +| main.rs:538:9:538:9 | v | main.rs:538:9:538:9 | [SSA] v | +| main.rs:538:9:538:9 | v | main.rs:538:9:538:9 | v | +| main.rs:538:14:538:15 | [post] receiver for vs | main.rs:538:14:538:15 | [post] vs | +| main.rs:538:14:538:15 | vs | main.rs:538:14:538:15 | receiver for vs | +| main.rs:542:9:542:18 | mut vs_mut | main.rs:542:13:542:18 | vs_mut | +| main.rs:542:13:542:18 | [SSA] vs_mut | main.rs:544:10:544:15 | vs_mut | +| main.rs:542:13:542:18 | vs_mut | main.rs:542:13:542:18 | [SSA] vs_mut | +| main.rs:542:22:542:42 | [...] | main.rs:542:9:542:18 | mut vs_mut | +| main.rs:544:10:544:15 | [post] vs_mut | main.rs:545:11:545:16 | [SSA] vs_mut | +| main.rs:544:10:544:15 | [post] vs_mut | main.rs:545:11:545:16 | vs_mut | +| main.rs:544:10:544:15 | vs_mut | main.rs:545:11:545:16 | [SSA] vs_mut | +| main.rs:544:10:544:15 | vs_mut | main.rs:545:11:545:16 | vs_mut | +| main.rs:545:11:545:16 | [SSA] vs_mut | main.rs:546:11:546:16 | [SSA] vs_mut | +| main.rs:545:11:545:16 | [SSA] vs_mut | main.rs:546:11:546:16 | vs_mut | +| main.rs:545:11:545:16 | [post] receiver for vs_mut | main.rs:545:11:545:16 | [post] vs_mut | +| main.rs:545:11:545:16 | [post] vs_mut | main.rs:546:11:546:16 | [SSA] vs_mut | +| main.rs:545:11:545:16 | [post] vs_mut | main.rs:546:11:546:16 | vs_mut | +| main.rs:545:11:545:16 | vs_mut | main.rs:545:11:545:16 | receiver for vs_mut | +| main.rs:545:11:545:16 | vs_mut | main.rs:546:11:546:16 | [SSA] vs_mut | +| main.rs:545:11:545:16 | vs_mut | main.rs:546:11:546:16 | vs_mut | +| main.rs:545:11:545:23 | [post] receiver for vs_mut.iter() | main.rs:545:11:545:23 | [post] vs_mut.iter() | +| main.rs:545:11:545:23 | vs_mut.iter() | main.rs:545:11:545:23 | receiver for vs_mut.iter() | +| main.rs:545:11:545:30 | ... .next() | main.rs:545:11:545:30 | receiver for ... .next() | +| main.rs:545:11:545:30 | [post] receiver for ... .next() | main.rs:545:11:545:30 | [post] ... .next() | +| main.rs:545:11:545:39 | ... .unwrap() | main.rs:545:11:545:39 | receiver for ... .unwrap() | +| main.rs:545:11:545:39 | [post] receiver for ... .unwrap() | main.rs:545:11:545:39 | [post] ... .unwrap() | +| main.rs:546:11:546:16 | [SSA] vs_mut | main.rs:548:19:548:24 | vs_mut | +| main.rs:546:11:546:16 | [post] receiver for vs_mut | main.rs:546:11:546:16 | [post] vs_mut | +| main.rs:546:11:546:16 | [post] vs_mut | main.rs:548:19:548:24 | vs_mut | +| main.rs:546:11:546:16 | vs_mut | main.rs:546:11:546:16 | receiver for vs_mut | +| main.rs:546:11:546:16 | vs_mut | main.rs:548:19:548:24 | vs_mut | +| main.rs:546:11:546:23 | [post] receiver for vs_mut.iter() | main.rs:546:11:546:23 | [post] vs_mut.iter() | +| main.rs:546:11:546:23 | vs_mut.iter() | main.rs:546:11:546:23 | receiver for vs_mut.iter() | +| main.rs:546:11:546:30 | ... .nth(...) | main.rs:546:11:546:30 | receiver for ... .nth(...) | +| main.rs:546:11:546:30 | [post] receiver for ... .nth(...) | main.rs:546:11:546:30 | [post] ... .nth(...) | +| main.rs:546:11:546:39 | ... .unwrap() | main.rs:546:11:546:39 | receiver for ... .unwrap() | +| main.rs:546:11:546:39 | [post] receiver for ... .unwrap() | main.rs:546:11:546:39 | [post] ... .unwrap() | +| main.rs:548:5:550:5 | for ... in ... { ... } | main.rs:516:16:551:1 | { ... } | +| main.rs:548:14:548:14 | [SSA] v | main.rs:549:14:549:14 | v | +| main.rs:548:14:548:14 | v | main.rs:548:14:548:14 | [SSA] v | +| main.rs:548:14:548:14 | v | main.rs:548:14:548:14 | v | +| main.rs:548:19:548:24 | [post] receiver for vs_mut | main.rs:548:19:548:24 | [post] vs_mut | +| main.rs:548:19:548:24 | vs_mut | main.rs:548:19:548:24 | receiver for vs_mut | +| main.rs:554:9:554:9 | [SSA] a | main.rs:559:10:559:10 | a | | main.rs:554:9:554:9 | a | main.rs:554:9:554:9 | [SSA] a | | main.rs:554:9:554:9 | a | main.rs:554:9:554:9 | a | -| main.rs:554:18:554:27 | source(...) | main.rs:554:9:554:9 | a | -| main.rs:556:10:556:10 | [post] a | main.rs:557:10:557:10 | a | -| main.rs:556:10:556:10 | a | main.rs:557:10:557:10 | a | -| main.rs:557:10:557:10 | [post] a | main.rs:558:20:558:20 | a | -| main.rs:557:10:557:10 | [post] receiver for a | main.rs:557:10:557:10 | [post] a | -| main.rs:557:10:557:10 | a | main.rs:557:10:557:10 | receiver for a | -| main.rs:557:10:557:10 | a | main.rs:558:20:558:20 | a | -| main.rs:560:9:560:9 | [SSA] b | main.rs:562:10:562:10 | b | -| main.rs:560:9:560:9 | b | main.rs:560:9:560:9 | [SSA] b | -| main.rs:560:9:560:9 | b | main.rs:560:9:560:9 | b | -| main.rs:560:18:560:34 | ... as i32 | main.rs:560:9:560:9 | b | -| main.rs:562:10:562:10 | [post] b | main.rs:563:10:563:10 | b | -| main.rs:562:10:562:10 | b | main.rs:563:10:563:10 | b | -| main.rs:563:10:563:10 | [post] b | main.rs:564:20:564:20 | b | -| main.rs:563:10:563:10 | [post] receiver for b | main.rs:563:10:563:10 | [post] b | -| main.rs:563:10:563:10 | b | main.rs:563:10:563:10 | receiver for b | -| main.rs:563:10:563:10 | b | main.rs:564:20:564:20 | b | -| main.rs:592:13:592:33 | result_questionmark(...) | main.rs:592:9:592:9 | _ | -| main.rs:604:36:604:39 | ...::new(...) | main.rs:604:36:604:41 | MacroExpr | -| main.rs:604:36:604:41 | [post] MacroExpr | main.rs:604:36:604:39 | [post] ...::new(...) | +| main.rs:554:13:554:22 | source(...) | main.rs:554:9:554:9 | a | +| main.rs:555:9:555:9 | [SSA] b | main.rs:560:15:560:15 | b | +| main.rs:555:9:555:9 | b | main.rs:555:9:555:9 | [SSA] b | +| main.rs:555:9:555:9 | b | main.rs:555:9:555:9 | b | +| main.rs:555:13:555:22 | source(...) | main.rs:555:9:555:9 | b | +| main.rs:556:9:556:9 | [SSA] c | main.rs:557:18:557:18 | c | +| main.rs:556:9:556:9 | c | main.rs:556:9:556:9 | [SSA] c | +| main.rs:556:9:556:9 | c | main.rs:556:9:556:9 | c | +| main.rs:556:13:556:22 | source(...) | main.rs:556:9:556:9 | c | +| main.rs:557:9:557:13 | [SSA] c_ref | main.rs:561:14:561:18 | c_ref | +| main.rs:557:9:557:13 | c_ref | main.rs:557:9:557:13 | [SSA] c_ref | +| main.rs:557:9:557:13 | c_ref | main.rs:557:9:557:13 | c_ref | +| main.rs:557:17:557:18 | &c | main.rs:557:9:557:13 | c_ref | +| main.rs:561:14:561:18 | [post] c_ref | main.rs:562:11:562:15 | c_ref | +| main.rs:561:14:561:18 | c_ref | main.rs:562:11:562:15 | c_ref | +| main.rs:562:11:562:15 | [post] receiver for c_ref | main.rs:562:11:562:15 | [post] c_ref | +| main.rs:562:11:562:15 | c_ref | main.rs:562:11:562:15 | receiver for c_ref | +| main.rs:566:9:566:9 | [SSA] a | main.rs:568:10:568:10 | a | +| main.rs:566:9:566:9 | a | main.rs:566:9:566:9 | [SSA] a | +| main.rs:566:9:566:9 | a | main.rs:566:9:566:9 | a | +| main.rs:566:18:566:27 | source(...) | main.rs:566:9:566:9 | a | +| main.rs:568:10:568:10 | [post] a | main.rs:569:10:569:10 | a | +| main.rs:568:10:568:10 | a | main.rs:569:10:569:10 | a | +| main.rs:569:10:569:10 | [post] a | main.rs:570:20:570:20 | a | +| main.rs:569:10:569:10 | [post] receiver for a | main.rs:569:10:569:10 | [post] a | +| main.rs:569:10:569:10 | a | main.rs:569:10:569:10 | receiver for a | +| main.rs:569:10:569:10 | a | main.rs:570:20:570:20 | a | +| main.rs:572:9:572:9 | [SSA] b | main.rs:574:10:574:10 | b | +| main.rs:572:9:572:9 | b | main.rs:572:9:572:9 | [SSA] b | +| main.rs:572:9:572:9 | b | main.rs:572:9:572:9 | b | +| main.rs:572:18:572:34 | ... as i32 | main.rs:572:9:572:9 | b | +| main.rs:574:10:574:10 | [post] b | main.rs:575:10:575:10 | b | +| main.rs:574:10:574:10 | b | main.rs:575:10:575:10 | b | +| main.rs:575:10:575:10 | [post] b | main.rs:576:20:576:20 | b | +| main.rs:575:10:575:10 | [post] receiver for b | main.rs:575:10:575:10 | [post] b | +| main.rs:575:10:575:10 | b | main.rs:575:10:575:10 | receiver for b | +| main.rs:575:10:575:10 | b | main.rs:576:20:576:20 | b | +| main.rs:604:13:604:33 | result_questionmark(...) | main.rs:604:9:604:9 | _ | +| main.rs:616:36:616:39 | ...::new(...) | main.rs:616:36:616:41 | MacroExpr | +| main.rs:616:36:616:41 | [post] MacroExpr | main.rs:616:36:616:39 | [post] ...::new(...) | readStep | main.rs:50:9:50:15 | Some(...) | {EXTERNAL LOCATION} | Some | main.rs:50:14:50:14 | _ | -| main.rs:104:11:104:11 | [post] receiver for i | file://:0:0:0:0 | &ref | main.rs:104:11:104:11 | [post] i | -| main.rs:104:11:104:11 | i | file://:0:0:0:0 | &ref | main.rs:104:10:104:11 | * ... | -| main.rs:112:10:112:10 | a | file://:0:0:0:0 | tuple.0 | main.rs:112:10:112:12 | a.0 | -| main.rs:113:10:113:10 | a | file://:0:0:0:0 | tuple.1 | main.rs:113:10:113:12 | a.1 | -| main.rs:118:9:118:20 | TuplePat | file://:0:0:0:0 | tuple.0 | main.rs:118:10:118:11 | a0 | -| main.rs:118:9:118:20 | TuplePat | file://:0:0:0:0 | tuple.1 | main.rs:118:14:118:15 | a1 | -| main.rs:118:9:118:20 | TuplePat | file://:0:0:0:0 | tuple.2 | main.rs:118:18:118:19 | a2 | -| main.rs:126:10:126:10 | a | file://:0:0:0:0 | tuple.0 | main.rs:126:10:126:12 | a.0 | -| main.rs:127:10:127:10 | a | file://:0:0:0:0 | tuple.1 | main.rs:127:10:127:12 | a.1 | -| main.rs:128:5:128:5 | a | file://:0:0:0:0 | tuple.0 | main.rs:128:5:128:7 | a.0 | -| main.rs:129:5:129:5 | a | file://:0:0:0:0 | tuple.1 | main.rs:129:5:129:7 | a.1 | -| main.rs:130:10:130:10 | a | file://:0:0:0:0 | tuple.0 | main.rs:130:10:130:12 | a.0 | -| main.rs:131:10:131:10 | a | file://:0:0:0:0 | tuple.1 | main.rs:131:10:131:12 | a.1 | -| main.rs:137:10:137:10 | b | file://:0:0:0:0 | tuple.0 | main.rs:137:10:137:12 | b.0 | -| main.rs:137:10:137:12 | b.0 | file://:0:0:0:0 | tuple.0 | main.rs:137:10:137:15 | ... .0 | -| main.rs:138:10:138:10 | b | file://:0:0:0:0 | tuple.0 | main.rs:138:10:138:12 | b.0 | -| main.rs:138:10:138:12 | b.0 | file://:0:0:0:0 | tuple.1 | main.rs:138:10:138:15 | ... .1 | -| main.rs:139:10:139:10 | b | file://:0:0:0:0 | tuple.1 | main.rs:139:10:139:12 | b.1 | -| main.rs:152:10:152:10 | p | main.rs:146:5:146:10 | Point.x | main.rs:152:10:152:12 | p.x | -| main.rs:153:10:153:10 | p | main.rs:147:5:147:10 | Point.y | main.rs:153:10:153:12 | p.y | -| main.rs:158:10:158:10 | p | main.rs:147:5:147:10 | Point.y | main.rs:158:10:158:12 | p.y | -| main.rs:159:5:159:5 | p | main.rs:147:5:147:10 | Point.y | main.rs:159:5:159:7 | p.y | -| main.rs:160:10:160:10 | p | main.rs:147:5:147:10 | Point.y | main.rs:160:10:160:12 | p.y | -| main.rs:168:9:168:28 | Point {...} | main.rs:146:5:146:10 | Point.x | main.rs:168:20:168:20 | a | -| main.rs:168:9:168:28 | Point {...} | main.rs:147:5:147:10 | Point.y | main.rs:168:26:168:26 | b | -| main.rs:186:10:186:10 | p | main.rs:174:5:174:16 | Point3D.plane | main.rs:186:10:186:16 | p.plane | -| main.rs:186:10:186:16 | p.plane | main.rs:146:5:146:10 | Point.x | main.rs:186:10:186:18 | ... .x | -| main.rs:187:10:187:10 | p | main.rs:174:5:174:16 | Point3D.plane | main.rs:187:10:187:16 | p.plane | -| main.rs:187:10:187:16 | p.plane | main.rs:147:5:147:10 | Point.y | main.rs:187:10:187:18 | ... .y | -| main.rs:188:10:188:10 | p | main.rs:175:5:175:10 | Point3D.z | main.rs:188:10:188:12 | p.z | -| main.rs:198:9:201:9 | Point3D {...} | main.rs:174:5:174:16 | Point3D.plane | main.rs:199:20:199:33 | Point {...} | -| main.rs:198:9:201:9 | Point3D {...} | main.rs:175:5:175:10 | Point3D.z | main.rs:200:13:200:13 | z | -| main.rs:199:20:199:33 | Point {...} | main.rs:146:5:146:10 | Point.x | main.rs:199:28:199:28 | x | -| main.rs:199:20:199:33 | Point {...} | main.rs:147:5:147:10 | Point.y | main.rs:199:31:199:31 | y | -| main.rs:213:10:213:10 | s | file://:0:0:0:0 | tuple.0 | main.rs:213:10:213:12 | s.0 | -| main.rs:213:10:213:10 | s | main.rs:209:22:209:24 | MyTupleStruct(0) | main.rs:213:10:213:12 | s.0 | -| main.rs:214:10:214:10 | s | file://:0:0:0:0 | tuple.1 | main.rs:214:10:214:12 | s.1 | -| main.rs:214:10:214:10 | s | main.rs:209:27:209:29 | MyTupleStruct(1) | main.rs:214:10:214:12 | s.1 | -| main.rs:217:9:217:27 | MyTupleStruct(...) | main.rs:209:22:209:24 | MyTupleStruct(0) | main.rs:217:23:217:23 | x | -| main.rs:217:9:217:27 | MyTupleStruct(...) | main.rs:209:27:209:29 | MyTupleStruct(1) | main.rs:217:26:217:26 | y | -| main.rs:231:9:231:23 | ...::Some(...) | {EXTERNAL LOCATION} | Some | main.rs:231:22:231:22 | n | -| main.rs:235:9:235:23 | ...::Some(...) | {EXTERNAL LOCATION} | Some | main.rs:235:22:235:22 | n | -| main.rs:244:9:244:15 | Some(...) | {EXTERNAL LOCATION} | Some | main.rs:244:14:244:14 | n | -| main.rs:248:9:248:15 | Some(...) | {EXTERNAL LOCATION} | Some | main.rs:248:14:248:14 | n | -| main.rs:255:12:255:18 | Some(...) | {EXTERNAL LOCATION} | Some | main.rs:255:17:255:17 | n | -| main.rs:289:14:289:15 | s1 | {EXTERNAL LOCATION} | Some | main.rs:289:14:289:16 | TryExpr | -| main.rs:289:14:289:15 | s1 | {EXTERNAL LOCATION} | Ok | main.rs:289:14:289:16 | TryExpr | -| main.rs:291:10:291:11 | s2 | {EXTERNAL LOCATION} | Some | main.rs:291:10:291:12 | TryExpr | -| main.rs:291:10:291:11 | s2 | {EXTERNAL LOCATION} | Ok | main.rs:291:10:291:12 | TryExpr | -| main.rs:313:14:313:15 | s1 | {EXTERNAL LOCATION} | Some | main.rs:313:14:313:16 | TryExpr | -| main.rs:313:14:313:15 | s1 | {EXTERNAL LOCATION} | Ok | main.rs:313:14:313:16 | TryExpr | -| main.rs:314:14:314:15 | s2 | {EXTERNAL LOCATION} | Some | main.rs:314:14:314:16 | TryExpr | -| main.rs:314:14:314:15 | s2 | {EXTERNAL LOCATION} | Ok | main.rs:314:14:314:16 | TryExpr | -| main.rs:317:14:317:15 | s3 | {EXTERNAL LOCATION} | Some | main.rs:317:14:317:16 | TryExpr | -| main.rs:317:14:317:15 | s3 | {EXTERNAL LOCATION} | Ok | main.rs:317:14:317:16 | TryExpr | -| main.rs:341:9:341:25 | ...::A(...) | main.rs:333:7:333:9 | A | main.rs:341:24:341:24 | n | -| main.rs:342:9:342:25 | ...::B(...) | main.rs:334:7:334:9 | B | main.rs:342:24:342:24 | n | -| main.rs:345:9:345:25 | ...::A(...) | main.rs:333:7:333:9 | A | main.rs:345:24:345:24 | n | -| main.rs:345:29:345:45 | ...::B(...) | main.rs:334:7:334:9 | B | main.rs:345:44:345:44 | n | -| main.rs:348:9:348:25 | ...::A(...) | main.rs:333:7:333:9 | A | main.rs:348:24:348:24 | n | -| main.rs:349:9:349:25 | ...::B(...) | main.rs:334:7:334:9 | B | main.rs:349:24:349:24 | n | -| main.rs:359:9:359:12 | A(...) | main.rs:333:7:333:9 | A | main.rs:359:11:359:11 | n | -| main.rs:360:9:360:12 | B(...) | main.rs:334:7:334:9 | B | main.rs:360:11:360:11 | n | -| main.rs:363:9:363:12 | A(...) | main.rs:333:7:333:9 | A | main.rs:363:11:363:11 | n | -| main.rs:363:16:363:19 | B(...) | main.rs:334:7:334:9 | B | main.rs:363:18:363:18 | n | -| main.rs:366:9:366:12 | A(...) | main.rs:333:7:333:9 | A | main.rs:366:11:366:11 | n | -| main.rs:367:9:367:12 | B(...) | main.rs:334:7:334:9 | B | main.rs:367:11:367:11 | n | -| main.rs:382:9:382:38 | ...::C {...} | main.rs:372:9:372:20 | C | main.rs:382:36:382:36 | n | -| main.rs:383:9:383:38 | ...::D {...} | main.rs:373:9:373:20 | D | main.rs:383:36:383:36 | n | -| main.rs:386:9:386:38 | ...::C {...} | main.rs:372:9:372:20 | C | main.rs:386:36:386:36 | n | -| main.rs:386:42:386:71 | ...::D {...} | main.rs:373:9:373:20 | D | main.rs:386:69:386:69 | n | -| main.rs:389:9:389:38 | ...::C {...} | main.rs:372:9:372:20 | C | main.rs:389:36:389:36 | n | -| main.rs:390:9:390:38 | ...::D {...} | main.rs:373:9:373:20 | D | main.rs:390:36:390:36 | n | -| main.rs:402:9:402:24 | C {...} | main.rs:372:9:372:20 | C | main.rs:402:22:402:22 | n | -| main.rs:403:9:403:24 | D {...} | main.rs:373:9:373:20 | D | main.rs:403:22:403:22 | n | -| main.rs:406:9:406:24 | C {...} | main.rs:372:9:372:20 | C | main.rs:406:22:406:22 | n | -| main.rs:406:28:406:43 | D {...} | main.rs:373:9:373:20 | D | main.rs:406:41:406:41 | n | -| main.rs:409:9:409:24 | C {...} | main.rs:372:9:372:20 | C | main.rs:409:22:409:22 | n | -| main.rs:410:9:410:24 | D {...} | main.rs:373:9:373:20 | D | main.rs:410:22:410:22 | n | -| main.rs:419:14:419:17 | arr1 | file://:0:0:0:0 | element | main.rs:419:14:419:20 | arr1[2] | -| main.rs:423:14:423:17 | arr2 | file://:0:0:0:0 | element | main.rs:423:14:423:20 | arr2[4] | -| main.rs:427:14:427:17 | arr3 | file://:0:0:0:0 | element | main.rs:427:14:427:20 | arr3[2] | -| main.rs:433:15:433:18 | arr1 | file://:0:0:0:0 | element | main.rs:433:9:433:10 | n1 | -| main.rs:438:15:438:18 | arr2 | file://:0:0:0:0 | element | main.rs:438:9:438:10 | n2 | -| main.rs:446:9:446:17 | SlicePat | file://:0:0:0:0 | element | main.rs:446:10:446:10 | a | -| main.rs:446:9:446:17 | SlicePat | file://:0:0:0:0 | element | main.rs:446:13:446:13 | b | -| main.rs:446:9:446:17 | SlicePat | file://:0:0:0:0 | element | main.rs:446:16:446:16 | c | -| main.rs:456:10:456:16 | mut_arr | file://:0:0:0:0 | element | main.rs:456:10:456:19 | mut_arr[1] | -| main.rs:458:5:458:11 | mut_arr | file://:0:0:0:0 | element | main.rs:458:5:458:14 | mut_arr[1] | -| main.rs:459:13:459:19 | mut_arr | file://:0:0:0:0 | element | main.rs:459:13:459:22 | mut_arr[1] | -| main.rs:461:10:461:16 | mut_arr | file://:0:0:0:0 | element | main.rs:461:10:461:19 | mut_arr[0] | -| main.rs:468:9:468:20 | TuplePat | file://:0:0:0:0 | tuple.0 | main.rs:468:10:468:13 | cond | -| main.rs:468:9:468:20 | TuplePat | file://:0:0:0:0 | tuple.1 | main.rs:468:16:468:19 | name | -| main.rs:468:25:468:29 | names | file://:0:0:0:0 | element | main.rs:468:9:468:20 | TuplePat | -| main.rs:470:41:470:67 | [post] \|...\| ... | main.rs:467:9:467:20 | captured default_name | main.rs:470:41:470:67 | [post] default_name | -| main.rs:470:44:470:55 | this | main.rs:467:9:467:20 | captured default_name | main.rs:470:44:470:55 | default_name | -| main.rs:471:18:471:18 | [post] receiver for n | file://:0:0:0:0 | &ref | main.rs:471:18:471:18 | [post] n | -| main.rs:495:13:495:13 | [post] receiver for b | file://:0:0:0:0 | &ref | main.rs:495:13:495:13 | [post] b | -| main.rs:496:18:496:18 | [post] receiver for b | file://:0:0:0:0 | &ref | main.rs:496:18:496:18 | [post] b | -| main.rs:507:10:507:11 | vs | file://:0:0:0:0 | element | main.rs:507:10:507:14 | vs[0] | -| main.rs:508:11:508:35 | ... .unwrap() | file://:0:0:0:0 | &ref | main.rs:508:10:508:35 | * ... | -| main.rs:509:11:509:35 | ... .unwrap() | file://:0:0:0:0 | &ref | main.rs:509:10:509:35 | * ... | -| main.rs:511:14:511:15 | vs | file://:0:0:0:0 | element | main.rs:511:9:511:9 | v | -| main.rs:514:9:514:10 | &... | file://:0:0:0:0 | &ref | main.rs:514:10:514:10 | v | -| main.rs:514:15:514:23 | vs.iter() | file://:0:0:0:0 | element | main.rs:514:9:514:10 | &... | -| main.rs:519:9:519:10 | &... | file://:0:0:0:0 | &ref | main.rs:519:10:519:10 | v | -| main.rs:519:15:519:17 | vs2 | file://:0:0:0:0 | element | main.rs:519:9:519:10 | &... | -| main.rs:523:29:523:29 | x | file://:0:0:0:0 | &ref | main.rs:523:28:523:29 | * ... | -| main.rs:524:34:524:34 | x | file://:0:0:0:0 | &ref | main.rs:524:33:524:34 | * ... | -| main.rs:526:14:526:27 | vs.into_iter() | file://:0:0:0:0 | element | main.rs:526:9:526:9 | v | -| main.rs:532:10:532:15 | vs_mut | file://:0:0:0:0 | element | main.rs:532:10:532:18 | vs_mut[0] | -| main.rs:533:11:533:39 | ... .unwrap() | file://:0:0:0:0 | &ref | main.rs:533:10:533:39 | * ... | -| main.rs:534:11:534:39 | ... .unwrap() | file://:0:0:0:0 | &ref | main.rs:534:10:534:39 | * ... | -| main.rs:536:9:536:14 | &mut ... | file://:0:0:0:0 | &ref | main.rs:536:14:536:14 | v | -| main.rs:536:19:536:35 | vs_mut.iter_mut() | file://:0:0:0:0 | element | main.rs:536:9:536:14 | &mut ... | -| main.rs:550:11:550:15 | c_ref | file://:0:0:0:0 | &ref | main.rs:550:10:550:15 | * ... | +| main.rs:116:11:116:11 | [post] receiver for i | file://:0:0:0:0 | &ref | main.rs:116:11:116:11 | [post] i | +| main.rs:116:11:116:11 | i | file://:0:0:0:0 | &ref | main.rs:116:10:116:11 | * ... | +| main.rs:124:10:124:10 | a | file://:0:0:0:0 | tuple.0 | main.rs:124:10:124:12 | a.0 | +| main.rs:125:10:125:10 | a | file://:0:0:0:0 | tuple.1 | main.rs:125:10:125:12 | a.1 | +| main.rs:130:9:130:20 | TuplePat | file://:0:0:0:0 | tuple.0 | main.rs:130:10:130:11 | a0 | +| main.rs:130:9:130:20 | TuplePat | file://:0:0:0:0 | tuple.1 | main.rs:130:14:130:15 | a1 | +| main.rs:130:9:130:20 | TuplePat | file://:0:0:0:0 | tuple.2 | main.rs:130:18:130:19 | a2 | +| main.rs:138:10:138:10 | a | file://:0:0:0:0 | tuple.0 | main.rs:138:10:138:12 | a.0 | +| main.rs:139:10:139:10 | a | file://:0:0:0:0 | tuple.1 | main.rs:139:10:139:12 | a.1 | +| main.rs:140:5:140:5 | a | file://:0:0:0:0 | tuple.0 | main.rs:140:5:140:7 | a.0 | +| main.rs:141:5:141:5 | a | file://:0:0:0:0 | tuple.1 | main.rs:141:5:141:7 | a.1 | +| main.rs:142:10:142:10 | a | file://:0:0:0:0 | tuple.0 | main.rs:142:10:142:12 | a.0 | +| main.rs:143:10:143:10 | a | file://:0:0:0:0 | tuple.1 | main.rs:143:10:143:12 | a.1 | +| main.rs:149:10:149:10 | b | file://:0:0:0:0 | tuple.0 | main.rs:149:10:149:12 | b.0 | +| main.rs:149:10:149:12 | b.0 | file://:0:0:0:0 | tuple.0 | main.rs:149:10:149:15 | ... .0 | +| main.rs:150:10:150:10 | b | file://:0:0:0:0 | tuple.0 | main.rs:150:10:150:12 | b.0 | +| main.rs:150:10:150:12 | b.0 | file://:0:0:0:0 | tuple.1 | main.rs:150:10:150:15 | ... .1 | +| main.rs:151:10:151:10 | b | file://:0:0:0:0 | tuple.1 | main.rs:151:10:151:12 | b.1 | +| main.rs:164:10:164:10 | p | main.rs:158:5:158:10 | Point.x | main.rs:164:10:164:12 | p.x | +| main.rs:165:10:165:10 | p | main.rs:159:5:159:10 | Point.y | main.rs:165:10:165:12 | p.y | +| main.rs:170:10:170:10 | p | main.rs:159:5:159:10 | Point.y | main.rs:170:10:170:12 | p.y | +| main.rs:171:5:171:5 | p | main.rs:159:5:159:10 | Point.y | main.rs:171:5:171:7 | p.y | +| main.rs:172:10:172:10 | p | main.rs:159:5:159:10 | Point.y | main.rs:172:10:172:12 | p.y | +| main.rs:180:9:180:28 | Point {...} | main.rs:158:5:158:10 | Point.x | main.rs:180:20:180:20 | a | +| main.rs:180:9:180:28 | Point {...} | main.rs:159:5:159:10 | Point.y | main.rs:180:26:180:26 | b | +| main.rs:198:10:198:10 | p | main.rs:186:5:186:16 | Point3D.plane | main.rs:198:10:198:16 | p.plane | +| main.rs:198:10:198:16 | p.plane | main.rs:158:5:158:10 | Point.x | main.rs:198:10:198:18 | ... .x | +| main.rs:199:10:199:10 | p | main.rs:186:5:186:16 | Point3D.plane | main.rs:199:10:199:16 | p.plane | +| main.rs:199:10:199:16 | p.plane | main.rs:159:5:159:10 | Point.y | main.rs:199:10:199:18 | ... .y | +| main.rs:200:10:200:10 | p | main.rs:187:5:187:10 | Point3D.z | main.rs:200:10:200:12 | p.z | +| main.rs:210:9:213:9 | Point3D {...} | main.rs:186:5:186:16 | Point3D.plane | main.rs:211:20:211:33 | Point {...} | +| main.rs:210:9:213:9 | Point3D {...} | main.rs:187:5:187:10 | Point3D.z | main.rs:212:13:212:13 | z | +| main.rs:211:20:211:33 | Point {...} | main.rs:158:5:158:10 | Point.x | main.rs:211:28:211:28 | x | +| main.rs:211:20:211:33 | Point {...} | main.rs:159:5:159:10 | Point.y | main.rs:211:31:211:31 | y | +| main.rs:225:10:225:10 | s | file://:0:0:0:0 | tuple.0 | main.rs:225:10:225:12 | s.0 | +| main.rs:225:10:225:10 | s | main.rs:221:22:221:24 | MyTupleStruct(0) | main.rs:225:10:225:12 | s.0 | +| main.rs:226:10:226:10 | s | file://:0:0:0:0 | tuple.1 | main.rs:226:10:226:12 | s.1 | +| main.rs:226:10:226:10 | s | main.rs:221:27:221:29 | MyTupleStruct(1) | main.rs:226:10:226:12 | s.1 | +| main.rs:229:9:229:27 | MyTupleStruct(...) | main.rs:221:22:221:24 | MyTupleStruct(0) | main.rs:229:23:229:23 | x | +| main.rs:229:9:229:27 | MyTupleStruct(...) | main.rs:221:27:221:29 | MyTupleStruct(1) | main.rs:229:26:229:26 | y | +| main.rs:243:9:243:23 | ...::Some(...) | {EXTERNAL LOCATION} | Some | main.rs:243:22:243:22 | n | +| main.rs:247:9:247:23 | ...::Some(...) | {EXTERNAL LOCATION} | Some | main.rs:247:22:247:22 | n | +| main.rs:256:9:256:15 | Some(...) | {EXTERNAL LOCATION} | Some | main.rs:256:14:256:14 | n | +| main.rs:260:9:260:15 | Some(...) | {EXTERNAL LOCATION} | Some | main.rs:260:14:260:14 | n | +| main.rs:267:12:267:18 | Some(...) | {EXTERNAL LOCATION} | Some | main.rs:267:17:267:17 | n | +| main.rs:301:14:301:15 | s1 | {EXTERNAL LOCATION} | Some | main.rs:301:14:301:16 | TryExpr | +| main.rs:301:14:301:15 | s1 | {EXTERNAL LOCATION} | Ok | main.rs:301:14:301:16 | TryExpr | +| main.rs:303:10:303:11 | s2 | {EXTERNAL LOCATION} | Some | main.rs:303:10:303:12 | TryExpr | +| main.rs:303:10:303:11 | s2 | {EXTERNAL LOCATION} | Ok | main.rs:303:10:303:12 | TryExpr | +| main.rs:325:14:325:15 | s1 | {EXTERNAL LOCATION} | Some | main.rs:325:14:325:16 | TryExpr | +| main.rs:325:14:325:15 | s1 | {EXTERNAL LOCATION} | Ok | main.rs:325:14:325:16 | TryExpr | +| main.rs:326:14:326:15 | s2 | {EXTERNAL LOCATION} | Some | main.rs:326:14:326:16 | TryExpr | +| main.rs:326:14:326:15 | s2 | {EXTERNAL LOCATION} | Ok | main.rs:326:14:326:16 | TryExpr | +| main.rs:329:14:329:15 | s3 | {EXTERNAL LOCATION} | Some | main.rs:329:14:329:16 | TryExpr | +| main.rs:329:14:329:15 | s3 | {EXTERNAL LOCATION} | Ok | main.rs:329:14:329:16 | TryExpr | +| main.rs:353:9:353:25 | ...::A(...) | main.rs:345:7:345:9 | A | main.rs:353:24:353:24 | n | +| main.rs:354:9:354:25 | ...::B(...) | main.rs:346:7:346:9 | B | main.rs:354:24:354:24 | n | +| main.rs:357:9:357:25 | ...::A(...) | main.rs:345:7:345:9 | A | main.rs:357:24:357:24 | n | +| main.rs:357:29:357:45 | ...::B(...) | main.rs:346:7:346:9 | B | main.rs:357:44:357:44 | n | +| main.rs:360:9:360:25 | ...::A(...) | main.rs:345:7:345:9 | A | main.rs:360:24:360:24 | n | +| main.rs:361:9:361:25 | ...::B(...) | main.rs:346:7:346:9 | B | main.rs:361:24:361:24 | n | +| main.rs:371:9:371:12 | A(...) | main.rs:345:7:345:9 | A | main.rs:371:11:371:11 | n | +| main.rs:372:9:372:12 | B(...) | main.rs:346:7:346:9 | B | main.rs:372:11:372:11 | n | +| main.rs:375:9:375:12 | A(...) | main.rs:345:7:345:9 | A | main.rs:375:11:375:11 | n | +| main.rs:375:16:375:19 | B(...) | main.rs:346:7:346:9 | B | main.rs:375:18:375:18 | n | +| main.rs:378:9:378:12 | A(...) | main.rs:345:7:345:9 | A | main.rs:378:11:378:11 | n | +| main.rs:379:9:379:12 | B(...) | main.rs:346:7:346:9 | B | main.rs:379:11:379:11 | n | +| main.rs:394:9:394:38 | ...::C {...} | main.rs:384:9:384:20 | C | main.rs:394:36:394:36 | n | +| main.rs:395:9:395:38 | ...::D {...} | main.rs:385:9:385:20 | D | main.rs:395:36:395:36 | n | +| main.rs:398:9:398:38 | ...::C {...} | main.rs:384:9:384:20 | C | main.rs:398:36:398:36 | n | +| main.rs:398:42:398:71 | ...::D {...} | main.rs:385:9:385:20 | D | main.rs:398:69:398:69 | n | +| main.rs:401:9:401:38 | ...::C {...} | main.rs:384:9:384:20 | C | main.rs:401:36:401:36 | n | +| main.rs:402:9:402:38 | ...::D {...} | main.rs:385:9:385:20 | D | main.rs:402:36:402:36 | n | +| main.rs:414:9:414:24 | C {...} | main.rs:384:9:384:20 | C | main.rs:414:22:414:22 | n | +| main.rs:415:9:415:24 | D {...} | main.rs:385:9:385:20 | D | main.rs:415:22:415:22 | n | +| main.rs:418:9:418:24 | C {...} | main.rs:384:9:384:20 | C | main.rs:418:22:418:22 | n | +| main.rs:418:28:418:43 | D {...} | main.rs:385:9:385:20 | D | main.rs:418:41:418:41 | n | +| main.rs:421:9:421:24 | C {...} | main.rs:384:9:384:20 | C | main.rs:421:22:421:22 | n | +| main.rs:422:9:422:24 | D {...} | main.rs:385:9:385:20 | D | main.rs:422:22:422:22 | n | +| main.rs:431:14:431:17 | arr1 | file://:0:0:0:0 | element | main.rs:431:14:431:20 | arr1[2] | +| main.rs:435:14:435:17 | arr2 | file://:0:0:0:0 | element | main.rs:435:14:435:20 | arr2[4] | +| main.rs:439:14:439:17 | arr3 | file://:0:0:0:0 | element | main.rs:439:14:439:20 | arr3[2] | +| main.rs:445:15:445:18 | arr1 | file://:0:0:0:0 | element | main.rs:445:9:445:10 | n1 | +| main.rs:450:15:450:18 | arr2 | file://:0:0:0:0 | element | main.rs:450:9:450:10 | n2 | +| main.rs:458:9:458:17 | SlicePat | file://:0:0:0:0 | element | main.rs:458:10:458:10 | a | +| main.rs:458:9:458:17 | SlicePat | file://:0:0:0:0 | element | main.rs:458:13:458:13 | b | +| main.rs:458:9:458:17 | SlicePat | file://:0:0:0:0 | element | main.rs:458:16:458:16 | c | +| main.rs:468:10:468:16 | mut_arr | file://:0:0:0:0 | element | main.rs:468:10:468:19 | mut_arr[1] | +| main.rs:470:5:470:11 | mut_arr | file://:0:0:0:0 | element | main.rs:470:5:470:14 | mut_arr[1] | +| main.rs:471:13:471:19 | mut_arr | file://:0:0:0:0 | element | main.rs:471:13:471:22 | mut_arr[1] | +| main.rs:473:10:473:16 | mut_arr | file://:0:0:0:0 | element | main.rs:473:10:473:19 | mut_arr[0] | +| main.rs:480:9:480:20 | TuplePat | file://:0:0:0:0 | tuple.0 | main.rs:480:10:480:13 | cond | +| main.rs:480:9:480:20 | TuplePat | file://:0:0:0:0 | tuple.1 | main.rs:480:16:480:19 | name | +| main.rs:480:25:480:29 | names | file://:0:0:0:0 | element | main.rs:480:9:480:20 | TuplePat | +| main.rs:482:41:482:67 | [post] \|...\| ... | main.rs:479:9:479:20 | captured default_name | main.rs:482:41:482:67 | [post] default_name | +| main.rs:482:44:482:55 | this | main.rs:479:9:479:20 | captured default_name | main.rs:482:44:482:55 | default_name | +| main.rs:483:18:483:18 | [post] receiver for n | file://:0:0:0:0 | &ref | main.rs:483:18:483:18 | [post] n | +| main.rs:507:13:507:13 | [post] receiver for b | file://:0:0:0:0 | &ref | main.rs:507:13:507:13 | [post] b | +| main.rs:508:18:508:18 | [post] receiver for b | file://:0:0:0:0 | &ref | main.rs:508:18:508:18 | [post] b | +| main.rs:519:10:519:11 | vs | file://:0:0:0:0 | element | main.rs:519:10:519:14 | vs[0] | +| main.rs:520:11:520:35 | ... .unwrap() | file://:0:0:0:0 | &ref | main.rs:520:10:520:35 | * ... | +| main.rs:521:11:521:35 | ... .unwrap() | file://:0:0:0:0 | &ref | main.rs:521:10:521:35 | * ... | +| main.rs:523:14:523:15 | vs | file://:0:0:0:0 | element | main.rs:523:9:523:9 | v | +| main.rs:526:9:526:10 | &... | file://:0:0:0:0 | &ref | main.rs:526:10:526:10 | v | +| main.rs:526:15:526:23 | vs.iter() | file://:0:0:0:0 | element | main.rs:526:9:526:10 | &... | +| main.rs:531:9:531:10 | &... | file://:0:0:0:0 | &ref | main.rs:531:10:531:10 | v | +| main.rs:531:15:531:17 | vs2 | file://:0:0:0:0 | element | main.rs:531:9:531:10 | &... | +| main.rs:535:29:535:29 | x | file://:0:0:0:0 | &ref | main.rs:535:28:535:29 | * ... | +| main.rs:536:34:536:34 | x | file://:0:0:0:0 | &ref | main.rs:536:33:536:34 | * ... | +| main.rs:538:14:538:27 | vs.into_iter() | file://:0:0:0:0 | element | main.rs:538:9:538:9 | v | +| main.rs:544:10:544:15 | vs_mut | file://:0:0:0:0 | element | main.rs:544:10:544:18 | vs_mut[0] | +| main.rs:545:11:545:39 | ... .unwrap() | file://:0:0:0:0 | &ref | main.rs:545:10:545:39 | * ... | +| main.rs:546:11:546:39 | ... .unwrap() | file://:0:0:0:0 | &ref | main.rs:546:10:546:39 | * ... | +| main.rs:548:9:548:14 | &mut ... | file://:0:0:0:0 | &ref | main.rs:548:14:548:14 | v | +| main.rs:548:19:548:35 | vs_mut.iter_mut() | file://:0:0:0:0 | element | main.rs:548:9:548:14 | &mut ... | +| main.rs:562:11:562:15 | c_ref | file://:0:0:0:0 | &ref | main.rs:562:10:562:15 | * ... | storeStep -| main.rs:104:11:104:11 | i | file://:0:0:0:0 | &ref | main.rs:104:11:104:11 | receiver for i | -| main.rs:111:14:111:22 | source(...) | file://:0:0:0:0 | tuple.0 | main.rs:111:13:111:26 | TupleExpr | -| main.rs:111:25:111:25 | 2 | file://:0:0:0:0 | tuple.1 | main.rs:111:13:111:26 | TupleExpr | -| main.rs:117:14:117:14 | 2 | file://:0:0:0:0 | tuple.0 | main.rs:117:13:117:30 | TupleExpr | -| main.rs:117:17:117:26 | source(...) | file://:0:0:0:0 | tuple.1 | main.rs:117:13:117:30 | TupleExpr | -| main.rs:117:29:117:29 | 2 | file://:0:0:0:0 | tuple.2 | main.rs:117:13:117:30 | TupleExpr | -| main.rs:125:18:125:18 | 2 | file://:0:0:0:0 | tuple.0 | main.rs:125:17:125:31 | TupleExpr | -| main.rs:125:21:125:30 | source(...) | file://:0:0:0:0 | tuple.1 | main.rs:125:17:125:31 | TupleExpr | -| main.rs:128:11:128:20 | source(...) | file://:0:0:0:0 | tuple.0 | main.rs:128:5:128:5 | [post] a | -| main.rs:129:11:129:11 | 2 | file://:0:0:0:0 | tuple.1 | main.rs:129:5:129:5 | [post] a | -| main.rs:135:14:135:14 | 3 | file://:0:0:0:0 | tuple.0 | main.rs:135:13:135:27 | TupleExpr | -| main.rs:135:17:135:26 | source(...) | file://:0:0:0:0 | tuple.1 | main.rs:135:13:135:27 | TupleExpr | -| main.rs:136:14:136:14 | a | file://:0:0:0:0 | tuple.0 | main.rs:136:13:136:18 | TupleExpr | -| main.rs:136:17:136:17 | 3 | file://:0:0:0:0 | tuple.1 | main.rs:136:13:136:18 | TupleExpr | -| main.rs:151:24:151:32 | source(...) | main.rs:146:5:146:10 | Point.x | main.rs:151:13:151:40 | Point {...} | -| main.rs:151:38:151:38 | 2 | main.rs:147:5:147:10 | Point.y | main.rs:151:13:151:40 | Point {...} | -| main.rs:157:28:157:36 | source(...) | main.rs:146:5:146:10 | Point.x | main.rs:157:17:157:44 | Point {...} | -| main.rs:157:42:157:42 | 2 | main.rs:147:5:147:10 | Point.y | main.rs:157:17:157:44 | Point {...} | -| main.rs:159:11:159:20 | source(...) | main.rs:147:5:147:10 | Point.y | main.rs:159:5:159:5 | [post] p | -| main.rs:165:12:165:21 | source(...) | main.rs:146:5:146:10 | Point.x | main.rs:164:13:167:5 | Point {...} | -| main.rs:166:12:166:12 | 2 | main.rs:147:5:147:10 | Point.y | main.rs:164:13:167:5 | Point {...} | -| main.rs:180:16:183:9 | Point {...} | main.rs:174:5:174:16 | Point3D.plane | main.rs:179:13:185:5 | Point3D {...} | -| main.rs:181:16:181:16 | 2 | main.rs:146:5:146:10 | Point.x | main.rs:180:16:183:9 | Point {...} | -| main.rs:182:16:182:25 | source(...) | main.rs:147:5:147:10 | Point.y | main.rs:180:16:183:9 | Point {...} | -| main.rs:184:12:184:12 | 4 | main.rs:175:5:175:10 | Point3D.z | main.rs:179:13:185:5 | Point3D {...} | -| main.rs:194:16:194:32 | Point {...} | main.rs:174:5:174:16 | Point3D.plane | main.rs:193:13:196:5 | Point3D {...} | -| main.rs:194:27:194:27 | 2 | main.rs:146:5:146:10 | Point.x | main.rs:194:16:194:32 | Point {...} | -| main.rs:194:30:194:30 | y | main.rs:147:5:147:10 | Point.y | main.rs:194:16:194:32 | Point {...} | -| main.rs:195:12:195:12 | 4 | main.rs:175:5:175:10 | Point3D.z | main.rs:193:13:196:5 | Point3D {...} | -| main.rs:212:27:212:36 | source(...) | main.rs:209:22:209:24 | MyTupleStruct(0) | main.rs:212:13:212:40 | MyTupleStruct(...) | -| main.rs:212:39:212:39 | 2 | main.rs:209:27:209:29 | MyTupleStruct(1) | main.rs:212:13:212:40 | MyTupleStruct(...) | -| main.rs:228:27:228:36 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:228:14:228:37 | ...::Some(...) | -| main.rs:229:27:229:27 | 2 | {EXTERNAL LOCATION} | Some | main.rs:229:14:229:28 | ...::Some(...) | -| main.rs:241:19:241:28 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:241:14:241:29 | Some(...) | -| main.rs:242:19:242:19 | 2 | {EXTERNAL LOCATION} | Some | main.rs:242:14:242:20 | Some(...) | -| main.rs:254:19:254:28 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:254:14:254:29 | Some(...) | +| main.rs:116:11:116:11 | i | file://:0:0:0:0 | &ref | main.rs:116:11:116:11 | receiver for i | +| main.rs:123:14:123:22 | source(...) | file://:0:0:0:0 | tuple.0 | main.rs:123:13:123:26 | TupleExpr | +| main.rs:123:25:123:25 | 2 | file://:0:0:0:0 | tuple.1 | main.rs:123:13:123:26 | TupleExpr | +| main.rs:129:14:129:14 | 2 | file://:0:0:0:0 | tuple.0 | main.rs:129:13:129:30 | TupleExpr | +| main.rs:129:17:129:26 | source(...) | file://:0:0:0:0 | tuple.1 | main.rs:129:13:129:30 | TupleExpr | +| main.rs:129:29:129:29 | 2 | file://:0:0:0:0 | tuple.2 | main.rs:129:13:129:30 | TupleExpr | +| main.rs:137:18:137:18 | 2 | file://:0:0:0:0 | tuple.0 | main.rs:137:17:137:31 | TupleExpr | +| main.rs:137:21:137:30 | source(...) | file://:0:0:0:0 | tuple.1 | main.rs:137:17:137:31 | TupleExpr | +| main.rs:140:11:140:20 | source(...) | file://:0:0:0:0 | tuple.0 | main.rs:140:5:140:5 | [post] a | +| main.rs:141:11:141:11 | 2 | file://:0:0:0:0 | tuple.1 | main.rs:141:5:141:5 | [post] a | +| main.rs:147:14:147:14 | 3 | file://:0:0:0:0 | tuple.0 | main.rs:147:13:147:27 | TupleExpr | +| main.rs:147:17:147:26 | source(...) | file://:0:0:0:0 | tuple.1 | main.rs:147:13:147:27 | TupleExpr | +| main.rs:148:14:148:14 | a | file://:0:0:0:0 | tuple.0 | main.rs:148:13:148:18 | TupleExpr | +| main.rs:148:17:148:17 | 3 | file://:0:0:0:0 | tuple.1 | main.rs:148:13:148:18 | TupleExpr | +| main.rs:163:24:163:32 | source(...) | main.rs:158:5:158:10 | Point.x | main.rs:163:13:163:40 | Point {...} | +| main.rs:163:38:163:38 | 2 | main.rs:159:5:159:10 | Point.y | main.rs:163:13:163:40 | Point {...} | +| main.rs:169:28:169:36 | source(...) | main.rs:158:5:158:10 | Point.x | main.rs:169:17:169:44 | Point {...} | +| main.rs:169:42:169:42 | 2 | main.rs:159:5:159:10 | Point.y | main.rs:169:17:169:44 | Point {...} | +| main.rs:171:11:171:20 | source(...) | main.rs:159:5:159:10 | Point.y | main.rs:171:5:171:5 | [post] p | +| main.rs:177:12:177:21 | source(...) | main.rs:158:5:158:10 | Point.x | main.rs:176:13:179:5 | Point {...} | +| main.rs:178:12:178:12 | 2 | main.rs:159:5:159:10 | Point.y | main.rs:176:13:179:5 | Point {...} | +| main.rs:192:16:195:9 | Point {...} | main.rs:186:5:186:16 | Point3D.plane | main.rs:191:13:197:5 | Point3D {...} | +| main.rs:193:16:193:16 | 2 | main.rs:158:5:158:10 | Point.x | main.rs:192:16:195:9 | Point {...} | +| main.rs:194:16:194:25 | source(...) | main.rs:159:5:159:10 | Point.y | main.rs:192:16:195:9 | Point {...} | +| main.rs:196:12:196:12 | 4 | main.rs:187:5:187:10 | Point3D.z | main.rs:191:13:197:5 | Point3D {...} | +| main.rs:206:16:206:32 | Point {...} | main.rs:186:5:186:16 | Point3D.plane | main.rs:205:13:208:5 | Point3D {...} | +| main.rs:206:27:206:27 | 2 | main.rs:158:5:158:10 | Point.x | main.rs:206:16:206:32 | Point {...} | +| main.rs:206:30:206:30 | y | main.rs:159:5:159:10 | Point.y | main.rs:206:16:206:32 | Point {...} | +| main.rs:207:12:207:12 | 4 | main.rs:187:5:187:10 | Point3D.z | main.rs:205:13:208:5 | Point3D {...} | +| main.rs:224:27:224:36 | source(...) | main.rs:221:22:221:24 | MyTupleStruct(0) | main.rs:224:13:224:40 | MyTupleStruct(...) | +| main.rs:224:39:224:39 | 2 | main.rs:221:27:221:29 | MyTupleStruct(1) | main.rs:224:13:224:40 | MyTupleStruct(...) | +| main.rs:240:27:240:36 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:240:14:240:37 | ...::Some(...) | +| main.rs:241:27:241:27 | 2 | {EXTERNAL LOCATION} | Some | main.rs:241:14:241:28 | ...::Some(...) | +| main.rs:253:19:253:28 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:253:14:253:29 | Some(...) | +| main.rs:254:19:254:19 | 2 | {EXTERNAL LOCATION} | Some | main.rs:254:14:254:20 | Some(...) | | main.rs:266:19:266:28 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:266:14:266:29 | Some(...) | -| main.rs:271:19:271:28 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:271:14:271:29 | Some(...) | -| main.rs:274:19:274:19 | 0 | {EXTERNAL LOCATION} | Some | main.rs:274:14:274:20 | Some(...) | -| main.rs:279:19:279:28 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:279:14:279:29 | Some(...) | -| main.rs:287:19:287:28 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:287:14:287:29 | Some(...) | -| main.rs:288:19:288:19 | 2 | {EXTERNAL LOCATION} | Some | main.rs:288:14:288:20 | Some(...) | -| main.rs:292:10:292:10 | 0 | {EXTERNAL LOCATION} | Some | main.rs:292:5:292:11 | Some(...) | -| main.rs:296:35:296:44 | source(...) | {EXTERNAL LOCATION} | Ok | main.rs:296:32:296:45 | Ok(...) | -| main.rs:302:36:302:45 | source(...) | {EXTERNAL LOCATION} | Err | main.rs:302:32:302:46 | Err(...) | -| main.rs:310:35:310:44 | source(...) | {EXTERNAL LOCATION} | Ok | main.rs:310:32:310:45 | Ok(...) | -| main.rs:311:35:311:35 | 2 | {EXTERNAL LOCATION} | Ok | main.rs:311:32:311:36 | Ok(...) | -| main.rs:312:36:312:45 | source(...) | {EXTERNAL LOCATION} | Err | main.rs:312:32:312:46 | Err(...) | -| main.rs:319:8:319:8 | 0 | {EXTERNAL LOCATION} | Ok | main.rs:319:5:319:9 | Ok(...) | -| main.rs:323:35:323:44 | source(...) | {EXTERNAL LOCATION} | Ok | main.rs:323:32:323:45 | Ok(...) | -| main.rs:327:36:327:45 | source(...) | {EXTERNAL LOCATION} | Err | main.rs:327:32:327:46 | Err(...) | -| main.rs:338:29:338:38 | source(...) | main.rs:333:7:333:9 | A | main.rs:338:14:338:39 | ...::A(...) | -| main.rs:339:29:339:29 | 2 | main.rs:334:7:334:9 | B | main.rs:339:14:339:30 | ...::B(...) | -| main.rs:356:16:356:25 | source(...) | main.rs:333:7:333:9 | A | main.rs:356:14:356:26 | A(...) | -| main.rs:357:16:357:16 | 2 | main.rs:334:7:334:9 | B | main.rs:357:14:357:17 | B(...) | -| main.rs:378:18:378:27 | source(...) | main.rs:372:9:372:20 | C | main.rs:377:14:379:5 | ...::C {...} | -| main.rs:380:41:380:41 | 2 | main.rs:373:9:373:20 | D | main.rs:380:14:380:43 | ...::D {...} | -| main.rs:398:18:398:27 | source(...) | main.rs:372:9:372:20 | C | main.rs:397:14:399:5 | C {...} | -| main.rs:400:27:400:27 | 2 | main.rs:373:9:373:20 | D | main.rs:400:14:400:29 | D {...} | -| main.rs:418:17:418:17 | 1 | file://:0:0:0:0 | element | main.rs:418:16:418:33 | [...] | -| main.rs:418:20:418:20 | 2 | file://:0:0:0:0 | element | main.rs:418:16:418:33 | [...] | -| main.rs:418:23:418:32 | source(...) | file://:0:0:0:0 | element | main.rs:418:16:418:33 | [...] | -| main.rs:422:17:422:26 | source(...) | file://:0:0:0:0 | element | main.rs:422:16:422:31 | [...; 10] | -| main.rs:426:17:426:17 | 1 | file://:0:0:0:0 | element | main.rs:426:16:426:24 | [...] | -| main.rs:426:20:426:20 | 2 | file://:0:0:0:0 | element | main.rs:426:16:426:24 | [...] | -| main.rs:426:23:426:23 | 3 | file://:0:0:0:0 | element | main.rs:426:16:426:24 | [...] | -| main.rs:432:17:432:17 | 1 | file://:0:0:0:0 | element | main.rs:432:16:432:33 | [...] | -| main.rs:432:20:432:20 | 2 | file://:0:0:0:0 | element | main.rs:432:16:432:33 | [...] | -| main.rs:432:23:432:32 | source(...) | file://:0:0:0:0 | element | main.rs:432:16:432:33 | [...] | -| main.rs:437:17:437:17 | 1 | file://:0:0:0:0 | element | main.rs:437:16:437:24 | [...] | -| main.rs:437:20:437:20 | 2 | file://:0:0:0:0 | element | main.rs:437:16:437:24 | [...] | -| main.rs:437:23:437:23 | 3 | file://:0:0:0:0 | element | main.rs:437:16:437:24 | [...] | +| main.rs:278:19:278:28 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:278:14:278:29 | Some(...) | +| main.rs:283:19:283:28 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:283:14:283:29 | Some(...) | +| main.rs:286:19:286:19 | 0 | {EXTERNAL LOCATION} | Some | main.rs:286:14:286:20 | Some(...) | +| main.rs:291:19:291:28 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:291:14:291:29 | Some(...) | +| main.rs:299:19:299:28 | source(...) | {EXTERNAL LOCATION} | Some | main.rs:299:14:299:29 | Some(...) | +| main.rs:300:19:300:19 | 2 | {EXTERNAL LOCATION} | Some | main.rs:300:14:300:20 | Some(...) | +| main.rs:304:10:304:10 | 0 | {EXTERNAL LOCATION} | Some | main.rs:304:5:304:11 | Some(...) | +| main.rs:308:35:308:44 | source(...) | {EXTERNAL LOCATION} | Ok | main.rs:308:32:308:45 | Ok(...) | +| main.rs:314:36:314:45 | source(...) | {EXTERNAL LOCATION} | Err | main.rs:314:32:314:46 | Err(...) | +| main.rs:322:35:322:44 | source(...) | {EXTERNAL LOCATION} | Ok | main.rs:322:32:322:45 | Ok(...) | +| main.rs:323:35:323:35 | 2 | {EXTERNAL LOCATION} | Ok | main.rs:323:32:323:36 | Ok(...) | +| main.rs:324:36:324:45 | source(...) | {EXTERNAL LOCATION} | Err | main.rs:324:32:324:46 | Err(...) | +| main.rs:331:8:331:8 | 0 | {EXTERNAL LOCATION} | Ok | main.rs:331:5:331:9 | Ok(...) | +| main.rs:335:35:335:44 | source(...) | {EXTERNAL LOCATION} | Ok | main.rs:335:32:335:45 | Ok(...) | +| main.rs:339:36:339:45 | source(...) | {EXTERNAL LOCATION} | Err | main.rs:339:32:339:46 | Err(...) | +| main.rs:350:29:350:38 | source(...) | main.rs:345:7:345:9 | A | main.rs:350:14:350:39 | ...::A(...) | +| main.rs:351:29:351:29 | 2 | main.rs:346:7:346:9 | B | main.rs:351:14:351:30 | ...::B(...) | +| main.rs:368:16:368:25 | source(...) | main.rs:345:7:345:9 | A | main.rs:368:14:368:26 | A(...) | +| main.rs:369:16:369:16 | 2 | main.rs:346:7:346:9 | B | main.rs:369:14:369:17 | B(...) | +| main.rs:390:18:390:27 | source(...) | main.rs:384:9:384:20 | C | main.rs:389:14:391:5 | ...::C {...} | +| main.rs:392:41:392:41 | 2 | main.rs:385:9:385:20 | D | main.rs:392:14:392:43 | ...::D {...} | +| main.rs:410:18:410:27 | source(...) | main.rs:384:9:384:20 | C | main.rs:409:14:411:5 | C {...} | +| main.rs:412:27:412:27 | 2 | main.rs:385:9:385:20 | D | main.rs:412:14:412:29 | D {...} | +| main.rs:430:17:430:17 | 1 | file://:0:0:0:0 | element | main.rs:430:16:430:33 | [...] | +| main.rs:430:20:430:20 | 2 | file://:0:0:0:0 | element | main.rs:430:16:430:33 | [...] | +| main.rs:430:23:430:32 | source(...) | file://:0:0:0:0 | element | main.rs:430:16:430:33 | [...] | +| main.rs:434:17:434:26 | source(...) | file://:0:0:0:0 | element | main.rs:434:16:434:31 | [...; 10] | +| main.rs:438:17:438:17 | 1 | file://:0:0:0:0 | element | main.rs:438:16:438:24 | [...] | +| main.rs:438:20:438:20 | 2 | file://:0:0:0:0 | element | main.rs:438:16:438:24 | [...] | +| main.rs:438:23:438:23 | 3 | file://:0:0:0:0 | element | main.rs:438:16:438:24 | [...] | | main.rs:444:17:444:17 | 1 | file://:0:0:0:0 | element | main.rs:444:16:444:33 | [...] | | main.rs:444:20:444:20 | 2 | file://:0:0:0:0 | element | main.rs:444:16:444:33 | [...] | | main.rs:444:23:444:32 | source(...) | file://:0:0:0:0 | element | main.rs:444:16:444:33 | [...] | -| main.rs:455:24:455:24 | 1 | file://:0:0:0:0 | element | main.rs:455:23:455:31 | [...] | -| main.rs:455:27:455:27 | 2 | file://:0:0:0:0 | element | main.rs:455:23:455:31 | [...] | -| main.rs:455:30:455:30 | 3 | file://:0:0:0:0 | element | main.rs:455:23:455:31 | [...] | -| main.rs:458:18:458:27 | source(...) | file://:0:0:0:0 | element | main.rs:458:5:458:11 | [post] mut_arr | -| main.rs:470:41:470:67 | default_name | main.rs:467:9:467:20 | captured default_name | main.rs:470:41:470:67 | \|...\| ... | -| main.rs:471:18:471:18 | n | file://:0:0:0:0 | &ref | main.rs:471:18:471:18 | receiver for n | -| main.rs:495:13:495:13 | b | file://:0:0:0:0 | &ref | main.rs:495:13:495:13 | receiver for b | -| main.rs:496:18:496:18 | b | file://:0:0:0:0 | &ref | main.rs:496:18:496:18 | receiver for b | -| main.rs:505:15:505:24 | source(...) | file://:0:0:0:0 | element | main.rs:505:14:505:34 | [...] | -| main.rs:505:27:505:27 | 2 | file://:0:0:0:0 | element | main.rs:505:14:505:34 | [...] | -| main.rs:505:30:505:30 | 3 | file://:0:0:0:0 | element | main.rs:505:14:505:34 | [...] | -| main.rs:505:33:505:33 | 4 | file://:0:0:0:0 | element | main.rs:505:14:505:34 | [...] | -| main.rs:530:23:530:32 | source(...) | file://:0:0:0:0 | element | main.rs:530:22:530:42 | [...] | -| main.rs:530:35:530:35 | 2 | file://:0:0:0:0 | element | main.rs:530:22:530:42 | [...] | -| main.rs:530:38:530:38 | 3 | file://:0:0:0:0 | element | main.rs:530:22:530:42 | [...] | -| main.rs:530:41:530:41 | 4 | file://:0:0:0:0 | element | main.rs:530:22:530:42 | [...] | -| main.rs:545:18:545:18 | c | file://:0:0:0:0 | &ref | main.rs:545:17:545:18 | &c | -| main.rs:548:15:548:15 | b | file://:0:0:0:0 | &ref | main.rs:548:14:548:15 | &b | -| main.rs:571:27:571:27 | 0 | {EXTERNAL LOCATION} | Some | main.rs:571:22:571:28 | Some(...) | +| main.rs:449:17:449:17 | 1 | file://:0:0:0:0 | element | main.rs:449:16:449:24 | [...] | +| main.rs:449:20:449:20 | 2 | file://:0:0:0:0 | element | main.rs:449:16:449:24 | [...] | +| main.rs:449:23:449:23 | 3 | file://:0:0:0:0 | element | main.rs:449:16:449:24 | [...] | +| main.rs:456:17:456:17 | 1 | file://:0:0:0:0 | element | main.rs:456:16:456:33 | [...] | +| main.rs:456:20:456:20 | 2 | file://:0:0:0:0 | element | main.rs:456:16:456:33 | [...] | +| main.rs:456:23:456:32 | source(...) | file://:0:0:0:0 | element | main.rs:456:16:456:33 | [...] | +| main.rs:467:24:467:24 | 1 | file://:0:0:0:0 | element | main.rs:467:23:467:31 | [...] | +| main.rs:467:27:467:27 | 2 | file://:0:0:0:0 | element | main.rs:467:23:467:31 | [...] | +| main.rs:467:30:467:30 | 3 | file://:0:0:0:0 | element | main.rs:467:23:467:31 | [...] | +| main.rs:470:18:470:27 | source(...) | file://:0:0:0:0 | element | main.rs:470:5:470:11 | [post] mut_arr | +| main.rs:482:41:482:67 | default_name | main.rs:479:9:479:20 | captured default_name | main.rs:482:41:482:67 | \|...\| ... | +| main.rs:483:18:483:18 | n | file://:0:0:0:0 | &ref | main.rs:483:18:483:18 | receiver for n | +| main.rs:507:13:507:13 | b | file://:0:0:0:0 | &ref | main.rs:507:13:507:13 | receiver for b | +| main.rs:508:18:508:18 | b | file://:0:0:0:0 | &ref | main.rs:508:18:508:18 | receiver for b | +| main.rs:517:15:517:24 | source(...) | file://:0:0:0:0 | element | main.rs:517:14:517:34 | [...] | +| main.rs:517:27:517:27 | 2 | file://:0:0:0:0 | element | main.rs:517:14:517:34 | [...] | +| main.rs:517:30:517:30 | 3 | file://:0:0:0:0 | element | main.rs:517:14:517:34 | [...] | +| main.rs:517:33:517:33 | 4 | file://:0:0:0:0 | element | main.rs:517:14:517:34 | [...] | +| main.rs:542:23:542:32 | source(...) | file://:0:0:0:0 | element | main.rs:542:22:542:42 | [...] | +| main.rs:542:35:542:35 | 2 | file://:0:0:0:0 | element | main.rs:542:22:542:42 | [...] | +| main.rs:542:38:542:38 | 3 | file://:0:0:0:0 | element | main.rs:542:22:542:42 | [...] | +| main.rs:542:41:542:41 | 4 | file://:0:0:0:0 | element | main.rs:542:22:542:42 | [...] | +| main.rs:557:18:557:18 | c | file://:0:0:0:0 | &ref | main.rs:557:17:557:18 | &c | +| main.rs:560:15:560:15 | b | file://:0:0:0:0 | &ref | main.rs:560:14:560:15 | &b | +| main.rs:583:27:583:27 | 0 | {EXTERNAL LOCATION} | Some | main.rs:583:22:583:28 | Some(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index 707a63342ba..eafe3a7452e 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -27,225 +27,229 @@ edges | main.rs:62:15:62:23 | source(...) | main.rs:61:9:61:9 | b | provenance | | | main.rs:70:5:70:5 | i | main.rs:71:10:71:10 | i | provenance | | | main.rs:70:9:70:17 | source(...) | main.rs:70:5:70:5 | i | provenance | | -| main.rs:103:9:103:9 | i [&ref] | main.rs:104:11:104:11 | i [&ref] | provenance | | -| main.rs:103:13:103:31 | ...::new(...) [&ref] | main.rs:103:9:103:9 | i [&ref] | provenance | | -| main.rs:103:22:103:30 | source(...) | main.rs:103:13:103:31 | ...::new(...) [&ref] | provenance | MaD:1 | -| main.rs:104:11:104:11 | i [&ref] | main.rs:104:10:104:11 | * ... | provenance | | -| main.rs:111:9:111:9 | a [tuple.0] | main.rs:112:10:112:10 | a [tuple.0] | provenance | | -| main.rs:111:13:111:26 | TupleExpr [tuple.0] | main.rs:111:9:111:9 | a [tuple.0] | provenance | | -| main.rs:111:14:111:22 | source(...) | main.rs:111:13:111:26 | TupleExpr [tuple.0] | provenance | | -| main.rs:112:10:112:10 | a [tuple.0] | main.rs:112:10:112:12 | a.0 | provenance | | -| main.rs:117:9:117:9 | a [tuple.1] | main.rs:118:9:118:20 | TuplePat [tuple.1] | provenance | | -| main.rs:117:13:117:30 | TupleExpr [tuple.1] | main.rs:117:9:117:9 | a [tuple.1] | provenance | | -| main.rs:117:17:117:26 | source(...) | main.rs:117:13:117:30 | TupleExpr [tuple.1] | provenance | | -| main.rs:118:9:118:20 | TuplePat [tuple.1] | main.rs:118:14:118:15 | a1 | provenance | | -| main.rs:118:14:118:15 | a1 | main.rs:120:10:120:11 | a1 | provenance | | -| main.rs:125:9:125:13 | mut a [tuple.1] | main.rs:127:10:127:10 | a [tuple.1] | provenance | | -| main.rs:125:17:125:31 | TupleExpr [tuple.1] | main.rs:125:9:125:13 | mut a [tuple.1] | provenance | | -| main.rs:125:21:125:30 | source(...) | main.rs:125:17:125:31 | TupleExpr [tuple.1] | provenance | | -| main.rs:127:10:127:10 | a [tuple.1] | main.rs:127:10:127:12 | a.1 | provenance | | -| main.rs:128:5:128:5 | [post] a [tuple.0] | main.rs:129:5:129:5 | a [tuple.0] | provenance | | -| main.rs:128:11:128:20 | source(...) | main.rs:128:5:128:5 | [post] a [tuple.0] | provenance | | -| main.rs:129:5:129:5 | a [tuple.0] | main.rs:130:10:130:10 | a [tuple.0] | provenance | | -| main.rs:130:10:130:10 | a [tuple.0] | main.rs:130:10:130:12 | a.0 | provenance | | -| main.rs:135:9:135:9 | a [tuple.1] | main.rs:136:14:136:14 | a [tuple.1] | provenance | | -| main.rs:135:13:135:27 | TupleExpr [tuple.1] | main.rs:135:9:135:9 | a [tuple.1] | provenance | | -| main.rs:135:17:135:26 | source(...) | main.rs:135:13:135:27 | TupleExpr [tuple.1] | provenance | | -| main.rs:136:9:136:9 | b [tuple.0, tuple.1] | main.rs:138:10:138:10 | b [tuple.0, tuple.1] | provenance | | -| main.rs:136:13:136:18 | TupleExpr [tuple.0, tuple.1] | main.rs:136:9:136:9 | b [tuple.0, tuple.1] | provenance | | -| main.rs:136:14:136:14 | a [tuple.1] | main.rs:136:13:136:18 | TupleExpr [tuple.0, tuple.1] | provenance | | -| main.rs:138:10:138:10 | b [tuple.0, tuple.1] | main.rs:138:10:138:12 | b.0 [tuple.1] | provenance | | -| main.rs:138:10:138:12 | b.0 [tuple.1] | main.rs:138:10:138:15 | ... .1 | provenance | | -| main.rs:151:9:151:9 | p [Point.x] | main.rs:152:10:152:10 | p [Point.x] | provenance | | -| main.rs:151:13:151:40 | Point {...} [Point.x] | main.rs:151:9:151:9 | p [Point.x] | provenance | | -| main.rs:151:24:151:32 | source(...) | main.rs:151:13:151:40 | Point {...} [Point.x] | provenance | | -| main.rs:152:10:152:10 | p [Point.x] | main.rs:152:10:152:12 | p.x | provenance | | -| main.rs:159:5:159:5 | [post] p [Point.y] | main.rs:160:10:160:10 | p [Point.y] | provenance | | -| main.rs:159:11:159:20 | source(...) | main.rs:159:5:159:5 | [post] p [Point.y] | provenance | | -| main.rs:160:10:160:10 | p [Point.y] | main.rs:160:10:160:12 | p.y | provenance | | -| main.rs:164:9:164:9 | p [Point.x] | main.rs:168:9:168:28 | Point {...} [Point.x] | provenance | | -| main.rs:164:13:167:5 | Point {...} [Point.x] | main.rs:164:9:164:9 | p [Point.x] | provenance | | -| main.rs:165:12:165:21 | source(...) | main.rs:164:13:167:5 | Point {...} [Point.x] | provenance | | -| main.rs:168:9:168:28 | Point {...} [Point.x] | main.rs:168:20:168:20 | a | provenance | | -| main.rs:168:20:168:20 | a | main.rs:169:10:169:10 | a | provenance | | -| main.rs:179:9:179:9 | p [Point3D.plane, Point.y] | main.rs:187:10:187:10 | p [Point3D.plane, Point.y] | provenance | | -| main.rs:179:13:185:5 | Point3D {...} [Point3D.plane, Point.y] | main.rs:179:9:179:9 | p [Point3D.plane, Point.y] | provenance | | -| main.rs:180:16:183:9 | Point {...} [Point.y] | main.rs:179:13:185:5 | Point3D {...} [Point3D.plane, Point.y] | provenance | | -| main.rs:182:16:182:25 | source(...) | main.rs:180:16:183:9 | Point {...} [Point.y] | provenance | | -| main.rs:187:10:187:10 | p [Point3D.plane, Point.y] | main.rs:187:10:187:16 | p.plane [Point.y] | provenance | | -| main.rs:187:10:187:16 | p.plane [Point.y] | main.rs:187:10:187:18 | ... .y | provenance | | -| main.rs:192:9:192:9 | y | main.rs:194:30:194:30 | y | provenance | | -| main.rs:192:13:192:22 | source(...) | main.rs:192:9:192:9 | y | provenance | | -| main.rs:193:9:193:9 | p [Point3D.plane, Point.y] | main.rs:197:11:197:11 | p [Point3D.plane, Point.y] | provenance | | -| main.rs:193:13:196:5 | Point3D {...} [Point3D.plane, Point.y] | main.rs:193:9:193:9 | p [Point3D.plane, Point.y] | provenance | | -| main.rs:194:16:194:32 | Point {...} [Point.y] | main.rs:193:13:196:5 | Point3D {...} [Point3D.plane, Point.y] | provenance | | -| main.rs:194:30:194:30 | y | main.rs:194:16:194:32 | Point {...} [Point.y] | provenance | | -| main.rs:197:11:197:11 | p [Point3D.plane, Point.y] | main.rs:198:9:201:9 | Point3D {...} [Point3D.plane, Point.y] | provenance | | -| main.rs:198:9:201:9 | Point3D {...} [Point3D.plane, Point.y] | main.rs:199:20:199:33 | Point {...} [Point.y] | provenance | | -| main.rs:199:20:199:33 | Point {...} [Point.y] | main.rs:199:31:199:31 | y | provenance | | -| main.rs:199:31:199:31 | y | main.rs:203:18:203:18 | y | provenance | | -| main.rs:212:9:212:9 | s [MyTupleStruct(0)] | main.rs:213:10:213:10 | s [MyTupleStruct(0)] | provenance | | -| main.rs:212:9:212:9 | s [MyTupleStruct(0)] | main.rs:216:11:216:11 | s [MyTupleStruct(0)] | provenance | | -| main.rs:212:13:212:40 | MyTupleStruct(...) [MyTupleStruct(0)] | main.rs:212:9:212:9 | s [MyTupleStruct(0)] | provenance | | -| main.rs:212:27:212:36 | source(...) | main.rs:212:13:212:40 | MyTupleStruct(...) [MyTupleStruct(0)] | provenance | | -| main.rs:213:10:213:10 | s [MyTupleStruct(0)] | main.rs:213:10:213:12 | s.0 | provenance | | -| main.rs:216:11:216:11 | s [MyTupleStruct(0)] | main.rs:217:9:217:27 | MyTupleStruct(...) [MyTupleStruct(0)] | provenance | | -| main.rs:217:9:217:27 | MyTupleStruct(...) [MyTupleStruct(0)] | main.rs:217:23:217:23 | x | provenance | | -| main.rs:217:23:217:23 | x | main.rs:218:18:218:18 | x | provenance | | -| main.rs:228:9:228:10 | s1 [Some] | main.rs:230:11:230:12 | s1 [Some] | provenance | | -| main.rs:228:14:228:37 | ...::Some(...) [Some] | main.rs:228:9:228:10 | s1 [Some] | provenance | | -| main.rs:228:27:228:36 | source(...) | main.rs:228:14:228:37 | ...::Some(...) [Some] | provenance | | -| main.rs:230:11:230:12 | s1 [Some] | main.rs:231:9:231:23 | ...::Some(...) [Some] | provenance | | -| main.rs:231:9:231:23 | ...::Some(...) [Some] | main.rs:231:22:231:22 | n | provenance | | -| main.rs:231:22:231:22 | n | main.rs:231:33:231:33 | n | provenance | | -| main.rs:241:9:241:10 | s1 [Some] | main.rs:243:11:243:12 | s1 [Some] | provenance | | -| main.rs:241:14:241:29 | Some(...) [Some] | main.rs:241:9:241:10 | s1 [Some] | provenance | | -| main.rs:241:19:241:28 | source(...) | main.rs:241:14:241:29 | Some(...) [Some] | provenance | | -| main.rs:243:11:243:12 | s1 [Some] | main.rs:244:9:244:15 | Some(...) [Some] | provenance | | -| main.rs:244:9:244:15 | Some(...) [Some] | main.rs:244:14:244:14 | n | provenance | | -| main.rs:244:14:244:14 | n | main.rs:244:25:244:25 | n | provenance | | -| main.rs:254:9:254:10 | s1 [Some] | main.rs:255:12:255:18 | Some(...) [Some] | provenance | | -| main.rs:254:14:254:29 | Some(...) [Some] | main.rs:254:9:254:10 | s1 [Some] | provenance | | -| main.rs:254:19:254:28 | source(...) | main.rs:254:14:254:29 | Some(...) [Some] | provenance | | -| main.rs:255:12:255:18 | Some(...) [Some] | main.rs:255:17:255:17 | n | provenance | | -| main.rs:255:17:255:17 | n | main.rs:257:18:257:18 | n | provenance | | -| main.rs:255:17:255:17 | n | main.rs:261:14:261:14 | n | provenance | | -| main.rs:266:9:266:10 | s1 [Some] | main.rs:267:10:267:20 | s1.unwrap() | provenance | MaD:2 | +| main.rs:76:9:76:9 | k | main.rs:77:5:77:5 | j | provenance | | +| main.rs:76:9:76:9 | k | main.rs:79:10:79:10 | k | provenance | | +| main.rs:76:13:76:21 | source(...) | main.rs:76:9:76:9 | k | provenance | | +| main.rs:77:5:77:5 | j | main.rs:78:10:78:10 | j | provenance | | +| main.rs:115:9:115:9 | i [&ref] | main.rs:116:11:116:11 | i [&ref] | provenance | | +| main.rs:115:13:115:31 | ...::new(...) [&ref] | main.rs:115:9:115:9 | i [&ref] | provenance | | +| main.rs:115:22:115:30 | source(...) | main.rs:115:13:115:31 | ...::new(...) [&ref] | provenance | MaD:1 | +| main.rs:116:11:116:11 | i [&ref] | main.rs:116:10:116:11 | * ... | provenance | | +| main.rs:123:9:123:9 | a [tuple.0] | main.rs:124:10:124:10 | a [tuple.0] | provenance | | +| main.rs:123:13:123:26 | TupleExpr [tuple.0] | main.rs:123:9:123:9 | a [tuple.0] | provenance | | +| main.rs:123:14:123:22 | source(...) | main.rs:123:13:123:26 | TupleExpr [tuple.0] | provenance | | +| main.rs:124:10:124:10 | a [tuple.0] | main.rs:124:10:124:12 | a.0 | provenance | | +| main.rs:129:9:129:9 | a [tuple.1] | main.rs:130:9:130:20 | TuplePat [tuple.1] | provenance | | +| main.rs:129:13:129:30 | TupleExpr [tuple.1] | main.rs:129:9:129:9 | a [tuple.1] | provenance | | +| main.rs:129:17:129:26 | source(...) | main.rs:129:13:129:30 | TupleExpr [tuple.1] | provenance | | +| main.rs:130:9:130:20 | TuplePat [tuple.1] | main.rs:130:14:130:15 | a1 | provenance | | +| main.rs:130:14:130:15 | a1 | main.rs:132:10:132:11 | a1 | provenance | | +| main.rs:137:9:137:13 | mut a [tuple.1] | main.rs:139:10:139:10 | a [tuple.1] | provenance | | +| main.rs:137:17:137:31 | TupleExpr [tuple.1] | main.rs:137:9:137:13 | mut a [tuple.1] | provenance | | +| main.rs:137:21:137:30 | source(...) | main.rs:137:17:137:31 | TupleExpr [tuple.1] | provenance | | +| main.rs:139:10:139:10 | a [tuple.1] | main.rs:139:10:139:12 | a.1 | provenance | | +| main.rs:140:5:140:5 | [post] a [tuple.0] | main.rs:141:5:141:5 | a [tuple.0] | provenance | | +| main.rs:140:11:140:20 | source(...) | main.rs:140:5:140:5 | [post] a [tuple.0] | provenance | | +| main.rs:141:5:141:5 | a [tuple.0] | main.rs:142:10:142:10 | a [tuple.0] | provenance | | +| main.rs:142:10:142:10 | a [tuple.0] | main.rs:142:10:142:12 | a.0 | provenance | | +| main.rs:147:9:147:9 | a [tuple.1] | main.rs:148:14:148:14 | a [tuple.1] | provenance | | +| main.rs:147:13:147:27 | TupleExpr [tuple.1] | main.rs:147:9:147:9 | a [tuple.1] | provenance | | +| main.rs:147:17:147:26 | source(...) | main.rs:147:13:147:27 | TupleExpr [tuple.1] | provenance | | +| main.rs:148:9:148:9 | b [tuple.0, tuple.1] | main.rs:150:10:150:10 | b [tuple.0, tuple.1] | provenance | | +| main.rs:148:13:148:18 | TupleExpr [tuple.0, tuple.1] | main.rs:148:9:148:9 | b [tuple.0, tuple.1] | provenance | | +| main.rs:148:14:148:14 | a [tuple.1] | main.rs:148:13:148:18 | TupleExpr [tuple.0, tuple.1] | provenance | | +| main.rs:150:10:150:10 | b [tuple.0, tuple.1] | main.rs:150:10:150:12 | b.0 [tuple.1] | provenance | | +| main.rs:150:10:150:12 | b.0 [tuple.1] | main.rs:150:10:150:15 | ... .1 | provenance | | +| main.rs:163:9:163:9 | p [Point.x] | main.rs:164:10:164:10 | p [Point.x] | provenance | | +| main.rs:163:13:163:40 | Point {...} [Point.x] | main.rs:163:9:163:9 | p [Point.x] | provenance | | +| main.rs:163:24:163:32 | source(...) | main.rs:163:13:163:40 | Point {...} [Point.x] | provenance | | +| main.rs:164:10:164:10 | p [Point.x] | main.rs:164:10:164:12 | p.x | provenance | | +| main.rs:171:5:171:5 | [post] p [Point.y] | main.rs:172:10:172:10 | p [Point.y] | provenance | | +| main.rs:171:11:171:20 | source(...) | main.rs:171:5:171:5 | [post] p [Point.y] | provenance | | +| main.rs:172:10:172:10 | p [Point.y] | main.rs:172:10:172:12 | p.y | provenance | | +| main.rs:176:9:176:9 | p [Point.x] | main.rs:180:9:180:28 | Point {...} [Point.x] | provenance | | +| main.rs:176:13:179:5 | Point {...} [Point.x] | main.rs:176:9:176:9 | p [Point.x] | provenance | | +| main.rs:177:12:177:21 | source(...) | main.rs:176:13:179:5 | Point {...} [Point.x] | provenance | | +| main.rs:180:9:180:28 | Point {...} [Point.x] | main.rs:180:20:180:20 | a | provenance | | +| main.rs:180:20:180:20 | a | main.rs:181:10:181:10 | a | provenance | | +| main.rs:191:9:191:9 | p [Point3D.plane, Point.y] | main.rs:199:10:199:10 | p [Point3D.plane, Point.y] | provenance | | +| main.rs:191:13:197:5 | Point3D {...} [Point3D.plane, Point.y] | main.rs:191:9:191:9 | p [Point3D.plane, Point.y] | provenance | | +| main.rs:192:16:195:9 | Point {...} [Point.y] | main.rs:191:13:197:5 | Point3D {...} [Point3D.plane, Point.y] | provenance | | +| main.rs:194:16:194:25 | source(...) | main.rs:192:16:195:9 | Point {...} [Point.y] | provenance | | +| main.rs:199:10:199:10 | p [Point3D.plane, Point.y] | main.rs:199:10:199:16 | p.plane [Point.y] | provenance | | +| main.rs:199:10:199:16 | p.plane [Point.y] | main.rs:199:10:199:18 | ... .y | provenance | | +| main.rs:204:9:204:9 | y | main.rs:206:30:206:30 | y | provenance | | +| main.rs:204:13:204:22 | source(...) | main.rs:204:9:204:9 | y | provenance | | +| main.rs:205:9:205:9 | p [Point3D.plane, Point.y] | main.rs:209:11:209:11 | p [Point3D.plane, Point.y] | provenance | | +| main.rs:205:13:208:5 | Point3D {...} [Point3D.plane, Point.y] | main.rs:205:9:205:9 | p [Point3D.plane, Point.y] | provenance | | +| main.rs:206:16:206:32 | Point {...} [Point.y] | main.rs:205:13:208:5 | Point3D {...} [Point3D.plane, Point.y] | provenance | | +| main.rs:206:30:206:30 | y | main.rs:206:16:206:32 | Point {...} [Point.y] | provenance | | +| main.rs:209:11:209:11 | p [Point3D.plane, Point.y] | main.rs:210:9:213:9 | Point3D {...} [Point3D.plane, Point.y] | provenance | | +| main.rs:210:9:213:9 | Point3D {...} [Point3D.plane, Point.y] | main.rs:211:20:211:33 | Point {...} [Point.y] | provenance | | +| main.rs:211:20:211:33 | Point {...} [Point.y] | main.rs:211:31:211:31 | y | provenance | | +| main.rs:211:31:211:31 | y | main.rs:215:18:215:18 | y | provenance | | +| main.rs:224:9:224:9 | s [MyTupleStruct(0)] | main.rs:225:10:225:10 | s [MyTupleStruct(0)] | provenance | | +| main.rs:224:9:224:9 | s [MyTupleStruct(0)] | main.rs:228:11:228:11 | s [MyTupleStruct(0)] | provenance | | +| main.rs:224:13:224:40 | MyTupleStruct(...) [MyTupleStruct(0)] | main.rs:224:9:224:9 | s [MyTupleStruct(0)] | provenance | | +| main.rs:224:27:224:36 | source(...) | main.rs:224:13:224:40 | MyTupleStruct(...) [MyTupleStruct(0)] | provenance | | +| main.rs:225:10:225:10 | s [MyTupleStruct(0)] | main.rs:225:10:225:12 | s.0 | provenance | | +| main.rs:228:11:228:11 | s [MyTupleStruct(0)] | main.rs:229:9:229:27 | MyTupleStruct(...) [MyTupleStruct(0)] | provenance | | +| main.rs:229:9:229:27 | MyTupleStruct(...) [MyTupleStruct(0)] | main.rs:229:23:229:23 | x | provenance | | +| main.rs:229:23:229:23 | x | main.rs:230:18:230:18 | x | provenance | | +| main.rs:240:9:240:10 | s1 [Some] | main.rs:242:11:242:12 | s1 [Some] | provenance | | +| main.rs:240:14:240:37 | ...::Some(...) [Some] | main.rs:240:9:240:10 | s1 [Some] | provenance | | +| main.rs:240:27:240:36 | source(...) | main.rs:240:14:240:37 | ...::Some(...) [Some] | provenance | | +| main.rs:242:11:242:12 | s1 [Some] | main.rs:243:9:243:23 | ...::Some(...) [Some] | provenance | | +| main.rs:243:9:243:23 | ...::Some(...) [Some] | main.rs:243:22:243:22 | n | provenance | | +| main.rs:243:22:243:22 | n | main.rs:243:33:243:33 | n | provenance | | +| main.rs:253:9:253:10 | s1 [Some] | main.rs:255:11:255:12 | s1 [Some] | provenance | | +| main.rs:253:14:253:29 | Some(...) [Some] | main.rs:253:9:253:10 | s1 [Some] | provenance | | +| main.rs:253:19:253:28 | source(...) | main.rs:253:14:253:29 | Some(...) [Some] | provenance | | +| main.rs:255:11:255:12 | s1 [Some] | main.rs:256:9:256:15 | Some(...) [Some] | provenance | | +| main.rs:256:9:256:15 | Some(...) [Some] | main.rs:256:14:256:14 | n | provenance | | +| main.rs:256:14:256:14 | n | main.rs:256:25:256:25 | n | provenance | | +| main.rs:266:9:266:10 | s1 [Some] | main.rs:267:12:267:18 | Some(...) [Some] | provenance | | | main.rs:266:14:266:29 | Some(...) [Some] | main.rs:266:9:266:10 | s1 [Some] | provenance | | | main.rs:266:19:266:28 | source(...) | main.rs:266:14:266:29 | Some(...) [Some] | provenance | | -| main.rs:271:9:271:10 | s1 [Some] | main.rs:272:10:272:24 | s1.unwrap_or(...) | provenance | MaD:4 | -| main.rs:271:14:271:29 | Some(...) [Some] | main.rs:271:9:271:10 | s1 [Some] | provenance | | -| main.rs:271:19:271:28 | source(...) | main.rs:271:14:271:29 | Some(...) [Some] | provenance | | -| main.rs:275:23:275:32 | source(...) | main.rs:275:10:275:33 | s2.unwrap_or(...) | provenance | MaD:3 | -| main.rs:279:9:279:10 | s1 [Some] | main.rs:280:10:280:32 | s1.unwrap_or_else(...) | provenance | MaD:6 | -| main.rs:279:14:279:29 | Some(...) [Some] | main.rs:279:9:279:10 | s1 [Some] | provenance | | -| main.rs:279:19:279:28 | source(...) | main.rs:279:14:279:29 | Some(...) [Some] | provenance | | -| main.rs:283:31:283:40 | source(...) | main.rs:283:10:283:41 | s2.unwrap_or_else(...) | provenance | MaD:5 | -| main.rs:287:9:287:10 | s1 [Some] | main.rs:289:14:289:15 | s1 [Some] | provenance | | -| main.rs:287:14:287:29 | Some(...) [Some] | main.rs:287:9:287:10 | s1 [Some] | provenance | | -| main.rs:287:19:287:28 | source(...) | main.rs:287:14:287:29 | Some(...) [Some] | provenance | | -| main.rs:289:9:289:10 | i1 | main.rs:290:10:290:11 | i1 | provenance | | -| main.rs:289:14:289:15 | s1 [Some] | main.rs:289:14:289:16 | TryExpr | provenance | | -| main.rs:289:14:289:16 | TryExpr | main.rs:289:9:289:10 | i1 | provenance | | -| main.rs:296:9:296:10 | r1 [Ok] | main.rs:297:28:297:34 | r1.ok() [Some] | provenance | MaD:10 | -| main.rs:296:32:296:45 | Ok(...) [Ok] | main.rs:296:9:296:10 | r1 [Ok] | provenance | | -| main.rs:296:35:296:44 | source(...) | main.rs:296:32:296:45 | Ok(...) [Ok] | provenance | | -| main.rs:297:9:297:11 | o1a [Some] | main.rs:299:10:299:21 | o1a.unwrap() | provenance | MaD:2 | -| main.rs:297:28:297:34 | r1.ok() [Some] | main.rs:297:9:297:11 | o1a [Some] | provenance | | -| main.rs:302:9:302:10 | r2 [Err] | main.rs:304:28:304:35 | r2.err() [Some] | provenance | MaD:7 | -| main.rs:302:32:302:46 | Err(...) [Err] | main.rs:302:9:302:10 | r2 [Err] | provenance | | -| main.rs:302:36:302:45 | source(...) | main.rs:302:32:302:46 | Err(...) [Err] | provenance | | -| main.rs:304:9:304:11 | o2b [Some] | main.rs:306:10:306:21 | o2b.unwrap() | provenance | MaD:2 | -| main.rs:304:28:304:35 | r2.err() [Some] | main.rs:304:9:304:11 | o2b [Some] | provenance | | -| main.rs:310:9:310:10 | s1 [Ok] | main.rs:313:14:313:15 | s1 [Ok] | provenance | | -| main.rs:310:32:310:45 | Ok(...) [Ok] | main.rs:310:9:310:10 | s1 [Ok] | provenance | | -| main.rs:310:35:310:44 | source(...) | main.rs:310:32:310:45 | Ok(...) [Ok] | provenance | | -| main.rs:313:9:313:10 | i1 | main.rs:315:10:315:11 | i1 | provenance | | -| main.rs:313:14:313:15 | s1 [Ok] | main.rs:313:14:313:16 | TryExpr | provenance | | -| main.rs:313:14:313:16 | TryExpr | main.rs:313:9:313:10 | i1 | provenance | | -| main.rs:323:9:323:10 | s1 [Ok] | main.rs:324:10:324:22 | s1.expect(...) | provenance | MaD:8 | -| main.rs:323:32:323:45 | Ok(...) [Ok] | main.rs:323:9:323:10 | s1 [Ok] | provenance | | -| main.rs:323:35:323:44 | source(...) | main.rs:323:32:323:45 | Ok(...) [Ok] | provenance | | -| main.rs:327:9:327:10 | s2 [Err] | main.rs:329:10:329:26 | s2.expect_err(...) | provenance | MaD:9 | -| main.rs:327:32:327:46 | Err(...) [Err] | main.rs:327:9:327:10 | s2 [Err] | provenance | | -| main.rs:327:36:327:45 | source(...) | main.rs:327:32:327:46 | Err(...) [Err] | provenance | | -| main.rs:338:9:338:10 | s1 [A] | main.rs:340:11:340:12 | s1 [A] | provenance | | -| main.rs:338:14:338:39 | ...::A(...) [A] | main.rs:338:9:338:10 | s1 [A] | provenance | | -| main.rs:338:29:338:38 | source(...) | main.rs:338:14:338:39 | ...::A(...) [A] | provenance | | -| main.rs:340:11:340:12 | s1 [A] | main.rs:341:9:341:25 | ...::A(...) [A] | provenance | | -| main.rs:340:11:340:12 | s1 [A] | main.rs:344:11:344:12 | s1 [A] | provenance | | -| main.rs:341:9:341:25 | ...::A(...) [A] | main.rs:341:24:341:24 | n | provenance | | -| main.rs:341:24:341:24 | n | main.rs:341:35:341:35 | n | provenance | | -| main.rs:344:11:344:12 | s1 [A] | main.rs:345:9:345:25 | ...::A(...) [A] | provenance | | -| main.rs:345:9:345:25 | ...::A(...) [A] | main.rs:345:24:345:24 | n | provenance | | -| main.rs:345:24:345:24 | n | main.rs:345:55:345:55 | n | provenance | | -| main.rs:356:9:356:10 | s1 [A] | main.rs:358:11:358:12 | s1 [A] | provenance | | -| main.rs:356:14:356:26 | A(...) [A] | main.rs:356:9:356:10 | s1 [A] | provenance | | -| main.rs:356:16:356:25 | source(...) | main.rs:356:14:356:26 | A(...) [A] | provenance | | -| main.rs:358:11:358:12 | s1 [A] | main.rs:359:9:359:12 | A(...) [A] | provenance | | -| main.rs:358:11:358:12 | s1 [A] | main.rs:362:11:362:12 | s1 [A] | provenance | | -| main.rs:359:9:359:12 | A(...) [A] | main.rs:359:11:359:11 | n | provenance | | -| main.rs:359:11:359:11 | n | main.rs:359:22:359:22 | n | provenance | | -| main.rs:362:11:362:12 | s1 [A] | main.rs:363:9:363:12 | A(...) [A] | provenance | | -| main.rs:363:9:363:12 | A(...) [A] | main.rs:363:11:363:11 | n | provenance | | -| main.rs:363:11:363:11 | n | main.rs:363:29:363:29 | n | provenance | | -| main.rs:377:9:377:10 | s1 [C] | main.rs:381:11:381:12 | s1 [C] | provenance | | -| main.rs:377:14:379:5 | ...::C {...} [C] | main.rs:377:9:377:10 | s1 [C] | provenance | | -| main.rs:378:18:378:27 | source(...) | main.rs:377:14:379:5 | ...::C {...} [C] | provenance | | -| main.rs:381:11:381:12 | s1 [C] | main.rs:382:9:382:38 | ...::C {...} [C] | provenance | | -| main.rs:381:11:381:12 | s1 [C] | main.rs:385:11:385:12 | s1 [C] | provenance | | -| main.rs:382:9:382:38 | ...::C {...} [C] | main.rs:382:36:382:36 | n | provenance | | -| main.rs:382:36:382:36 | n | main.rs:382:48:382:48 | n | provenance | | -| main.rs:385:11:385:12 | s1 [C] | main.rs:386:9:386:38 | ...::C {...} [C] | provenance | | -| main.rs:386:9:386:38 | ...::C {...} [C] | main.rs:386:36:386:36 | n | provenance | | -| main.rs:386:36:386:36 | n | main.rs:386:81:386:81 | n | provenance | | -| main.rs:397:9:397:10 | s1 [C] | main.rs:401:11:401:12 | s1 [C] | provenance | | -| main.rs:397:14:399:5 | C {...} [C] | main.rs:397:9:397:10 | s1 [C] | provenance | | -| main.rs:398:18:398:27 | source(...) | main.rs:397:14:399:5 | C {...} [C] | provenance | | -| main.rs:401:11:401:12 | s1 [C] | main.rs:402:9:402:24 | C {...} [C] | provenance | | -| main.rs:401:11:401:12 | s1 [C] | main.rs:405:11:405:12 | s1 [C] | provenance | | -| main.rs:402:9:402:24 | C {...} [C] | main.rs:402:22:402:22 | n | provenance | | -| main.rs:402:22:402:22 | n | main.rs:402:34:402:34 | n | provenance | | -| main.rs:405:11:405:12 | s1 [C] | main.rs:406:9:406:24 | C {...} [C] | provenance | | -| main.rs:406:9:406:24 | C {...} [C] | main.rs:406:22:406:22 | n | provenance | | -| main.rs:406:22:406:22 | n | main.rs:406:53:406:53 | n | provenance | | -| main.rs:418:9:418:12 | arr1 [element] | main.rs:419:14:419:17 | arr1 [element] | provenance | | -| main.rs:418:16:418:33 | [...] [element] | main.rs:418:9:418:12 | arr1 [element] | provenance | | -| main.rs:418:23:418:32 | source(...) | main.rs:418:16:418:33 | [...] [element] | provenance | | -| main.rs:419:9:419:10 | n1 | main.rs:420:10:420:11 | n1 | provenance | | -| main.rs:419:14:419:17 | arr1 [element] | main.rs:419:14:419:20 | arr1[2] | provenance | | -| main.rs:419:14:419:20 | arr1[2] | main.rs:419:9:419:10 | n1 | provenance | | -| main.rs:422:9:422:12 | arr2 [element] | main.rs:423:14:423:17 | arr2 [element] | provenance | | -| main.rs:422:16:422:31 | [...; 10] [element] | main.rs:422:9:422:12 | arr2 [element] | provenance | | -| main.rs:422:17:422:26 | source(...) | main.rs:422:16:422:31 | [...; 10] [element] | provenance | | -| main.rs:423:9:423:10 | n2 | main.rs:424:10:424:11 | n2 | provenance | | -| main.rs:423:14:423:17 | arr2 [element] | main.rs:423:14:423:20 | arr2[4] | provenance | | -| main.rs:423:14:423:20 | arr2[4] | main.rs:423:9:423:10 | n2 | provenance | | -| main.rs:432:9:432:12 | arr1 [element] | main.rs:433:15:433:18 | arr1 [element] | provenance | | -| main.rs:432:16:432:33 | [...] [element] | main.rs:432:9:432:12 | arr1 [element] | provenance | | -| main.rs:432:23:432:32 | source(...) | main.rs:432:16:432:33 | [...] [element] | provenance | | -| main.rs:433:9:433:10 | n1 | main.rs:434:14:434:15 | n1 | provenance | | -| main.rs:433:15:433:18 | arr1 [element] | main.rs:433:9:433:10 | n1 | provenance | | -| main.rs:444:9:444:12 | arr1 [element] | main.rs:445:11:445:14 | arr1 [element] | provenance | | +| main.rs:267:12:267:18 | Some(...) [Some] | main.rs:267:17:267:17 | n | provenance | | +| main.rs:267:17:267:17 | n | main.rs:269:18:269:18 | n | provenance | | +| main.rs:267:17:267:17 | n | main.rs:273:14:273:14 | n | provenance | | +| main.rs:278:9:278:10 | s1 [Some] | main.rs:279:10:279:20 | s1.unwrap() | provenance | MaD:2 | +| main.rs:278:14:278:29 | Some(...) [Some] | main.rs:278:9:278:10 | s1 [Some] | provenance | | +| main.rs:278:19:278:28 | source(...) | main.rs:278:14:278:29 | Some(...) [Some] | provenance | | +| main.rs:283:9:283:10 | s1 [Some] | main.rs:284:10:284:24 | s1.unwrap_or(...) | provenance | MaD:4 | +| main.rs:283:14:283:29 | Some(...) [Some] | main.rs:283:9:283:10 | s1 [Some] | provenance | | +| main.rs:283:19:283:28 | source(...) | main.rs:283:14:283:29 | Some(...) [Some] | provenance | | +| main.rs:287:23:287:32 | source(...) | main.rs:287:10:287:33 | s2.unwrap_or(...) | provenance | MaD:3 | +| main.rs:291:9:291:10 | s1 [Some] | main.rs:292:10:292:32 | s1.unwrap_or_else(...) | provenance | MaD:6 | +| main.rs:291:14:291:29 | Some(...) [Some] | main.rs:291:9:291:10 | s1 [Some] | provenance | | +| main.rs:291:19:291:28 | source(...) | main.rs:291:14:291:29 | Some(...) [Some] | provenance | | +| main.rs:295:31:295:40 | source(...) | main.rs:295:10:295:41 | s2.unwrap_or_else(...) | provenance | MaD:5 | +| main.rs:299:9:299:10 | s1 [Some] | main.rs:301:14:301:15 | s1 [Some] | provenance | | +| main.rs:299:14:299:29 | Some(...) [Some] | main.rs:299:9:299:10 | s1 [Some] | provenance | | +| main.rs:299:19:299:28 | source(...) | main.rs:299:14:299:29 | Some(...) [Some] | provenance | | +| main.rs:301:9:301:10 | i1 | main.rs:302:10:302:11 | i1 | provenance | | +| main.rs:301:14:301:15 | s1 [Some] | main.rs:301:14:301:16 | TryExpr | provenance | | +| main.rs:301:14:301:16 | TryExpr | main.rs:301:9:301:10 | i1 | provenance | | +| main.rs:308:9:308:10 | r1 [Ok] | main.rs:309:28:309:34 | r1.ok() [Some] | provenance | MaD:10 | +| main.rs:308:32:308:45 | Ok(...) [Ok] | main.rs:308:9:308:10 | r1 [Ok] | provenance | | +| main.rs:308:35:308:44 | source(...) | main.rs:308:32:308:45 | Ok(...) [Ok] | provenance | | +| main.rs:309:9:309:11 | o1a [Some] | main.rs:311:10:311:21 | o1a.unwrap() | provenance | MaD:2 | +| main.rs:309:28:309:34 | r1.ok() [Some] | main.rs:309:9:309:11 | o1a [Some] | provenance | | +| main.rs:314:9:314:10 | r2 [Err] | main.rs:316:28:316:35 | r2.err() [Some] | provenance | MaD:7 | +| main.rs:314:32:314:46 | Err(...) [Err] | main.rs:314:9:314:10 | r2 [Err] | provenance | | +| main.rs:314:36:314:45 | source(...) | main.rs:314:32:314:46 | Err(...) [Err] | provenance | | +| main.rs:316:9:316:11 | o2b [Some] | main.rs:318:10:318:21 | o2b.unwrap() | provenance | MaD:2 | +| main.rs:316:28:316:35 | r2.err() [Some] | main.rs:316:9:316:11 | o2b [Some] | provenance | | +| main.rs:322:9:322:10 | s1 [Ok] | main.rs:325:14:325:15 | s1 [Ok] | provenance | | +| main.rs:322:32:322:45 | Ok(...) [Ok] | main.rs:322:9:322:10 | s1 [Ok] | provenance | | +| main.rs:322:35:322:44 | source(...) | main.rs:322:32:322:45 | Ok(...) [Ok] | provenance | | +| main.rs:325:9:325:10 | i1 | main.rs:327:10:327:11 | i1 | provenance | | +| main.rs:325:14:325:15 | s1 [Ok] | main.rs:325:14:325:16 | TryExpr | provenance | | +| main.rs:325:14:325:16 | TryExpr | main.rs:325:9:325:10 | i1 | provenance | | +| main.rs:335:9:335:10 | s1 [Ok] | main.rs:336:10:336:22 | s1.expect(...) | provenance | MaD:8 | +| main.rs:335:32:335:45 | Ok(...) [Ok] | main.rs:335:9:335:10 | s1 [Ok] | provenance | | +| main.rs:335:35:335:44 | source(...) | main.rs:335:32:335:45 | Ok(...) [Ok] | provenance | | +| main.rs:339:9:339:10 | s2 [Err] | main.rs:341:10:341:26 | s2.expect_err(...) | provenance | MaD:9 | +| main.rs:339:32:339:46 | Err(...) [Err] | main.rs:339:9:339:10 | s2 [Err] | provenance | | +| main.rs:339:36:339:45 | source(...) | main.rs:339:32:339:46 | Err(...) [Err] | provenance | | +| main.rs:350:9:350:10 | s1 [A] | main.rs:352:11:352:12 | s1 [A] | provenance | | +| main.rs:350:14:350:39 | ...::A(...) [A] | main.rs:350:9:350:10 | s1 [A] | provenance | | +| main.rs:350:29:350:38 | source(...) | main.rs:350:14:350:39 | ...::A(...) [A] | provenance | | +| main.rs:352:11:352:12 | s1 [A] | main.rs:353:9:353:25 | ...::A(...) [A] | provenance | | +| main.rs:352:11:352:12 | s1 [A] | main.rs:356:11:356:12 | s1 [A] | provenance | | +| main.rs:353:9:353:25 | ...::A(...) [A] | main.rs:353:24:353:24 | n | provenance | | +| main.rs:353:24:353:24 | n | main.rs:353:35:353:35 | n | provenance | | +| main.rs:356:11:356:12 | s1 [A] | main.rs:357:9:357:25 | ...::A(...) [A] | provenance | | +| main.rs:357:9:357:25 | ...::A(...) [A] | main.rs:357:24:357:24 | n | provenance | | +| main.rs:357:24:357:24 | n | main.rs:357:55:357:55 | n | provenance | | +| main.rs:368:9:368:10 | s1 [A] | main.rs:370:11:370:12 | s1 [A] | provenance | | +| main.rs:368:14:368:26 | A(...) [A] | main.rs:368:9:368:10 | s1 [A] | provenance | | +| main.rs:368:16:368:25 | source(...) | main.rs:368:14:368:26 | A(...) [A] | provenance | | +| main.rs:370:11:370:12 | s1 [A] | main.rs:371:9:371:12 | A(...) [A] | provenance | | +| main.rs:370:11:370:12 | s1 [A] | main.rs:374:11:374:12 | s1 [A] | provenance | | +| main.rs:371:9:371:12 | A(...) [A] | main.rs:371:11:371:11 | n | provenance | | +| main.rs:371:11:371:11 | n | main.rs:371:22:371:22 | n | provenance | | +| main.rs:374:11:374:12 | s1 [A] | main.rs:375:9:375:12 | A(...) [A] | provenance | | +| main.rs:375:9:375:12 | A(...) [A] | main.rs:375:11:375:11 | n | provenance | | +| main.rs:375:11:375:11 | n | main.rs:375:29:375:29 | n | provenance | | +| main.rs:389:9:389:10 | s1 [C] | main.rs:393:11:393:12 | s1 [C] | provenance | | +| main.rs:389:14:391:5 | ...::C {...} [C] | main.rs:389:9:389:10 | s1 [C] | provenance | | +| main.rs:390:18:390:27 | source(...) | main.rs:389:14:391:5 | ...::C {...} [C] | provenance | | +| main.rs:393:11:393:12 | s1 [C] | main.rs:394:9:394:38 | ...::C {...} [C] | provenance | | +| main.rs:393:11:393:12 | s1 [C] | main.rs:397:11:397:12 | s1 [C] | provenance | | +| main.rs:394:9:394:38 | ...::C {...} [C] | main.rs:394:36:394:36 | n | provenance | | +| main.rs:394:36:394:36 | n | main.rs:394:48:394:48 | n | provenance | | +| main.rs:397:11:397:12 | s1 [C] | main.rs:398:9:398:38 | ...::C {...} [C] | provenance | | +| main.rs:398:9:398:38 | ...::C {...} [C] | main.rs:398:36:398:36 | n | provenance | | +| main.rs:398:36:398:36 | n | main.rs:398:81:398:81 | n | provenance | | +| main.rs:409:9:409:10 | s1 [C] | main.rs:413:11:413:12 | s1 [C] | provenance | | +| main.rs:409:14:411:5 | C {...} [C] | main.rs:409:9:409:10 | s1 [C] | provenance | | +| main.rs:410:18:410:27 | source(...) | main.rs:409:14:411:5 | C {...} [C] | provenance | | +| main.rs:413:11:413:12 | s1 [C] | main.rs:414:9:414:24 | C {...} [C] | provenance | | +| main.rs:413:11:413:12 | s1 [C] | main.rs:417:11:417:12 | s1 [C] | provenance | | +| main.rs:414:9:414:24 | C {...} [C] | main.rs:414:22:414:22 | n | provenance | | +| main.rs:414:22:414:22 | n | main.rs:414:34:414:34 | n | provenance | | +| main.rs:417:11:417:12 | s1 [C] | main.rs:418:9:418:24 | C {...} [C] | provenance | | +| main.rs:418:9:418:24 | C {...} [C] | main.rs:418:22:418:22 | n | provenance | | +| main.rs:418:22:418:22 | n | main.rs:418:53:418:53 | n | provenance | | +| main.rs:430:9:430:12 | arr1 [element] | main.rs:431:14:431:17 | arr1 [element] | provenance | | +| main.rs:430:16:430:33 | [...] [element] | main.rs:430:9:430:12 | arr1 [element] | provenance | | +| main.rs:430:23:430:32 | source(...) | main.rs:430:16:430:33 | [...] [element] | provenance | | +| main.rs:431:9:431:10 | n1 | main.rs:432:10:432:11 | n1 | provenance | | +| main.rs:431:14:431:17 | arr1 [element] | main.rs:431:14:431:20 | arr1[2] | provenance | | +| main.rs:431:14:431:20 | arr1[2] | main.rs:431:9:431:10 | n1 | provenance | | +| main.rs:434:9:434:12 | arr2 [element] | main.rs:435:14:435:17 | arr2 [element] | provenance | | +| main.rs:434:16:434:31 | [...; 10] [element] | main.rs:434:9:434:12 | arr2 [element] | provenance | | +| main.rs:434:17:434:26 | source(...) | main.rs:434:16:434:31 | [...; 10] [element] | provenance | | +| main.rs:435:9:435:10 | n2 | main.rs:436:10:436:11 | n2 | provenance | | +| main.rs:435:14:435:17 | arr2 [element] | main.rs:435:14:435:20 | arr2[4] | provenance | | +| main.rs:435:14:435:20 | arr2[4] | main.rs:435:9:435:10 | n2 | provenance | | +| main.rs:444:9:444:12 | arr1 [element] | main.rs:445:15:445:18 | arr1 [element] | provenance | | | main.rs:444:16:444:33 | [...] [element] | main.rs:444:9:444:12 | arr1 [element] | provenance | | | main.rs:444:23:444:32 | source(...) | main.rs:444:16:444:33 | [...] [element] | provenance | | -| main.rs:445:11:445:14 | arr1 [element] | main.rs:446:9:446:17 | SlicePat [element] | provenance | | -| main.rs:446:9:446:17 | SlicePat [element] | main.rs:446:10:446:10 | a | provenance | | -| main.rs:446:9:446:17 | SlicePat [element] | main.rs:446:13:446:13 | b | provenance | | -| main.rs:446:9:446:17 | SlicePat [element] | main.rs:446:16:446:16 | c | provenance | | -| main.rs:446:10:446:10 | a | main.rs:447:18:447:18 | a | provenance | | -| main.rs:446:13:446:13 | b | main.rs:448:18:448:18 | b | provenance | | -| main.rs:446:16:446:16 | c | main.rs:449:18:449:18 | c | provenance | | -| main.rs:458:5:458:11 | [post] mut_arr [element] | main.rs:459:13:459:19 | mut_arr [element] | provenance | | -| main.rs:458:5:458:11 | [post] mut_arr [element] | main.rs:461:10:461:16 | mut_arr [element] | provenance | | -| main.rs:458:18:458:27 | source(...) | main.rs:458:5:458:11 | [post] mut_arr [element] | provenance | | -| main.rs:459:9:459:9 | d | main.rs:460:10:460:10 | d | provenance | | -| main.rs:459:13:459:19 | mut_arr [element] | main.rs:459:13:459:22 | mut_arr[1] | provenance | | -| main.rs:459:13:459:22 | mut_arr[1] | main.rs:459:9:459:9 | d | provenance | | -| main.rs:461:10:461:16 | mut_arr [element] | main.rs:461:10:461:19 | mut_arr[0] | provenance | | -| main.rs:484:9:484:9 | s | main.rs:485:10:485:10 | s | provenance | | -| main.rs:484:25:484:26 | source(...) | main.rs:484:9:484:9 | s | provenance | | -| main.rs:493:9:493:9 | a | main.rs:498:10:498:10 | a | provenance | | -| main.rs:493:13:493:22 | source(...) | main.rs:493:9:493:9 | a | provenance | | -| main.rs:505:9:505:10 | vs [element] | main.rs:507:10:507:11 | vs [element] | provenance | | -| main.rs:505:9:505:10 | vs [element] | main.rs:511:14:511:15 | vs [element] | provenance | | -| main.rs:505:14:505:34 | [...] [element] | main.rs:505:9:505:10 | vs [element] | provenance | | -| main.rs:505:15:505:24 | source(...) | main.rs:505:14:505:34 | [...] [element] | provenance | | -| main.rs:507:10:507:11 | vs [element] | main.rs:507:10:507:14 | vs[0] | provenance | | -| main.rs:511:9:511:9 | v | main.rs:512:14:512:14 | v | provenance | | -| main.rs:511:14:511:15 | vs [element] | main.rs:511:9:511:9 | v | provenance | | -| main.rs:530:9:530:18 | mut vs_mut [element] | main.rs:532:10:532:15 | vs_mut [element] | provenance | | -| main.rs:530:22:530:42 | [...] [element] | main.rs:530:9:530:18 | mut vs_mut [element] | provenance | | -| main.rs:530:23:530:32 | source(...) | main.rs:530:22:530:42 | [...] [element] | provenance | | -| main.rs:532:10:532:15 | vs_mut [element] | main.rs:532:10:532:18 | vs_mut[0] | provenance | | -| main.rs:542:9:542:9 | a | main.rs:547:10:547:10 | a | provenance | | -| main.rs:542:13:542:22 | source(...) | main.rs:542:9:542:9 | a | provenance | | -| main.rs:544:9:544:9 | c | main.rs:545:18:545:18 | c | provenance | | -| main.rs:544:13:544:22 | source(...) | main.rs:544:9:544:9 | c | provenance | | -| main.rs:545:9:545:13 | c_ref [&ref] | main.rs:550:11:550:15 | c_ref [&ref] | provenance | | -| main.rs:545:17:545:18 | &c [&ref] | main.rs:545:9:545:13 | c_ref [&ref] | provenance | | -| main.rs:545:18:545:18 | c | main.rs:545:17:545:18 | &c [&ref] | provenance | | -| main.rs:550:11:550:15 | c_ref [&ref] | main.rs:550:10:550:15 | * ... | provenance | | +| main.rs:445:9:445:10 | n1 | main.rs:446:14:446:15 | n1 | provenance | | +| main.rs:445:15:445:18 | arr1 [element] | main.rs:445:9:445:10 | n1 | provenance | | +| main.rs:456:9:456:12 | arr1 [element] | main.rs:457:11:457:14 | arr1 [element] | provenance | | +| main.rs:456:16:456:33 | [...] [element] | main.rs:456:9:456:12 | arr1 [element] | provenance | | +| main.rs:456:23:456:32 | source(...) | main.rs:456:16:456:33 | [...] [element] | provenance | | +| main.rs:457:11:457:14 | arr1 [element] | main.rs:458:9:458:17 | SlicePat [element] | provenance | | +| main.rs:458:9:458:17 | SlicePat [element] | main.rs:458:10:458:10 | a | provenance | | +| main.rs:458:9:458:17 | SlicePat [element] | main.rs:458:13:458:13 | b | provenance | | +| main.rs:458:9:458:17 | SlicePat [element] | main.rs:458:16:458:16 | c | provenance | | +| main.rs:458:10:458:10 | a | main.rs:459:18:459:18 | a | provenance | | +| main.rs:458:13:458:13 | b | main.rs:460:18:460:18 | b | provenance | | +| main.rs:458:16:458:16 | c | main.rs:461:18:461:18 | c | provenance | | +| main.rs:470:5:470:11 | [post] mut_arr [element] | main.rs:471:13:471:19 | mut_arr [element] | provenance | | +| main.rs:470:5:470:11 | [post] mut_arr [element] | main.rs:473:10:473:16 | mut_arr [element] | provenance | | +| main.rs:470:18:470:27 | source(...) | main.rs:470:5:470:11 | [post] mut_arr [element] | provenance | | +| main.rs:471:9:471:9 | d | main.rs:472:10:472:10 | d | provenance | | +| main.rs:471:13:471:19 | mut_arr [element] | main.rs:471:13:471:22 | mut_arr[1] | provenance | | +| main.rs:471:13:471:22 | mut_arr[1] | main.rs:471:9:471:9 | d | provenance | | +| main.rs:473:10:473:16 | mut_arr [element] | main.rs:473:10:473:19 | mut_arr[0] | provenance | | +| main.rs:496:9:496:9 | s | main.rs:497:10:497:10 | s | provenance | | +| main.rs:496:25:496:26 | source(...) | main.rs:496:9:496:9 | s | provenance | | +| main.rs:505:9:505:9 | a | main.rs:510:10:510:10 | a | provenance | | +| main.rs:505:13:505:22 | source(...) | main.rs:505:9:505:9 | a | provenance | | +| main.rs:517:9:517:10 | vs [element] | main.rs:519:10:519:11 | vs [element] | provenance | | +| main.rs:517:9:517:10 | vs [element] | main.rs:523:14:523:15 | vs [element] | provenance | | +| main.rs:517:14:517:34 | [...] [element] | main.rs:517:9:517:10 | vs [element] | provenance | | +| main.rs:517:15:517:24 | source(...) | main.rs:517:14:517:34 | [...] [element] | provenance | | +| main.rs:519:10:519:11 | vs [element] | main.rs:519:10:519:14 | vs[0] | provenance | | +| main.rs:523:9:523:9 | v | main.rs:524:14:524:14 | v | provenance | | +| main.rs:523:14:523:15 | vs [element] | main.rs:523:9:523:9 | v | provenance | | +| main.rs:542:9:542:18 | mut vs_mut [element] | main.rs:544:10:544:15 | vs_mut [element] | provenance | | +| main.rs:542:22:542:42 | [...] [element] | main.rs:542:9:542:18 | mut vs_mut [element] | provenance | | +| main.rs:542:23:542:32 | source(...) | main.rs:542:22:542:42 | [...] [element] | provenance | | +| main.rs:544:10:544:15 | vs_mut [element] | main.rs:544:10:544:18 | vs_mut[0] | provenance | | +| main.rs:554:9:554:9 | a | main.rs:559:10:559:10 | a | provenance | | +| main.rs:554:13:554:22 | source(...) | main.rs:554:9:554:9 | a | provenance | | +| main.rs:556:9:556:9 | c | main.rs:557:18:557:18 | c | provenance | | +| main.rs:556:13:556:22 | source(...) | main.rs:556:9:556:9 | c | provenance | | +| main.rs:557:9:557:13 | c_ref [&ref] | main.rs:562:11:562:15 | c_ref [&ref] | provenance | | +| main.rs:557:17:557:18 | &c [&ref] | main.rs:557:9:557:13 | c_ref [&ref] | provenance | | +| main.rs:557:18:557:18 | c | main.rs:557:17:557:18 | &c [&ref] | provenance | | +| main.rs:562:11:562:15 | c_ref [&ref] | main.rs:562:10:562:15 | * ... | provenance | | nodes | main.rs:19:10:19:18 | source(...) | semmle.label | source(...) | | main.rs:23:9:23:9 | s | semmle.label | s | @@ -270,266 +274,271 @@ nodes | main.rs:70:5:70:5 | i | semmle.label | i | | main.rs:70:9:70:17 | source(...) | semmle.label | source(...) | | main.rs:71:10:71:10 | i | semmle.label | i | -| main.rs:103:9:103:9 | i [&ref] | semmle.label | i [&ref] | -| main.rs:103:13:103:31 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] | -| main.rs:103:22:103:30 | source(...) | semmle.label | source(...) | -| main.rs:104:10:104:11 | * ... | semmle.label | * ... | -| main.rs:104:11:104:11 | i [&ref] | semmle.label | i [&ref] | -| main.rs:111:9:111:9 | a [tuple.0] | semmle.label | a [tuple.0] | -| main.rs:111:13:111:26 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | -| main.rs:111:14:111:22 | source(...) | semmle.label | source(...) | -| main.rs:112:10:112:10 | a [tuple.0] | semmle.label | a [tuple.0] | -| main.rs:112:10:112:12 | a.0 | semmle.label | a.0 | -| main.rs:117:9:117:9 | a [tuple.1] | semmle.label | a [tuple.1] | -| main.rs:117:13:117:30 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] | -| main.rs:117:17:117:26 | source(...) | semmle.label | source(...) | -| main.rs:118:9:118:20 | TuplePat [tuple.1] | semmle.label | TuplePat [tuple.1] | -| main.rs:118:14:118:15 | a1 | semmle.label | a1 | -| main.rs:120:10:120:11 | a1 | semmle.label | a1 | -| main.rs:125:9:125:13 | mut a [tuple.1] | semmle.label | mut a [tuple.1] | -| main.rs:125:17:125:31 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] | -| main.rs:125:21:125:30 | source(...) | semmle.label | source(...) | -| main.rs:127:10:127:10 | a [tuple.1] | semmle.label | a [tuple.1] | -| main.rs:127:10:127:12 | a.1 | semmle.label | a.1 | -| main.rs:128:5:128:5 | [post] a [tuple.0] | semmle.label | [post] a [tuple.0] | -| main.rs:128:11:128:20 | source(...) | semmle.label | source(...) | -| main.rs:129:5:129:5 | a [tuple.0] | semmle.label | a [tuple.0] | -| main.rs:130:10:130:10 | a [tuple.0] | semmle.label | a [tuple.0] | -| main.rs:130:10:130:12 | a.0 | semmle.label | a.0 | -| main.rs:135:9:135:9 | a [tuple.1] | semmle.label | a [tuple.1] | -| main.rs:135:13:135:27 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] | -| main.rs:135:17:135:26 | source(...) | semmle.label | source(...) | -| main.rs:136:9:136:9 | b [tuple.0, tuple.1] | semmle.label | b [tuple.0, tuple.1] | -| main.rs:136:13:136:18 | TupleExpr [tuple.0, tuple.1] | semmle.label | TupleExpr [tuple.0, tuple.1] | -| main.rs:136:14:136:14 | a [tuple.1] | semmle.label | a [tuple.1] | -| main.rs:138:10:138:10 | b [tuple.0, tuple.1] | semmle.label | b [tuple.0, tuple.1] | -| main.rs:138:10:138:12 | b.0 [tuple.1] | semmle.label | b.0 [tuple.1] | -| main.rs:138:10:138:15 | ... .1 | semmle.label | ... .1 | -| main.rs:151:9:151:9 | p [Point.x] | semmle.label | p [Point.x] | -| main.rs:151:13:151:40 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] | -| main.rs:151:24:151:32 | source(...) | semmle.label | source(...) | -| main.rs:152:10:152:10 | p [Point.x] | semmle.label | p [Point.x] | -| main.rs:152:10:152:12 | p.x | semmle.label | p.x | -| main.rs:159:5:159:5 | [post] p [Point.y] | semmle.label | [post] p [Point.y] | -| main.rs:159:11:159:20 | source(...) | semmle.label | source(...) | -| main.rs:160:10:160:10 | p [Point.y] | semmle.label | p [Point.y] | -| main.rs:160:10:160:12 | p.y | semmle.label | p.y | -| main.rs:164:9:164:9 | p [Point.x] | semmle.label | p [Point.x] | -| main.rs:164:13:167:5 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] | -| main.rs:165:12:165:21 | source(...) | semmle.label | source(...) | -| main.rs:168:9:168:28 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] | -| main.rs:168:20:168:20 | a | semmle.label | a | -| main.rs:169:10:169:10 | a | semmle.label | a | -| main.rs:179:9:179:9 | p [Point3D.plane, Point.y] | semmle.label | p [Point3D.plane, Point.y] | -| main.rs:179:13:185:5 | Point3D {...} [Point3D.plane, Point.y] | semmle.label | Point3D {...} [Point3D.plane, Point.y] | -| main.rs:180:16:183:9 | Point {...} [Point.y] | semmle.label | Point {...} [Point.y] | -| main.rs:182:16:182:25 | source(...) | semmle.label | source(...) | -| main.rs:187:10:187:10 | p [Point3D.plane, Point.y] | semmle.label | p [Point3D.plane, Point.y] | -| main.rs:187:10:187:16 | p.plane [Point.y] | semmle.label | p.plane [Point.y] | -| main.rs:187:10:187:18 | ... .y | semmle.label | ... .y | -| main.rs:192:9:192:9 | y | semmle.label | y | -| main.rs:192:13:192:22 | source(...) | semmle.label | source(...) | -| main.rs:193:9:193:9 | p [Point3D.plane, Point.y] | semmle.label | p [Point3D.plane, Point.y] | -| main.rs:193:13:196:5 | Point3D {...} [Point3D.plane, Point.y] | semmle.label | Point3D {...} [Point3D.plane, Point.y] | -| main.rs:194:16:194:32 | Point {...} [Point.y] | semmle.label | Point {...} [Point.y] | -| main.rs:194:30:194:30 | y | semmle.label | y | -| main.rs:197:11:197:11 | p [Point3D.plane, Point.y] | semmle.label | p [Point3D.plane, Point.y] | -| main.rs:198:9:201:9 | Point3D {...} [Point3D.plane, Point.y] | semmle.label | Point3D {...} [Point3D.plane, Point.y] | -| main.rs:199:20:199:33 | Point {...} [Point.y] | semmle.label | Point {...} [Point.y] | -| main.rs:199:31:199:31 | y | semmle.label | y | -| main.rs:203:18:203:18 | y | semmle.label | y | -| main.rs:212:9:212:9 | s [MyTupleStruct(0)] | semmle.label | s [MyTupleStruct(0)] | -| main.rs:212:13:212:40 | MyTupleStruct(...) [MyTupleStruct(0)] | semmle.label | MyTupleStruct(...) [MyTupleStruct(0)] | -| main.rs:212:27:212:36 | source(...) | semmle.label | source(...) | -| main.rs:213:10:213:10 | s [MyTupleStruct(0)] | semmle.label | s [MyTupleStruct(0)] | -| main.rs:213:10:213:12 | s.0 | semmle.label | s.0 | -| main.rs:216:11:216:11 | s [MyTupleStruct(0)] | semmle.label | s [MyTupleStruct(0)] | -| main.rs:217:9:217:27 | MyTupleStruct(...) [MyTupleStruct(0)] | semmle.label | MyTupleStruct(...) [MyTupleStruct(0)] | -| main.rs:217:23:217:23 | x | semmle.label | x | -| main.rs:218:18:218:18 | x | semmle.label | x | -| main.rs:228:9:228:10 | s1 [Some] | semmle.label | s1 [Some] | -| main.rs:228:14:228:37 | ...::Some(...) [Some] | semmle.label | ...::Some(...) [Some] | -| main.rs:228:27:228:36 | source(...) | semmle.label | source(...) | -| main.rs:230:11:230:12 | s1 [Some] | semmle.label | s1 [Some] | -| main.rs:231:9:231:23 | ...::Some(...) [Some] | semmle.label | ...::Some(...) [Some] | -| main.rs:231:22:231:22 | n | semmle.label | n | -| main.rs:231:33:231:33 | n | semmle.label | n | -| main.rs:241:9:241:10 | s1 [Some] | semmle.label | s1 [Some] | -| main.rs:241:14:241:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | -| main.rs:241:19:241:28 | source(...) | semmle.label | source(...) | -| main.rs:243:11:243:12 | s1 [Some] | semmle.label | s1 [Some] | -| main.rs:244:9:244:15 | Some(...) [Some] | semmle.label | Some(...) [Some] | -| main.rs:244:14:244:14 | n | semmle.label | n | -| main.rs:244:25:244:25 | n | semmle.label | n | -| main.rs:254:9:254:10 | s1 [Some] | semmle.label | s1 [Some] | -| main.rs:254:14:254:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | -| main.rs:254:19:254:28 | source(...) | semmle.label | source(...) | -| main.rs:255:12:255:18 | Some(...) [Some] | semmle.label | Some(...) [Some] | -| main.rs:255:17:255:17 | n | semmle.label | n | -| main.rs:257:18:257:18 | n | semmle.label | n | -| main.rs:261:14:261:14 | n | semmle.label | n | +| main.rs:76:9:76:9 | k | semmle.label | k | +| main.rs:76:13:76:21 | source(...) | semmle.label | source(...) | +| main.rs:77:5:77:5 | j | semmle.label | j | +| main.rs:78:10:78:10 | j | semmle.label | j | +| main.rs:79:10:79:10 | k | semmle.label | k | +| main.rs:115:9:115:9 | i [&ref] | semmle.label | i [&ref] | +| main.rs:115:13:115:31 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] | +| main.rs:115:22:115:30 | source(...) | semmle.label | source(...) | +| main.rs:116:10:116:11 | * ... | semmle.label | * ... | +| main.rs:116:11:116:11 | i [&ref] | semmle.label | i [&ref] | +| main.rs:123:9:123:9 | a [tuple.0] | semmle.label | a [tuple.0] | +| main.rs:123:13:123:26 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] | +| main.rs:123:14:123:22 | source(...) | semmle.label | source(...) | +| main.rs:124:10:124:10 | a [tuple.0] | semmle.label | a [tuple.0] | +| main.rs:124:10:124:12 | a.0 | semmle.label | a.0 | +| main.rs:129:9:129:9 | a [tuple.1] | semmle.label | a [tuple.1] | +| main.rs:129:13:129:30 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] | +| main.rs:129:17:129:26 | source(...) | semmle.label | source(...) | +| main.rs:130:9:130:20 | TuplePat [tuple.1] | semmle.label | TuplePat [tuple.1] | +| main.rs:130:14:130:15 | a1 | semmle.label | a1 | +| main.rs:132:10:132:11 | a1 | semmle.label | a1 | +| main.rs:137:9:137:13 | mut a [tuple.1] | semmle.label | mut a [tuple.1] | +| main.rs:137:17:137:31 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] | +| main.rs:137:21:137:30 | source(...) | semmle.label | source(...) | +| main.rs:139:10:139:10 | a [tuple.1] | semmle.label | a [tuple.1] | +| main.rs:139:10:139:12 | a.1 | semmle.label | a.1 | +| main.rs:140:5:140:5 | [post] a [tuple.0] | semmle.label | [post] a [tuple.0] | +| main.rs:140:11:140:20 | source(...) | semmle.label | source(...) | +| main.rs:141:5:141:5 | a [tuple.0] | semmle.label | a [tuple.0] | +| main.rs:142:10:142:10 | a [tuple.0] | semmle.label | a [tuple.0] | +| main.rs:142:10:142:12 | a.0 | semmle.label | a.0 | +| main.rs:147:9:147:9 | a [tuple.1] | semmle.label | a [tuple.1] | +| main.rs:147:13:147:27 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] | +| main.rs:147:17:147:26 | source(...) | semmle.label | source(...) | +| main.rs:148:9:148:9 | b [tuple.0, tuple.1] | semmle.label | b [tuple.0, tuple.1] | +| main.rs:148:13:148:18 | TupleExpr [tuple.0, tuple.1] | semmle.label | TupleExpr [tuple.0, tuple.1] | +| main.rs:148:14:148:14 | a [tuple.1] | semmle.label | a [tuple.1] | +| main.rs:150:10:150:10 | b [tuple.0, tuple.1] | semmle.label | b [tuple.0, tuple.1] | +| main.rs:150:10:150:12 | b.0 [tuple.1] | semmle.label | b.0 [tuple.1] | +| main.rs:150:10:150:15 | ... .1 | semmle.label | ... .1 | +| main.rs:163:9:163:9 | p [Point.x] | semmle.label | p [Point.x] | +| main.rs:163:13:163:40 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] | +| main.rs:163:24:163:32 | source(...) | semmle.label | source(...) | +| main.rs:164:10:164:10 | p [Point.x] | semmle.label | p [Point.x] | +| main.rs:164:10:164:12 | p.x | semmle.label | p.x | +| main.rs:171:5:171:5 | [post] p [Point.y] | semmle.label | [post] p [Point.y] | +| main.rs:171:11:171:20 | source(...) | semmle.label | source(...) | +| main.rs:172:10:172:10 | p [Point.y] | semmle.label | p [Point.y] | +| main.rs:172:10:172:12 | p.y | semmle.label | p.y | +| main.rs:176:9:176:9 | p [Point.x] | semmle.label | p [Point.x] | +| main.rs:176:13:179:5 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] | +| main.rs:177:12:177:21 | source(...) | semmle.label | source(...) | +| main.rs:180:9:180:28 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] | +| main.rs:180:20:180:20 | a | semmle.label | a | +| main.rs:181:10:181:10 | a | semmle.label | a | +| main.rs:191:9:191:9 | p [Point3D.plane, Point.y] | semmle.label | p [Point3D.plane, Point.y] | +| main.rs:191:13:197:5 | Point3D {...} [Point3D.plane, Point.y] | semmle.label | Point3D {...} [Point3D.plane, Point.y] | +| main.rs:192:16:195:9 | Point {...} [Point.y] | semmle.label | Point {...} [Point.y] | +| main.rs:194:16:194:25 | source(...) | semmle.label | source(...) | +| main.rs:199:10:199:10 | p [Point3D.plane, Point.y] | semmle.label | p [Point3D.plane, Point.y] | +| main.rs:199:10:199:16 | p.plane [Point.y] | semmle.label | p.plane [Point.y] | +| main.rs:199:10:199:18 | ... .y | semmle.label | ... .y | +| main.rs:204:9:204:9 | y | semmle.label | y | +| main.rs:204:13:204:22 | source(...) | semmle.label | source(...) | +| main.rs:205:9:205:9 | p [Point3D.plane, Point.y] | semmle.label | p [Point3D.plane, Point.y] | +| main.rs:205:13:208:5 | Point3D {...} [Point3D.plane, Point.y] | semmle.label | Point3D {...} [Point3D.plane, Point.y] | +| main.rs:206:16:206:32 | Point {...} [Point.y] | semmle.label | Point {...} [Point.y] | +| main.rs:206:30:206:30 | y | semmle.label | y | +| main.rs:209:11:209:11 | p [Point3D.plane, Point.y] | semmle.label | p [Point3D.plane, Point.y] | +| main.rs:210:9:213:9 | Point3D {...} [Point3D.plane, Point.y] | semmle.label | Point3D {...} [Point3D.plane, Point.y] | +| main.rs:211:20:211:33 | Point {...} [Point.y] | semmle.label | Point {...} [Point.y] | +| main.rs:211:31:211:31 | y | semmle.label | y | +| main.rs:215:18:215:18 | y | semmle.label | y | +| main.rs:224:9:224:9 | s [MyTupleStruct(0)] | semmle.label | s [MyTupleStruct(0)] | +| main.rs:224:13:224:40 | MyTupleStruct(...) [MyTupleStruct(0)] | semmle.label | MyTupleStruct(...) [MyTupleStruct(0)] | +| main.rs:224:27:224:36 | source(...) | semmle.label | source(...) | +| main.rs:225:10:225:10 | s [MyTupleStruct(0)] | semmle.label | s [MyTupleStruct(0)] | +| main.rs:225:10:225:12 | s.0 | semmle.label | s.0 | +| main.rs:228:11:228:11 | s [MyTupleStruct(0)] | semmle.label | s [MyTupleStruct(0)] | +| main.rs:229:9:229:27 | MyTupleStruct(...) [MyTupleStruct(0)] | semmle.label | MyTupleStruct(...) [MyTupleStruct(0)] | +| main.rs:229:23:229:23 | x | semmle.label | x | +| main.rs:230:18:230:18 | x | semmle.label | x | +| main.rs:240:9:240:10 | s1 [Some] | semmle.label | s1 [Some] | +| main.rs:240:14:240:37 | ...::Some(...) [Some] | semmle.label | ...::Some(...) [Some] | +| main.rs:240:27:240:36 | source(...) | semmle.label | source(...) | +| main.rs:242:11:242:12 | s1 [Some] | semmle.label | s1 [Some] | +| main.rs:243:9:243:23 | ...::Some(...) [Some] | semmle.label | ...::Some(...) [Some] | +| main.rs:243:22:243:22 | n | semmle.label | n | +| main.rs:243:33:243:33 | n | semmle.label | n | +| main.rs:253:9:253:10 | s1 [Some] | semmle.label | s1 [Some] | +| main.rs:253:14:253:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | +| main.rs:253:19:253:28 | source(...) | semmle.label | source(...) | +| main.rs:255:11:255:12 | s1 [Some] | semmle.label | s1 [Some] | +| main.rs:256:9:256:15 | Some(...) [Some] | semmle.label | Some(...) [Some] | +| main.rs:256:14:256:14 | n | semmle.label | n | +| main.rs:256:25:256:25 | n | semmle.label | n | | main.rs:266:9:266:10 | s1 [Some] | semmle.label | s1 [Some] | | main.rs:266:14:266:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | | main.rs:266:19:266:28 | source(...) | semmle.label | source(...) | -| main.rs:267:10:267:20 | s1.unwrap() | semmle.label | s1.unwrap() | -| main.rs:271:9:271:10 | s1 [Some] | semmle.label | s1 [Some] | -| main.rs:271:14:271:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | -| main.rs:271:19:271:28 | source(...) | semmle.label | source(...) | -| main.rs:272:10:272:24 | s1.unwrap_or(...) | semmle.label | s1.unwrap_or(...) | -| main.rs:275:10:275:33 | s2.unwrap_or(...) | semmle.label | s2.unwrap_or(...) | -| main.rs:275:23:275:32 | source(...) | semmle.label | source(...) | -| main.rs:279:9:279:10 | s1 [Some] | semmle.label | s1 [Some] | -| main.rs:279:14:279:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | -| main.rs:279:19:279:28 | source(...) | semmle.label | source(...) | -| main.rs:280:10:280:32 | s1.unwrap_or_else(...) | semmle.label | s1.unwrap_or_else(...) | -| main.rs:283:10:283:41 | s2.unwrap_or_else(...) | semmle.label | s2.unwrap_or_else(...) | -| main.rs:283:31:283:40 | source(...) | semmle.label | source(...) | -| main.rs:287:9:287:10 | s1 [Some] | semmle.label | s1 [Some] | -| main.rs:287:14:287:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | -| main.rs:287:19:287:28 | source(...) | semmle.label | source(...) | -| main.rs:289:9:289:10 | i1 | semmle.label | i1 | -| main.rs:289:14:289:15 | s1 [Some] | semmle.label | s1 [Some] | -| main.rs:289:14:289:16 | TryExpr | semmle.label | TryExpr | -| main.rs:290:10:290:11 | i1 | semmle.label | i1 | -| main.rs:296:9:296:10 | r1 [Ok] | semmle.label | r1 [Ok] | -| main.rs:296:32:296:45 | Ok(...) [Ok] | semmle.label | Ok(...) [Ok] | -| main.rs:296:35:296:44 | source(...) | semmle.label | source(...) | -| main.rs:297:9:297:11 | o1a [Some] | semmle.label | o1a [Some] | -| main.rs:297:28:297:34 | r1.ok() [Some] | semmle.label | r1.ok() [Some] | -| main.rs:299:10:299:21 | o1a.unwrap() | semmle.label | o1a.unwrap() | -| main.rs:302:9:302:10 | r2 [Err] | semmle.label | r2 [Err] | -| main.rs:302:32:302:46 | Err(...) [Err] | semmle.label | Err(...) [Err] | -| main.rs:302:36:302:45 | source(...) | semmle.label | source(...) | -| main.rs:304:9:304:11 | o2b [Some] | semmle.label | o2b [Some] | -| main.rs:304:28:304:35 | r2.err() [Some] | semmle.label | r2.err() [Some] | -| main.rs:306:10:306:21 | o2b.unwrap() | semmle.label | o2b.unwrap() | -| main.rs:310:9:310:10 | s1 [Ok] | semmle.label | s1 [Ok] | -| main.rs:310:32:310:45 | Ok(...) [Ok] | semmle.label | Ok(...) [Ok] | -| main.rs:310:35:310:44 | source(...) | semmle.label | source(...) | -| main.rs:313:9:313:10 | i1 | semmle.label | i1 | -| main.rs:313:14:313:15 | s1 [Ok] | semmle.label | s1 [Ok] | -| main.rs:313:14:313:16 | TryExpr | semmle.label | TryExpr | -| main.rs:315:10:315:11 | i1 | semmle.label | i1 | -| main.rs:323:9:323:10 | s1 [Ok] | semmle.label | s1 [Ok] | -| main.rs:323:32:323:45 | Ok(...) [Ok] | semmle.label | Ok(...) [Ok] | -| main.rs:323:35:323:44 | source(...) | semmle.label | source(...) | -| main.rs:324:10:324:22 | s1.expect(...) | semmle.label | s1.expect(...) | -| main.rs:327:9:327:10 | s2 [Err] | semmle.label | s2 [Err] | -| main.rs:327:32:327:46 | Err(...) [Err] | semmle.label | Err(...) [Err] | -| main.rs:327:36:327:45 | source(...) | semmle.label | source(...) | -| main.rs:329:10:329:26 | s2.expect_err(...) | semmle.label | s2.expect_err(...) | -| main.rs:338:9:338:10 | s1 [A] | semmle.label | s1 [A] | -| main.rs:338:14:338:39 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | -| main.rs:338:29:338:38 | source(...) | semmle.label | source(...) | -| main.rs:340:11:340:12 | s1 [A] | semmle.label | s1 [A] | -| main.rs:341:9:341:25 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | -| main.rs:341:24:341:24 | n | semmle.label | n | -| main.rs:341:35:341:35 | n | semmle.label | n | -| main.rs:344:11:344:12 | s1 [A] | semmle.label | s1 [A] | -| main.rs:345:9:345:25 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | -| main.rs:345:24:345:24 | n | semmle.label | n | -| main.rs:345:55:345:55 | n | semmle.label | n | -| main.rs:356:9:356:10 | s1 [A] | semmle.label | s1 [A] | -| main.rs:356:14:356:26 | A(...) [A] | semmle.label | A(...) [A] | -| main.rs:356:16:356:25 | source(...) | semmle.label | source(...) | -| main.rs:358:11:358:12 | s1 [A] | semmle.label | s1 [A] | -| main.rs:359:9:359:12 | A(...) [A] | semmle.label | A(...) [A] | -| main.rs:359:11:359:11 | n | semmle.label | n | -| main.rs:359:22:359:22 | n | semmle.label | n | -| main.rs:362:11:362:12 | s1 [A] | semmle.label | s1 [A] | -| main.rs:363:9:363:12 | A(...) [A] | semmle.label | A(...) [A] | -| main.rs:363:11:363:11 | n | semmle.label | n | -| main.rs:363:29:363:29 | n | semmle.label | n | -| main.rs:377:9:377:10 | s1 [C] | semmle.label | s1 [C] | -| main.rs:377:14:379:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:378:18:378:27 | source(...) | semmle.label | source(...) | -| main.rs:381:11:381:12 | s1 [C] | semmle.label | s1 [C] | -| main.rs:382:9:382:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:382:36:382:36 | n | semmle.label | n | -| main.rs:382:48:382:48 | n | semmle.label | n | -| main.rs:385:11:385:12 | s1 [C] | semmle.label | s1 [C] | -| main.rs:386:9:386:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:386:36:386:36 | n | semmle.label | n | -| main.rs:386:81:386:81 | n | semmle.label | n | -| main.rs:397:9:397:10 | s1 [C] | semmle.label | s1 [C] | -| main.rs:397:14:399:5 | C {...} [C] | semmle.label | C {...} [C] | -| main.rs:398:18:398:27 | source(...) | semmle.label | source(...) | -| main.rs:401:11:401:12 | s1 [C] | semmle.label | s1 [C] | -| main.rs:402:9:402:24 | C {...} [C] | semmle.label | C {...} [C] | -| main.rs:402:22:402:22 | n | semmle.label | n | -| main.rs:402:34:402:34 | n | semmle.label | n | -| main.rs:405:11:405:12 | s1 [C] | semmle.label | s1 [C] | -| main.rs:406:9:406:24 | C {...} [C] | semmle.label | C {...} [C] | -| main.rs:406:22:406:22 | n | semmle.label | n | -| main.rs:406:53:406:53 | n | semmle.label | n | -| main.rs:418:9:418:12 | arr1 [element] | semmle.label | arr1 [element] | -| main.rs:418:16:418:33 | [...] [element] | semmle.label | [...] [element] | -| main.rs:418:23:418:32 | source(...) | semmle.label | source(...) | -| main.rs:419:9:419:10 | n1 | semmle.label | n1 | -| main.rs:419:14:419:17 | arr1 [element] | semmle.label | arr1 [element] | -| main.rs:419:14:419:20 | arr1[2] | semmle.label | arr1[2] | -| main.rs:420:10:420:11 | n1 | semmle.label | n1 | -| main.rs:422:9:422:12 | arr2 [element] | semmle.label | arr2 [element] | -| main.rs:422:16:422:31 | [...; 10] [element] | semmle.label | [...; 10] [element] | -| main.rs:422:17:422:26 | source(...) | semmle.label | source(...) | -| main.rs:423:9:423:10 | n2 | semmle.label | n2 | -| main.rs:423:14:423:17 | arr2 [element] | semmle.label | arr2 [element] | -| main.rs:423:14:423:20 | arr2[4] | semmle.label | arr2[4] | -| main.rs:424:10:424:11 | n2 | semmle.label | n2 | -| main.rs:432:9:432:12 | arr1 [element] | semmle.label | arr1 [element] | -| main.rs:432:16:432:33 | [...] [element] | semmle.label | [...] [element] | -| main.rs:432:23:432:32 | source(...) | semmle.label | source(...) | -| main.rs:433:9:433:10 | n1 | semmle.label | n1 | -| main.rs:433:15:433:18 | arr1 [element] | semmle.label | arr1 [element] | -| main.rs:434:14:434:15 | n1 | semmle.label | n1 | +| main.rs:267:12:267:18 | Some(...) [Some] | semmle.label | Some(...) [Some] | +| main.rs:267:17:267:17 | n | semmle.label | n | +| main.rs:269:18:269:18 | n | semmle.label | n | +| main.rs:273:14:273:14 | n | semmle.label | n | +| main.rs:278:9:278:10 | s1 [Some] | semmle.label | s1 [Some] | +| main.rs:278:14:278:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | +| main.rs:278:19:278:28 | source(...) | semmle.label | source(...) | +| main.rs:279:10:279:20 | s1.unwrap() | semmle.label | s1.unwrap() | +| main.rs:283:9:283:10 | s1 [Some] | semmle.label | s1 [Some] | +| main.rs:283:14:283:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | +| main.rs:283:19:283:28 | source(...) | semmle.label | source(...) | +| main.rs:284:10:284:24 | s1.unwrap_or(...) | semmle.label | s1.unwrap_or(...) | +| main.rs:287:10:287:33 | s2.unwrap_or(...) | semmle.label | s2.unwrap_or(...) | +| main.rs:287:23:287:32 | source(...) | semmle.label | source(...) | +| main.rs:291:9:291:10 | s1 [Some] | semmle.label | s1 [Some] | +| main.rs:291:14:291:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | +| main.rs:291:19:291:28 | source(...) | semmle.label | source(...) | +| main.rs:292:10:292:32 | s1.unwrap_or_else(...) | semmle.label | s1.unwrap_or_else(...) | +| main.rs:295:10:295:41 | s2.unwrap_or_else(...) | semmle.label | s2.unwrap_or_else(...) | +| main.rs:295:31:295:40 | source(...) | semmle.label | source(...) | +| main.rs:299:9:299:10 | s1 [Some] | semmle.label | s1 [Some] | +| main.rs:299:14:299:29 | Some(...) [Some] | semmle.label | Some(...) [Some] | +| main.rs:299:19:299:28 | source(...) | semmle.label | source(...) | +| main.rs:301:9:301:10 | i1 | semmle.label | i1 | +| main.rs:301:14:301:15 | s1 [Some] | semmle.label | s1 [Some] | +| main.rs:301:14:301:16 | TryExpr | semmle.label | TryExpr | +| main.rs:302:10:302:11 | i1 | semmle.label | i1 | +| main.rs:308:9:308:10 | r1 [Ok] | semmle.label | r1 [Ok] | +| main.rs:308:32:308:45 | Ok(...) [Ok] | semmle.label | Ok(...) [Ok] | +| main.rs:308:35:308:44 | source(...) | semmle.label | source(...) | +| main.rs:309:9:309:11 | o1a [Some] | semmle.label | o1a [Some] | +| main.rs:309:28:309:34 | r1.ok() [Some] | semmle.label | r1.ok() [Some] | +| main.rs:311:10:311:21 | o1a.unwrap() | semmle.label | o1a.unwrap() | +| main.rs:314:9:314:10 | r2 [Err] | semmle.label | r2 [Err] | +| main.rs:314:32:314:46 | Err(...) [Err] | semmle.label | Err(...) [Err] | +| main.rs:314:36:314:45 | source(...) | semmle.label | source(...) | +| main.rs:316:9:316:11 | o2b [Some] | semmle.label | o2b [Some] | +| main.rs:316:28:316:35 | r2.err() [Some] | semmle.label | r2.err() [Some] | +| main.rs:318:10:318:21 | o2b.unwrap() | semmle.label | o2b.unwrap() | +| main.rs:322:9:322:10 | s1 [Ok] | semmle.label | s1 [Ok] | +| main.rs:322:32:322:45 | Ok(...) [Ok] | semmle.label | Ok(...) [Ok] | +| main.rs:322:35:322:44 | source(...) | semmle.label | source(...) | +| main.rs:325:9:325:10 | i1 | semmle.label | i1 | +| main.rs:325:14:325:15 | s1 [Ok] | semmle.label | s1 [Ok] | +| main.rs:325:14:325:16 | TryExpr | semmle.label | TryExpr | +| main.rs:327:10:327:11 | i1 | semmle.label | i1 | +| main.rs:335:9:335:10 | s1 [Ok] | semmle.label | s1 [Ok] | +| main.rs:335:32:335:45 | Ok(...) [Ok] | semmle.label | Ok(...) [Ok] | +| main.rs:335:35:335:44 | source(...) | semmle.label | source(...) | +| main.rs:336:10:336:22 | s1.expect(...) | semmle.label | s1.expect(...) | +| main.rs:339:9:339:10 | s2 [Err] | semmle.label | s2 [Err] | +| main.rs:339:32:339:46 | Err(...) [Err] | semmle.label | Err(...) [Err] | +| main.rs:339:36:339:45 | source(...) | semmle.label | source(...) | +| main.rs:341:10:341:26 | s2.expect_err(...) | semmle.label | s2.expect_err(...) | +| main.rs:350:9:350:10 | s1 [A] | semmle.label | s1 [A] | +| main.rs:350:14:350:39 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | +| main.rs:350:29:350:38 | source(...) | semmle.label | source(...) | +| main.rs:352:11:352:12 | s1 [A] | semmle.label | s1 [A] | +| main.rs:353:9:353:25 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | +| main.rs:353:24:353:24 | n | semmle.label | n | +| main.rs:353:35:353:35 | n | semmle.label | n | +| main.rs:356:11:356:12 | s1 [A] | semmle.label | s1 [A] | +| main.rs:357:9:357:25 | ...::A(...) [A] | semmle.label | ...::A(...) [A] | +| main.rs:357:24:357:24 | n | semmle.label | n | +| main.rs:357:55:357:55 | n | semmle.label | n | +| main.rs:368:9:368:10 | s1 [A] | semmle.label | s1 [A] | +| main.rs:368:14:368:26 | A(...) [A] | semmle.label | A(...) [A] | +| main.rs:368:16:368:25 | source(...) | semmle.label | source(...) | +| main.rs:370:11:370:12 | s1 [A] | semmle.label | s1 [A] | +| main.rs:371:9:371:12 | A(...) [A] | semmle.label | A(...) [A] | +| main.rs:371:11:371:11 | n | semmle.label | n | +| main.rs:371:22:371:22 | n | semmle.label | n | +| main.rs:374:11:374:12 | s1 [A] | semmle.label | s1 [A] | +| main.rs:375:9:375:12 | A(...) [A] | semmle.label | A(...) [A] | +| main.rs:375:11:375:11 | n | semmle.label | n | +| main.rs:375:29:375:29 | n | semmle.label | n | +| main.rs:389:9:389:10 | s1 [C] | semmle.label | s1 [C] | +| main.rs:389:14:391:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:390:18:390:27 | source(...) | semmle.label | source(...) | +| main.rs:393:11:393:12 | s1 [C] | semmle.label | s1 [C] | +| main.rs:394:9:394:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:394:36:394:36 | n | semmle.label | n | +| main.rs:394:48:394:48 | n | semmle.label | n | +| main.rs:397:11:397:12 | s1 [C] | semmle.label | s1 [C] | +| main.rs:398:9:398:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:398:36:398:36 | n | semmle.label | n | +| main.rs:398:81:398:81 | n | semmle.label | n | +| main.rs:409:9:409:10 | s1 [C] | semmle.label | s1 [C] | +| main.rs:409:14:411:5 | C {...} [C] | semmle.label | C {...} [C] | +| main.rs:410:18:410:27 | source(...) | semmle.label | source(...) | +| main.rs:413:11:413:12 | s1 [C] | semmle.label | s1 [C] | +| main.rs:414:9:414:24 | C {...} [C] | semmle.label | C {...} [C] | +| main.rs:414:22:414:22 | n | semmle.label | n | +| main.rs:414:34:414:34 | n | semmle.label | n | +| main.rs:417:11:417:12 | s1 [C] | semmle.label | s1 [C] | +| main.rs:418:9:418:24 | C {...} [C] | semmle.label | C {...} [C] | +| main.rs:418:22:418:22 | n | semmle.label | n | +| main.rs:418:53:418:53 | n | semmle.label | n | +| main.rs:430:9:430:12 | arr1 [element] | semmle.label | arr1 [element] | +| main.rs:430:16:430:33 | [...] [element] | semmle.label | [...] [element] | +| main.rs:430:23:430:32 | source(...) | semmle.label | source(...) | +| main.rs:431:9:431:10 | n1 | semmle.label | n1 | +| main.rs:431:14:431:17 | arr1 [element] | semmle.label | arr1 [element] | +| main.rs:431:14:431:20 | arr1[2] | semmle.label | arr1[2] | +| main.rs:432:10:432:11 | n1 | semmle.label | n1 | +| main.rs:434:9:434:12 | arr2 [element] | semmle.label | arr2 [element] | +| main.rs:434:16:434:31 | [...; 10] [element] | semmle.label | [...; 10] [element] | +| main.rs:434:17:434:26 | source(...) | semmle.label | source(...) | +| main.rs:435:9:435:10 | n2 | semmle.label | n2 | +| main.rs:435:14:435:17 | arr2 [element] | semmle.label | arr2 [element] | +| main.rs:435:14:435:20 | arr2[4] | semmle.label | arr2[4] | +| main.rs:436:10:436:11 | n2 | semmle.label | n2 | | main.rs:444:9:444:12 | arr1 [element] | semmle.label | arr1 [element] | | main.rs:444:16:444:33 | [...] [element] | semmle.label | [...] [element] | | main.rs:444:23:444:32 | source(...) | semmle.label | source(...) | -| main.rs:445:11:445:14 | arr1 [element] | semmle.label | arr1 [element] | -| main.rs:446:9:446:17 | SlicePat [element] | semmle.label | SlicePat [element] | -| main.rs:446:10:446:10 | a | semmle.label | a | -| main.rs:446:13:446:13 | b | semmle.label | b | -| main.rs:446:16:446:16 | c | semmle.label | c | -| main.rs:447:18:447:18 | a | semmle.label | a | -| main.rs:448:18:448:18 | b | semmle.label | b | -| main.rs:449:18:449:18 | c | semmle.label | c | -| main.rs:458:5:458:11 | [post] mut_arr [element] | semmle.label | [post] mut_arr [element] | -| main.rs:458:18:458:27 | source(...) | semmle.label | source(...) | -| main.rs:459:9:459:9 | d | semmle.label | d | -| main.rs:459:13:459:19 | mut_arr [element] | semmle.label | mut_arr [element] | -| main.rs:459:13:459:22 | mut_arr[1] | semmle.label | mut_arr[1] | -| main.rs:460:10:460:10 | d | semmle.label | d | -| main.rs:461:10:461:16 | mut_arr [element] | semmle.label | mut_arr [element] | -| main.rs:461:10:461:19 | mut_arr[0] | semmle.label | mut_arr[0] | -| main.rs:484:9:484:9 | s | semmle.label | s | -| main.rs:484:25:484:26 | source(...) | semmle.label | source(...) | -| main.rs:485:10:485:10 | s | semmle.label | s | -| main.rs:493:9:493:9 | a | semmle.label | a | -| main.rs:493:13:493:22 | source(...) | semmle.label | source(...) | -| main.rs:498:10:498:10 | a | semmle.label | a | -| main.rs:505:9:505:10 | vs [element] | semmle.label | vs [element] | -| main.rs:505:14:505:34 | [...] [element] | semmle.label | [...] [element] | -| main.rs:505:15:505:24 | source(...) | semmle.label | source(...) | -| main.rs:507:10:507:11 | vs [element] | semmle.label | vs [element] | -| main.rs:507:10:507:14 | vs[0] | semmle.label | vs[0] | -| main.rs:511:9:511:9 | v | semmle.label | v | -| main.rs:511:14:511:15 | vs [element] | semmle.label | vs [element] | -| main.rs:512:14:512:14 | v | semmle.label | v | -| main.rs:530:9:530:18 | mut vs_mut [element] | semmle.label | mut vs_mut [element] | -| main.rs:530:22:530:42 | [...] [element] | semmle.label | [...] [element] | -| main.rs:530:23:530:32 | source(...) | semmle.label | source(...) | -| main.rs:532:10:532:15 | vs_mut [element] | semmle.label | vs_mut [element] | -| main.rs:532:10:532:18 | vs_mut[0] | semmle.label | vs_mut[0] | -| main.rs:542:9:542:9 | a | semmle.label | a | -| main.rs:542:13:542:22 | source(...) | semmle.label | source(...) | -| main.rs:544:9:544:9 | c | semmle.label | c | -| main.rs:544:13:544:22 | source(...) | semmle.label | source(...) | -| main.rs:545:9:545:13 | c_ref [&ref] | semmle.label | c_ref [&ref] | -| main.rs:545:17:545:18 | &c [&ref] | semmle.label | &c [&ref] | -| main.rs:545:18:545:18 | c | semmle.label | c | -| main.rs:547:10:547:10 | a | semmle.label | a | -| main.rs:550:10:550:15 | * ... | semmle.label | * ... | -| main.rs:550:11:550:15 | c_ref [&ref] | semmle.label | c_ref [&ref] | +| main.rs:445:9:445:10 | n1 | semmle.label | n1 | +| main.rs:445:15:445:18 | arr1 [element] | semmle.label | arr1 [element] | +| main.rs:446:14:446:15 | n1 | semmle.label | n1 | +| main.rs:456:9:456:12 | arr1 [element] | semmle.label | arr1 [element] | +| main.rs:456:16:456:33 | [...] [element] | semmle.label | [...] [element] | +| main.rs:456:23:456:32 | source(...) | semmle.label | source(...) | +| main.rs:457:11:457:14 | arr1 [element] | semmle.label | arr1 [element] | +| main.rs:458:9:458:17 | SlicePat [element] | semmle.label | SlicePat [element] | +| main.rs:458:10:458:10 | a | semmle.label | a | +| main.rs:458:13:458:13 | b | semmle.label | b | +| main.rs:458:16:458:16 | c | semmle.label | c | +| main.rs:459:18:459:18 | a | semmle.label | a | +| main.rs:460:18:460:18 | b | semmle.label | b | +| main.rs:461:18:461:18 | c | semmle.label | c | +| main.rs:470:5:470:11 | [post] mut_arr [element] | semmle.label | [post] mut_arr [element] | +| main.rs:470:18:470:27 | source(...) | semmle.label | source(...) | +| main.rs:471:9:471:9 | d | semmle.label | d | +| main.rs:471:13:471:19 | mut_arr [element] | semmle.label | mut_arr [element] | +| main.rs:471:13:471:22 | mut_arr[1] | semmle.label | mut_arr[1] | +| main.rs:472:10:472:10 | d | semmle.label | d | +| main.rs:473:10:473:16 | mut_arr [element] | semmle.label | mut_arr [element] | +| main.rs:473:10:473:19 | mut_arr[0] | semmle.label | mut_arr[0] | +| main.rs:496:9:496:9 | s | semmle.label | s | +| main.rs:496:25:496:26 | source(...) | semmle.label | source(...) | +| main.rs:497:10:497:10 | s | semmle.label | s | +| main.rs:505:9:505:9 | a | semmle.label | a | +| main.rs:505:13:505:22 | source(...) | semmle.label | source(...) | +| main.rs:510:10:510:10 | a | semmle.label | a | +| main.rs:517:9:517:10 | vs [element] | semmle.label | vs [element] | +| main.rs:517:14:517:34 | [...] [element] | semmle.label | [...] [element] | +| main.rs:517:15:517:24 | source(...) | semmle.label | source(...) | +| main.rs:519:10:519:11 | vs [element] | semmle.label | vs [element] | +| main.rs:519:10:519:14 | vs[0] | semmle.label | vs[0] | +| main.rs:523:9:523:9 | v | semmle.label | v | +| main.rs:523:14:523:15 | vs [element] | semmle.label | vs [element] | +| main.rs:524:14:524:14 | v | semmle.label | v | +| main.rs:542:9:542:18 | mut vs_mut [element] | semmle.label | mut vs_mut [element] | +| main.rs:542:22:542:42 | [...] [element] | semmle.label | [...] [element] | +| main.rs:542:23:542:32 | source(...) | semmle.label | source(...) | +| main.rs:544:10:544:15 | vs_mut [element] | semmle.label | vs_mut [element] | +| main.rs:544:10:544:18 | vs_mut[0] | semmle.label | vs_mut[0] | +| main.rs:554:9:554:9 | a | semmle.label | a | +| main.rs:554:13:554:22 | source(...) | semmle.label | source(...) | +| main.rs:556:9:556:9 | c | semmle.label | c | +| main.rs:556:13:556:22 | source(...) | semmle.label | source(...) | +| main.rs:557:9:557:13 | c_ref [&ref] | semmle.label | c_ref [&ref] | +| main.rs:557:17:557:18 | &c [&ref] | semmle.label | &c [&ref] | +| main.rs:557:18:557:18 | c | semmle.label | c | +| main.rs:559:10:559:10 | a | semmle.label | a | +| main.rs:562:10:562:15 | * ... | semmle.label | * ... | +| main.rs:562:11:562:15 | c_ref [&ref] | semmle.label | c_ref [&ref] | subpaths testFailures #select @@ -542,54 +551,56 @@ testFailures | main.rs:53:10:53:10 | b | main.rs:48:13:48:21 | source(...) | main.rs:53:10:53:10 | b | $@ | main.rs:48:13:48:21 | source(...) | source(...) | | main.rs:64:10:64:10 | b | main.rs:62:15:62:23 | source(...) | main.rs:64:10:64:10 | b | $@ | main.rs:62:15:62:23 | source(...) | source(...) | | main.rs:71:10:71:10 | i | main.rs:70:9:70:17 | source(...) | main.rs:71:10:71:10 | i | $@ | main.rs:70:9:70:17 | source(...) | source(...) | -| main.rs:104:10:104:11 | * ... | main.rs:103:22:103:30 | source(...) | main.rs:104:10:104:11 | * ... | $@ | main.rs:103:22:103:30 | source(...) | source(...) | -| main.rs:112:10:112:12 | a.0 | main.rs:111:14:111:22 | source(...) | main.rs:112:10:112:12 | a.0 | $@ | main.rs:111:14:111:22 | source(...) | source(...) | -| main.rs:120:10:120:11 | a1 | main.rs:117:17:117:26 | source(...) | main.rs:120:10:120:11 | a1 | $@ | main.rs:117:17:117:26 | source(...) | source(...) | -| main.rs:127:10:127:12 | a.1 | main.rs:125:21:125:30 | source(...) | main.rs:127:10:127:12 | a.1 | $@ | main.rs:125:21:125:30 | source(...) | source(...) | -| main.rs:130:10:130:12 | a.0 | main.rs:128:11:128:20 | source(...) | main.rs:130:10:130:12 | a.0 | $@ | main.rs:128:11:128:20 | source(...) | source(...) | -| main.rs:138:10:138:15 | ... .1 | main.rs:135:17:135:26 | source(...) | main.rs:138:10:138:15 | ... .1 | $@ | main.rs:135:17:135:26 | source(...) | source(...) | -| main.rs:152:10:152:12 | p.x | main.rs:151:24:151:32 | source(...) | main.rs:152:10:152:12 | p.x | $@ | main.rs:151:24:151:32 | source(...) | source(...) | -| main.rs:160:10:160:12 | p.y | main.rs:159:11:159:20 | source(...) | main.rs:160:10:160:12 | p.y | $@ | main.rs:159:11:159:20 | source(...) | source(...) | -| main.rs:169:10:169:10 | a | main.rs:165:12:165:21 | source(...) | main.rs:169:10:169:10 | a | $@ | main.rs:165:12:165:21 | source(...) | source(...) | -| main.rs:187:10:187:18 | ... .y | main.rs:182:16:182:25 | source(...) | main.rs:187:10:187:18 | ... .y | $@ | main.rs:182:16:182:25 | source(...) | source(...) | -| main.rs:203:18:203:18 | y | main.rs:192:13:192:22 | source(...) | main.rs:203:18:203:18 | y | $@ | main.rs:192:13:192:22 | source(...) | source(...) | -| main.rs:213:10:213:12 | s.0 | main.rs:212:27:212:36 | source(...) | main.rs:213:10:213:12 | s.0 | $@ | main.rs:212:27:212:36 | source(...) | source(...) | -| main.rs:218:18:218:18 | x | main.rs:212:27:212:36 | source(...) | main.rs:218:18:218:18 | x | $@ | main.rs:212:27:212:36 | source(...) | source(...) | -| main.rs:231:33:231:33 | n | main.rs:228:27:228:36 | source(...) | main.rs:231:33:231:33 | n | $@ | main.rs:228:27:228:36 | source(...) | source(...) | -| main.rs:244:25:244:25 | n | main.rs:241:19:241:28 | source(...) | main.rs:244:25:244:25 | n | $@ | main.rs:241:19:241:28 | source(...) | source(...) | -| main.rs:257:18:257:18 | n | main.rs:254:19:254:28 | source(...) | main.rs:257:18:257:18 | n | $@ | main.rs:254:19:254:28 | source(...) | source(...) | -| main.rs:261:14:261:14 | n | main.rs:254:19:254:28 | source(...) | main.rs:261:14:261:14 | n | $@ | main.rs:254:19:254:28 | source(...) | source(...) | -| main.rs:267:10:267:20 | s1.unwrap() | main.rs:266:19:266:28 | source(...) | main.rs:267:10:267:20 | s1.unwrap() | $@ | main.rs:266:19:266:28 | source(...) | source(...) | -| main.rs:272:10:272:24 | s1.unwrap_or(...) | main.rs:271:19:271:28 | source(...) | main.rs:272:10:272:24 | s1.unwrap_or(...) | $@ | main.rs:271:19:271:28 | source(...) | source(...) | -| main.rs:275:10:275:33 | s2.unwrap_or(...) | main.rs:275:23:275:32 | source(...) | main.rs:275:10:275:33 | s2.unwrap_or(...) | $@ | main.rs:275:23:275:32 | source(...) | source(...) | -| main.rs:280:10:280:32 | s1.unwrap_or_else(...) | main.rs:279:19:279:28 | source(...) | main.rs:280:10:280:32 | s1.unwrap_or_else(...) | $@ | main.rs:279:19:279:28 | source(...) | source(...) | -| main.rs:283:10:283:41 | s2.unwrap_or_else(...) | main.rs:283:31:283:40 | source(...) | main.rs:283:10:283:41 | s2.unwrap_or_else(...) | $@ | main.rs:283:31:283:40 | source(...) | source(...) | -| main.rs:290:10:290:11 | i1 | main.rs:287:19:287:28 | source(...) | main.rs:290:10:290:11 | i1 | $@ | main.rs:287:19:287:28 | source(...) | source(...) | -| main.rs:299:10:299:21 | o1a.unwrap() | main.rs:296:35:296:44 | source(...) | main.rs:299:10:299:21 | o1a.unwrap() | $@ | main.rs:296:35:296:44 | source(...) | source(...) | -| main.rs:306:10:306:21 | o2b.unwrap() | main.rs:302:36:302:45 | source(...) | main.rs:306:10:306:21 | o2b.unwrap() | $@ | main.rs:302:36:302:45 | source(...) | source(...) | -| main.rs:315:10:315:11 | i1 | main.rs:310:35:310:44 | source(...) | main.rs:315:10:315:11 | i1 | $@ | main.rs:310:35:310:44 | source(...) | source(...) | -| main.rs:324:10:324:22 | s1.expect(...) | main.rs:323:35:323:44 | source(...) | main.rs:324:10:324:22 | s1.expect(...) | $@ | main.rs:323:35:323:44 | source(...) | source(...) | -| main.rs:329:10:329:26 | s2.expect_err(...) | main.rs:327:36:327:45 | source(...) | main.rs:329:10:329:26 | s2.expect_err(...) | $@ | main.rs:327:36:327:45 | source(...) | source(...) | -| main.rs:341:35:341:35 | n | main.rs:338:29:338:38 | source(...) | main.rs:341:35:341:35 | n | $@ | main.rs:338:29:338:38 | source(...) | source(...) | -| main.rs:345:55:345:55 | n | main.rs:338:29:338:38 | source(...) | main.rs:345:55:345:55 | n | $@ | main.rs:338:29:338:38 | source(...) | source(...) | -| main.rs:359:22:359:22 | n | main.rs:356:16:356:25 | source(...) | main.rs:359:22:359:22 | n | $@ | main.rs:356:16:356:25 | source(...) | source(...) | -| main.rs:363:29:363:29 | n | main.rs:356:16:356:25 | source(...) | main.rs:363:29:363:29 | n | $@ | main.rs:356:16:356:25 | source(...) | source(...) | -| main.rs:382:48:382:48 | n | main.rs:378:18:378:27 | source(...) | main.rs:382:48:382:48 | n | $@ | main.rs:378:18:378:27 | source(...) | source(...) | -| main.rs:386:81:386:81 | n | main.rs:378:18:378:27 | source(...) | main.rs:386:81:386:81 | n | $@ | main.rs:378:18:378:27 | source(...) | source(...) | -| main.rs:402:34:402:34 | n | main.rs:398:18:398:27 | source(...) | main.rs:402:34:402:34 | n | $@ | main.rs:398:18:398:27 | source(...) | source(...) | -| main.rs:406:53:406:53 | n | main.rs:398:18:398:27 | source(...) | main.rs:406:53:406:53 | n | $@ | main.rs:398:18:398:27 | source(...) | source(...) | -| main.rs:420:10:420:11 | n1 | main.rs:418:23:418:32 | source(...) | main.rs:420:10:420:11 | n1 | $@ | main.rs:418:23:418:32 | source(...) | source(...) | -| main.rs:424:10:424:11 | n2 | main.rs:422:17:422:26 | source(...) | main.rs:424:10:424:11 | n2 | $@ | main.rs:422:17:422:26 | source(...) | source(...) | -| main.rs:434:14:434:15 | n1 | main.rs:432:23:432:32 | source(...) | main.rs:434:14:434:15 | n1 | $@ | main.rs:432:23:432:32 | source(...) | source(...) | -| main.rs:447:18:447:18 | a | main.rs:444:23:444:32 | source(...) | main.rs:447:18:447:18 | a | $@ | main.rs:444:23:444:32 | source(...) | source(...) | -| main.rs:448:18:448:18 | b | main.rs:444:23:444:32 | source(...) | main.rs:448:18:448:18 | b | $@ | main.rs:444:23:444:32 | source(...) | source(...) | -| main.rs:449:18:449:18 | c | main.rs:444:23:444:32 | source(...) | main.rs:449:18:449:18 | c | $@ | main.rs:444:23:444:32 | source(...) | source(...) | -| main.rs:460:10:460:10 | d | main.rs:458:18:458:27 | source(...) | main.rs:460:10:460:10 | d | $@ | main.rs:458:18:458:27 | source(...) | source(...) | -| main.rs:461:10:461:19 | mut_arr[0] | main.rs:458:18:458:27 | source(...) | main.rs:461:10:461:19 | mut_arr[0] | $@ | main.rs:458:18:458:27 | source(...) | source(...) | -| main.rs:485:10:485:10 | s | main.rs:484:25:484:26 | source(...) | main.rs:485:10:485:10 | s | $@ | main.rs:484:25:484:26 | source(...) | source(...) | -| main.rs:498:10:498:10 | a | main.rs:493:13:493:22 | source(...) | main.rs:498:10:498:10 | a | $@ | main.rs:493:13:493:22 | source(...) | source(...) | -| main.rs:507:10:507:14 | vs[0] | main.rs:505:15:505:24 | source(...) | main.rs:507:10:507:14 | vs[0] | $@ | main.rs:505:15:505:24 | source(...) | source(...) | -| main.rs:512:14:512:14 | v | main.rs:505:15:505:24 | source(...) | main.rs:512:14:512:14 | v | $@ | main.rs:505:15:505:24 | source(...) | source(...) | -| main.rs:532:10:532:18 | vs_mut[0] | main.rs:530:23:530:32 | source(...) | main.rs:532:10:532:18 | vs_mut[0] | $@ | main.rs:530:23:530:32 | source(...) | source(...) | -| main.rs:547:10:547:10 | a | main.rs:542:13:542:22 | source(...) | main.rs:547:10:547:10 | a | $@ | main.rs:542:13:542:22 | source(...) | source(...) | -| main.rs:550:10:550:15 | * ... | main.rs:544:13:544:22 | source(...) | main.rs:550:10:550:15 | * ... | $@ | main.rs:544:13:544:22 | source(...) | source(...) | +| main.rs:78:10:78:10 | j | main.rs:76:13:76:21 | source(...) | main.rs:78:10:78:10 | j | $@ | main.rs:76:13:76:21 | source(...) | source(...) | +| main.rs:79:10:79:10 | k | main.rs:76:13:76:21 | source(...) | main.rs:79:10:79:10 | k | $@ | main.rs:76:13:76:21 | source(...) | source(...) | +| main.rs:116:10:116:11 | * ... | main.rs:115:22:115:30 | source(...) | main.rs:116:10:116:11 | * ... | $@ | main.rs:115:22:115:30 | source(...) | source(...) | +| main.rs:124:10:124:12 | a.0 | main.rs:123:14:123:22 | source(...) | main.rs:124:10:124:12 | a.0 | $@ | main.rs:123:14:123:22 | source(...) | source(...) | +| main.rs:132:10:132:11 | a1 | main.rs:129:17:129:26 | source(...) | main.rs:132:10:132:11 | a1 | $@ | main.rs:129:17:129:26 | source(...) | source(...) | +| main.rs:139:10:139:12 | a.1 | main.rs:137:21:137:30 | source(...) | main.rs:139:10:139:12 | a.1 | $@ | main.rs:137:21:137:30 | source(...) | source(...) | +| main.rs:142:10:142:12 | a.0 | main.rs:140:11:140:20 | source(...) | main.rs:142:10:142:12 | a.0 | $@ | main.rs:140:11:140:20 | source(...) | source(...) | +| main.rs:150:10:150:15 | ... .1 | main.rs:147:17:147:26 | source(...) | main.rs:150:10:150:15 | ... .1 | $@ | main.rs:147:17:147:26 | source(...) | source(...) | +| main.rs:164:10:164:12 | p.x | main.rs:163:24:163:32 | source(...) | main.rs:164:10:164:12 | p.x | $@ | main.rs:163:24:163:32 | source(...) | source(...) | +| main.rs:172:10:172:12 | p.y | main.rs:171:11:171:20 | source(...) | main.rs:172:10:172:12 | p.y | $@ | main.rs:171:11:171:20 | source(...) | source(...) | +| main.rs:181:10:181:10 | a | main.rs:177:12:177:21 | source(...) | main.rs:181:10:181:10 | a | $@ | main.rs:177:12:177:21 | source(...) | source(...) | +| main.rs:199:10:199:18 | ... .y | main.rs:194:16:194:25 | source(...) | main.rs:199:10:199:18 | ... .y | $@ | main.rs:194:16:194:25 | source(...) | source(...) | +| main.rs:215:18:215:18 | y | main.rs:204:13:204:22 | source(...) | main.rs:215:18:215:18 | y | $@ | main.rs:204:13:204:22 | source(...) | source(...) | +| main.rs:225:10:225:12 | s.0 | main.rs:224:27:224:36 | source(...) | main.rs:225:10:225:12 | s.0 | $@ | main.rs:224:27:224:36 | source(...) | source(...) | +| main.rs:230:18:230:18 | x | main.rs:224:27:224:36 | source(...) | main.rs:230:18:230:18 | x | $@ | main.rs:224:27:224:36 | source(...) | source(...) | +| main.rs:243:33:243:33 | n | main.rs:240:27:240:36 | source(...) | main.rs:243:33:243:33 | n | $@ | main.rs:240:27:240:36 | source(...) | source(...) | +| main.rs:256:25:256:25 | n | main.rs:253:19:253:28 | source(...) | main.rs:256:25:256:25 | n | $@ | main.rs:253:19:253:28 | source(...) | source(...) | +| main.rs:269:18:269:18 | n | main.rs:266:19:266:28 | source(...) | main.rs:269:18:269:18 | n | $@ | main.rs:266:19:266:28 | source(...) | source(...) | +| main.rs:273:14:273:14 | n | main.rs:266:19:266:28 | source(...) | main.rs:273:14:273:14 | n | $@ | main.rs:266:19:266:28 | source(...) | source(...) | +| main.rs:279:10:279:20 | s1.unwrap() | main.rs:278:19:278:28 | source(...) | main.rs:279:10:279:20 | s1.unwrap() | $@ | main.rs:278:19:278:28 | source(...) | source(...) | +| main.rs:284:10:284:24 | s1.unwrap_or(...) | main.rs:283:19:283:28 | source(...) | main.rs:284:10:284:24 | s1.unwrap_or(...) | $@ | main.rs:283:19:283:28 | source(...) | source(...) | +| main.rs:287:10:287:33 | s2.unwrap_or(...) | main.rs:287:23:287:32 | source(...) | main.rs:287:10:287:33 | s2.unwrap_or(...) | $@ | main.rs:287:23:287:32 | source(...) | source(...) | +| main.rs:292:10:292:32 | s1.unwrap_or_else(...) | main.rs:291:19:291:28 | source(...) | main.rs:292:10:292:32 | s1.unwrap_or_else(...) | $@ | main.rs:291:19:291:28 | source(...) | source(...) | +| main.rs:295:10:295:41 | s2.unwrap_or_else(...) | main.rs:295:31:295:40 | source(...) | main.rs:295:10:295:41 | s2.unwrap_or_else(...) | $@ | main.rs:295:31:295:40 | source(...) | source(...) | +| main.rs:302:10:302:11 | i1 | main.rs:299:19:299:28 | source(...) | main.rs:302:10:302:11 | i1 | $@ | main.rs:299:19:299:28 | source(...) | source(...) | +| main.rs:311:10:311:21 | o1a.unwrap() | main.rs:308:35:308:44 | source(...) | main.rs:311:10:311:21 | o1a.unwrap() | $@ | main.rs:308:35:308:44 | source(...) | source(...) | +| main.rs:318:10:318:21 | o2b.unwrap() | main.rs:314:36:314:45 | source(...) | main.rs:318:10:318:21 | o2b.unwrap() | $@ | main.rs:314:36:314:45 | source(...) | source(...) | +| main.rs:327:10:327:11 | i1 | main.rs:322:35:322:44 | source(...) | main.rs:327:10:327:11 | i1 | $@ | main.rs:322:35:322:44 | source(...) | source(...) | +| main.rs:336:10:336:22 | s1.expect(...) | main.rs:335:35:335:44 | source(...) | main.rs:336:10:336:22 | s1.expect(...) | $@ | main.rs:335:35:335:44 | source(...) | source(...) | +| main.rs:341:10:341:26 | s2.expect_err(...) | main.rs:339:36:339:45 | source(...) | main.rs:341:10:341:26 | s2.expect_err(...) | $@ | main.rs:339:36:339:45 | source(...) | source(...) | +| main.rs:353:35:353:35 | n | main.rs:350:29:350:38 | source(...) | main.rs:353:35:353:35 | n | $@ | main.rs:350:29:350:38 | source(...) | source(...) | +| main.rs:357:55:357:55 | n | main.rs:350:29:350:38 | source(...) | main.rs:357:55:357:55 | n | $@ | main.rs:350:29:350:38 | source(...) | source(...) | +| main.rs:371:22:371:22 | n | main.rs:368:16:368:25 | source(...) | main.rs:371:22:371:22 | n | $@ | main.rs:368:16:368:25 | source(...) | source(...) | +| main.rs:375:29:375:29 | n | main.rs:368:16:368:25 | source(...) | main.rs:375:29:375:29 | n | $@ | main.rs:368:16:368:25 | source(...) | source(...) | +| main.rs:394:48:394:48 | n | main.rs:390:18:390:27 | source(...) | main.rs:394:48:394:48 | n | $@ | main.rs:390:18:390:27 | source(...) | source(...) | +| main.rs:398:81:398:81 | n | main.rs:390:18:390:27 | source(...) | main.rs:398:81:398:81 | n | $@ | main.rs:390:18:390:27 | source(...) | source(...) | +| main.rs:414:34:414:34 | n | main.rs:410:18:410:27 | source(...) | main.rs:414:34:414:34 | n | $@ | main.rs:410:18:410:27 | source(...) | source(...) | +| main.rs:418:53:418:53 | n | main.rs:410:18:410:27 | source(...) | main.rs:418:53:418:53 | n | $@ | main.rs:410:18:410:27 | source(...) | source(...) | +| main.rs:432:10:432:11 | n1 | main.rs:430:23:430:32 | source(...) | main.rs:432:10:432:11 | n1 | $@ | main.rs:430:23:430:32 | source(...) | source(...) | +| main.rs:436:10:436:11 | n2 | main.rs:434:17:434:26 | source(...) | main.rs:436:10:436:11 | n2 | $@ | main.rs:434:17:434:26 | source(...) | source(...) | +| main.rs:446:14:446:15 | n1 | main.rs:444:23:444:32 | source(...) | main.rs:446:14:446:15 | n1 | $@ | main.rs:444:23:444:32 | source(...) | source(...) | +| main.rs:459:18:459:18 | a | main.rs:456:23:456:32 | source(...) | main.rs:459:18:459:18 | a | $@ | main.rs:456:23:456:32 | source(...) | source(...) | +| main.rs:460:18:460:18 | b | main.rs:456:23:456:32 | source(...) | main.rs:460:18:460:18 | b | $@ | main.rs:456:23:456:32 | source(...) | source(...) | +| main.rs:461:18:461:18 | c | main.rs:456:23:456:32 | source(...) | main.rs:461:18:461:18 | c | $@ | main.rs:456:23:456:32 | source(...) | source(...) | +| main.rs:472:10:472:10 | d | main.rs:470:18:470:27 | source(...) | main.rs:472:10:472:10 | d | $@ | main.rs:470:18:470:27 | source(...) | source(...) | +| main.rs:473:10:473:19 | mut_arr[0] | main.rs:470:18:470:27 | source(...) | main.rs:473:10:473:19 | mut_arr[0] | $@ | main.rs:470:18:470:27 | source(...) | source(...) | +| main.rs:497:10:497:10 | s | main.rs:496:25:496:26 | source(...) | main.rs:497:10:497:10 | s | $@ | main.rs:496:25:496:26 | source(...) | source(...) | +| main.rs:510:10:510:10 | a | main.rs:505:13:505:22 | source(...) | main.rs:510:10:510:10 | a | $@ | main.rs:505:13:505:22 | source(...) | source(...) | +| main.rs:519:10:519:14 | vs[0] | main.rs:517:15:517:24 | source(...) | main.rs:519:10:519:14 | vs[0] | $@ | main.rs:517:15:517:24 | source(...) | source(...) | +| main.rs:524:14:524:14 | v | main.rs:517:15:517:24 | source(...) | main.rs:524:14:524:14 | v | $@ | main.rs:517:15:517:24 | source(...) | source(...) | +| main.rs:544:10:544:18 | vs_mut[0] | main.rs:542:23:542:32 | source(...) | main.rs:544:10:544:18 | vs_mut[0] | $@ | main.rs:542:23:542:32 | source(...) | source(...) | +| main.rs:559:10:559:10 | a | main.rs:554:13:554:22 | source(...) | main.rs:559:10:559:10 | a | $@ | main.rs:554:13:554:22 | source(...) | source(...) | +| main.rs:562:10:562:15 | * ... | main.rs:556:13:556:22 | source(...) | main.rs:562:10:562:15 | * ... | $@ | main.rs:556:13:556:22 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index 598aed6777f..d352eb0cbf1 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -69,6 +69,18 @@ fn assignment() { sink(i); i = source(6); sink(i); // $ hasValueFlow=6 + i = 2; + sink(i); + + let mut j = 3; + let k = source(7); + j = k; + sink(j); // $ hasValueFlow=7 + sink(k); // $ hasValueFlow=7 + + let mut l = source(8); + l = l; + sink(l); // $ MISSING: hasValueFlow=8 } fn block_expression1() -> i64 { From a8d4d6b5630f7bd4804c51aefd8b0f84ef00ffe1 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Mon, 15 Sep 2025 22:02:03 -0400 Subject: [PATCH 015/160] Apply naming standards + changenote --- .../2025-09-15-grape-framework-support.md | 4 ++ ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 44 +++++++++---------- .../frameworks/grape/Grape.expected | 2 +- .../library-tests/frameworks/grape/Grape.ql | 4 +- 4 files changed, 29 insertions(+), 25 deletions(-) create mode 100644 ruby/ql/lib/change-notes/2025-09-15-grape-framework-support.md diff --git a/ruby/ql/lib/change-notes/2025-09-15-grape-framework-support.md b/ruby/ql/lib/change-notes/2025-09-15-grape-framework-support.md new file mode 100644 index 00000000000..258da40d36c --- /dev/null +++ b/ruby/ql/lib/change-notes/2025-09-15-grape-framework-support.md @@ -0,0 +1,4 @@ +--- +category: feature +--- +* Initial modeling for the Ruby Grape framework in `Grape.qll` have been added to detect API endpoints, parameters, and headers within Grape API classes. \ No newline at end of file diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index fbab28180b8..72dd1e13b9b 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -23,9 +23,9 @@ module Grape { * A Grape API class which sits at the top of the class hierarchy. * In other words, it does not subclass any other Grape API class in source code. */ - class RootAPI extends GrapeAPIClass { - RootAPI() { - not exists(GrapeAPIClass parent | this != parent and this = parent.getADescendent()) + class RootApi extends GrapeApiClass { + RootApi() { + not exists(GrapeApiClass parent | this != parent and this = parent.getADescendent()) } } } @@ -43,17 +43,17 @@ module Grape { * end * ``` */ -class GrapeAPIClass extends DataFlow::ClassNode { - GrapeAPIClass() { - this = grapeAPIBaseClass().getADescendentModule() and - not exists(DataFlow::ModuleNode m | m = grapeAPIBaseClass().asModule() | this = m) +class GrapeApiClass extends DataFlow::ClassNode { + GrapeApiClass() { + this = grapeApiBaseClass().getADescendentModule() and + not exists(DataFlow::ModuleNode m | m = grapeApiBaseClass().asModule() | this = m) } /** * Gets a `GrapeEndpoint` defined in this class. */ GrapeEndpoint getAnEndpoint() { - result.getAPIClass() = this + result.getApiClass() = this } /** @@ -68,19 +68,19 @@ class GrapeAPIClass extends DataFlow::ClassNode { } } -private DataFlow::ConstRef grapeAPIBaseClass() { +private DataFlow::ConstRef grapeApiBaseClass() { result = DataFlow::getConstant("Grape").getConstant("API") } -private API::Node grapeAPIInstance() { - result = any(GrapeAPIClass cls).getSelf().track() +private API::Node grapeApiInstance() { + result = any(GrapeApiClass cls).getSelf().track() } /** * A Grape API endpoint (get, post, put, delete, etc.) call within a `Grape::API` class. */ class GrapeEndpoint extends DataFlow::CallNode { - private GrapeAPIClass apiClass; + private GrapeApiClass apiClass; GrapeEndpoint() { this = apiClass.getAModuleLevelCall(["get", "post", "put", "delete", "patch", "head", "options"]) @@ -96,7 +96,7 @@ class GrapeEndpoint extends DataFlow::CallNode { /** * Gets the API class containing this endpoint. */ - GrapeAPIClass getAPIClass() { result = apiClass } + GrapeApiClass getApiClass() { result = apiClass } /** * Gets the block containing the endpoint logic. @@ -131,7 +131,7 @@ class GrapeParamsSource extends Http::Server::RequestInputAccess::Range { private class GrapeParamsCall extends ParamsCallImpl { GrapeParamsCall() { // Simplified approach: find params calls that are descendants of Grape API class methods - exists(GrapeAPIClass api | + exists(GrapeApiClass api | this.getMethodName() = "params" and this.getParent+() = api.getADeclaration() ) @@ -163,7 +163,7 @@ private class GrapeHeadersCall extends MethodCall { ) or // Also handle cases where headers is called on an instance of a Grape API class - this = grapeAPIInstance().getAMethodCall("headers").asExpr().getExpr() + this = grapeApiInstance().getAMethodCall("headers").asExpr().getExpr() } } @@ -206,7 +206,7 @@ private class GrapeRequestCall extends MethodCall { ) or // Also handle cases where request is called on an instance of a Grape API class - this = grapeAPIInstance().getAMethodCall("request").asExpr().getExpr() + this = grapeApiInstance().getAMethodCall("request").asExpr().getExpr() } } @@ -221,7 +221,7 @@ private class GrapeRouteParamCall extends MethodCall { ) or // Also handle cases where route_param is called on an instance of a Grape API class - this = grapeAPIInstance().getAMethodCall("route_param").asExpr().getExpr() + this = grapeApiInstance().getAMethodCall("route_param").asExpr().getExpr() } } @@ -231,7 +231,7 @@ private class GrapeRouteParamCall extends MethodCall { */ private class GrapeHeadersBlockCall extends MethodCall { GrapeHeadersBlockCall() { - exists(GrapeAPIClass api | + exists(GrapeApiClass api | this.getParent+() = api.getADeclaration() and this.getMethodName() = "headers" and exists(this.getBlock()) @@ -245,7 +245,7 @@ private class GrapeHeadersBlockCall extends MethodCall { */ private class GrapeCookiesBlockCall extends MethodCall { GrapeCookiesBlockCall() { - exists(GrapeAPIClass api | + exists(GrapeApiClass api | this.getParent+() = api.getADeclaration() and this.getMethodName() = "cookies" and exists(this.getBlock()) @@ -280,7 +280,7 @@ private class GrapeCookiesCall extends MethodCall { ) or // Also handle cases where cookies is called on an instance of a Grape API class - this = grapeAPIInstance().getAMethodCall("cookies").asExpr().getExpr() + this = grapeApiInstance().getAMethodCall("cookies").asExpr().getExpr() } } @@ -289,7 +289,7 @@ private class GrapeCookiesCall extends MethodCall { * These methods become available in endpoint contexts through Grape's DSL. */ private class GrapeHelperMethod extends Method { - private GrapeAPIClass apiClass; + private GrapeApiClass apiClass; GrapeHelperMethod() { exists(DataFlow::CallNode helpersCall | @@ -301,7 +301,7 @@ private class GrapeHelperMethod extends Method { /** * Gets the API class that contains this helper method. */ - GrapeAPIClass getAPIClass() { result = apiClass } + GrapeApiClass getAPIClass() { result = apiClass } } /** diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.expected b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected index c0bee75371c..af4d936e88d 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Grape.expected +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected @@ -1,4 +1,4 @@ -grapeAPIClasses +grapeApiClasses | app.rb:1:1:90:3 | MyAPI | | app.rb:92:1:96:3 | AdminAPI | grapeEndpoints diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql index 63d59d0bdd7..ebfb304dbe7 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql @@ -3,9 +3,9 @@ import codeql.ruby.frameworks.Grape import codeql.ruby.Concepts import codeql.ruby.AST -query predicate grapeAPIClasses(GrapeAPIClass api) { any() } +query predicate grapeApiClasses(GrapeApiClass api) { any() } -query predicate grapeEndpoints(GrapeAPIClass api, GrapeEndpoint endpoint, string method, string path) { +query predicate grapeEndpoints(GrapeApiClass api, GrapeEndpoint endpoint, string method, string path) { endpoint = api.getAnEndpoint() and method = endpoint.getHttpMethod() and path = endpoint.getPath() From 19cb1874368723b7441b01bb07d6aaf16f8c009d Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Mon, 15 Sep 2025 22:03:27 -0400 Subject: [PATCH 016/160] Update ruby/ql/lib/codeql/ruby/frameworks/Grape.qll Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index 72dd1e13b9b..417d4ee4da4 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -136,7 +136,9 @@ private class GrapeParamsCall extends ParamsCallImpl { this.getParent+() = api.getADeclaration() ) } -}/** +} + +/** * A call to `headers` from within a Grape API endpoint or headers block. * Headers can also be a source of user input. */ From fc98cd8d08e9f1d258611757094f73b00095963e Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Mon, 15 Sep 2025 22:11:33 -0400 Subject: [PATCH 017/160] Fix naming standards --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index 72dd1e13b9b..7b963c92ee1 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -301,7 +301,7 @@ private class GrapeHelperMethod extends Method { /** * Gets the API class that contains this helper method. */ - GrapeApiClass getAPIClass() { result = apiClass } + GrapeApiClass getApiClass() { result = apiClass } } /** From 49de716f10ab1d9e0ec7155363edc5e9e23405f5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 16 Sep 2025 10:50:28 +0100 Subject: [PATCH 018/160] Rust: Accept consistency check changes. --- .../local/CONSISTENCY/PathResolutionConsistency.expected | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/test/library-tests/dataflow/local/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/library-tests/dataflow/local/CONSISTENCY/PathResolutionConsistency.expected index f5f63c61593..cbf6523d21c 100644 --- a/rust/ql/test/library-tests/dataflow/local/CONSISTENCY/PathResolutionConsistency.expected +++ b/rust/ql/test/library-tests/dataflow/local/CONSISTENCY/PathResolutionConsistency.expected @@ -1,2 +1,2 @@ multipleCallTargets -| main.rs:471:18:471:24 | n.len() | +| main.rs:483:18:483:24 | n.len() | From 7b04cf1a73ddb561738e31ba5b31348ced20c626 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 16 Sep 2025 12:15:44 +0100 Subject: [PATCH 019/160] Rust: Fix up the test annotations. --- .../security/CWE-319/UseOfHttp.expected | 10 ------- .../test/query-tests/security/CWE-319/main.rs | 30 +++++++++---------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected index 53cc8606cc8..f2a2e7e05f4 100644 --- a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected +++ b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected @@ -66,13 +66,3 @@ nodes | main.rs:60:21:60:42 | ...::get | semmle.label | ...::get | | main.rs:60:44:60:46 | url | semmle.label | url | subpaths -testFailures -| main.rs:22:20:22:39 | "http://example.com" | Unexpected result: Source | -| main.rs:22:42:22:71 | //... | Missing result: Alert[rust/non-https-url] | -| main.rs:25:21:25:42 | ...::get | Unexpected result: Alert | -| main.rs:33:20:33:28 | "http://" | Unexpected result: Source | -| main.rs:33:31:33:60 | //... | Missing result: Alert[rust/non-https-url] | -| main.rs:36:30:36:51 | ...::get | Unexpected result: Alert | -| main.rs:59:15:59:49 | "http://example.com/sensitive-... | Unexpected result: Source | -| main.rs:59:52:59:81 | //... | Missing result: Alert[rust/non-https-url] | -| main.rs:60:21:60:42 | ...::get | Unexpected result: Alert | diff --git a/rust/ql/test/query-tests/security/CWE-319/main.rs b/rust/ql/test/query-tests/security/CWE-319/main.rs index ae58967a49b..52f744e39a1 100644 --- a/rust/ql/test/query-tests/security/CWE-319/main.rs +++ b/rust/ql/test/query-tests/security/CWE-319/main.rs @@ -11,30 +11,30 @@ fn test_direct_literals() { // BAD: Direct HTTP URLs that should be flagged let _response1 = reqwest::blocking::get("http://example.com/api").unwrap(); // $ Alert[rust/non-https-url] let _response2 = reqwest::blocking::get("http://api.example.com/data").unwrap(); // $ Alert[rust/non-https-url] - - // GOOD: HTTPS URLs that should not be flagged + + // GOOD: HTTPS URLs that should not be flagged let _response3 = reqwest::blocking::get("https://example.com/api").unwrap(); let _response4 = reqwest::blocking::get("https://api.example.com/data").unwrap(); } fn test_dynamic_urls() { // BAD: HTTP URLs constructed dynamically - let base_url = "http://example.com"; // $ Alert[rust/non-https-url] + let base_url = "http://example.com"; // $ Source let endpoint = "/api/users"; let full_url = format!("{}{}", base_url, endpoint); - let _response = reqwest::blocking::get(&full_url).unwrap(); - + let _response = reqwest::blocking::get(&full_url).unwrap(); // $ Alert[rust/non-https-url] + // GOOD: HTTPS URLs constructed dynamically let secure_base = "https://example.com"; let secure_full = format!("{}{}", secure_base, endpoint); let _secure_response = reqwest::blocking::get(&secure_full).unwrap(); - + // BAD: HTTP protocol string - let protocol = "http://"; // $ Alert[rust/non-https-url] + let protocol = "http://"; // $ Source let host = "api.example.com"; let insecure_url = format!("{}{}", protocol, host); - let _insecure_response = reqwest::blocking::get(&insecure_url).unwrap(); - + let _insecure_response = reqwest::blocking::get(&insecure_url).unwrap(); // $ Alert[rust/non-https-url] + // GOOD: HTTPS protocol string let secure_protocol = "https://"; let secure_url = format!("{}{}", secure_protocol, host); @@ -47,7 +47,7 @@ fn test_localhost_exemptions() { let _local2 = reqwest::blocking::get("http://127.0.0.1:3000/test").unwrap(); let _local3 = reqwest::blocking::get("http://192.168.1.100/internal").unwrap(); let _local4 = reqwest::blocking::get("http://10.0.0.1/admin").unwrap(); - + // Test IPv6 localhost variants let _local5 = reqwest::blocking::get("http://[::1]:8080/api").unwrap(); let _local6 = reqwest::blocking::get("http://[0:0:0:0:0:0:0:1]/test").unwrap(); @@ -56,10 +56,10 @@ fn test_localhost_exemptions() { // Additional test cases that mirror the Bad/Good examples fn test_examples() { // From UseOfHttpBad.rs - BAD case - let url = "http://example.com/sensitive-data"; // $ Alert[rust/non-https-url] - let _response = reqwest::blocking::get(url).unwrap(); - - // From UseOfHttpGood.rs - GOOD case + let url = "http://example.com/sensitive-data"; // $ Source + let _response = reqwest::blocking::get(url).unwrap(); // $ Alert[rust/non-https-url] + + // From UseOfHttpGood.rs - GOOD case let secure_url = "https://example.com/sensitive-data"; let _secure_response = reqwest::blocking::get(secure_url).unwrap(); -} \ No newline at end of file +} From 0924dec545a0eff7113574d629f4c5f2b99007be Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 16 Sep 2025 11:21:57 +0100 Subject: [PATCH 020/160] Rust: Make the tests of the example code closer to the actual example code. --- .../security/CWE-319/UseOfHttp.expected | 16 ++++++++-------- .../test/query-tests/security/CWE-319/main.rs | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected index f2a2e7e05f4..e8b7d301335 100644 --- a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected +++ b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected @@ -3,7 +3,7 @@ | main.rs:13:22:13:43 | ...::get | main.rs:13:45:13:73 | "http://api.example.com/data" | main.rs:13:22:13:43 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:13:45:13:73 | "http://api.example.com/data" | this HTTP URL | | main.rs:25:21:25:42 | ...::get | main.rs:22:20:22:39 | "http://example.com" | main.rs:25:21:25:42 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:22:20:22:39 | "http://example.com" | this HTTP URL | | main.rs:36:30:36:51 | ...::get | main.rs:33:20:33:28 | "http://" | main.rs:36:30:36:51 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:33:20:33:28 | "http://" | this HTTP URL | -| main.rs:60:21:60:42 | ...::get | main.rs:59:15:59:49 | "http://example.com/sensitive-... | main.rs:60:21:60:42 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:59:15:59:49 | "http://example.com/sensitive-... | this HTTP URL | +| main.rs:63:24:63:45 | ...::get | main.rs:60:19:60:53 | "http://example.com/sensitive-... | main.rs:63:24:63:45 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:60:19:60:53 | "http://example.com/sensitive-... | this HTTP URL | edges | main.rs:12:45:12:68 | "http://example.com/api" | main.rs:12:22:12:43 | ...::get | provenance | MaD:1 Sink:MaD:1 | | main.rs:13:45:13:73 | "http://api.example.com/data" | main.rs:13:22:13:43 | ...::get | provenance | MaD:1 Sink:MaD:1 | @@ -27,9 +27,9 @@ edges | main.rs:35:32:35:53 | { ... } | main.rs:35:32:35:53 | ...::must_use(...) | provenance | MaD:3 | | main.rs:36:53:36:65 | &insecure_url [&ref] | main.rs:36:30:36:51 | ...::get | provenance | MaD:1 Sink:MaD:1 | | main.rs:36:54:36:65 | insecure_url | main.rs:36:53:36:65 | &insecure_url [&ref] | provenance | | -| main.rs:59:9:59:11 | url | main.rs:60:44:60:46 | url | provenance | | -| main.rs:59:15:59:49 | "http://example.com/sensitive-... | main.rs:59:9:59:11 | url | provenance | | -| main.rs:60:44:60:46 | url | main.rs:60:21:60:42 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:60:13:60:15 | url | main.rs:63:47:63:49 | url | provenance | | +| main.rs:60:19:60:53 | "http://example.com/sensitive-... | main.rs:60:13:60:15 | url | provenance | | +| main.rs:63:47:63:49 | url | main.rs:63:24:63:45 | ...::get | provenance | MaD:1 Sink:MaD:1 | models | 1 | Sink: reqwest::blocking::get; Argument[0]; request-url | | 2 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | @@ -61,8 +61,8 @@ nodes | main.rs:36:30:36:51 | ...::get | semmle.label | ...::get | | main.rs:36:53:36:65 | &insecure_url [&ref] | semmle.label | &insecure_url [&ref] | | main.rs:36:54:36:65 | insecure_url | semmle.label | insecure_url | -| main.rs:59:9:59:11 | url | semmle.label | url | -| main.rs:59:15:59:49 | "http://example.com/sensitive-... | semmle.label | "http://example.com/sensitive-... | -| main.rs:60:21:60:42 | ...::get | semmle.label | ...::get | -| main.rs:60:44:60:46 | url | semmle.label | url | +| main.rs:60:13:60:15 | url | semmle.label | url | +| main.rs:60:19:60:53 | "http://example.com/sensitive-... | semmle.label | "http://example.com/sensitive-... | +| main.rs:63:24:63:45 | ...::get | semmle.label | ...::get | +| main.rs:63:47:63:49 | url | semmle.label | url | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-319/main.rs b/rust/ql/test/query-tests/security/CWE-319/main.rs index 52f744e39a1..cec94840f29 100644 --- a/rust/ql/test/query-tests/security/CWE-319/main.rs +++ b/rust/ql/test/query-tests/security/CWE-319/main.rs @@ -56,10 +56,20 @@ fn test_localhost_exemptions() { // Additional test cases that mirror the Bad/Good examples fn test_examples() { // From UseOfHttpBad.rs - BAD case - let url = "http://example.com/sensitive-data"; // $ Source - let _response = reqwest::blocking::get(url).unwrap(); // $ Alert[rust/non-https-url] + { + let url = "http://example.com/sensitive-data"; // $ Source + + // This makes an insecure HTTP request that can be intercepted + let response = reqwest::blocking::get(url).unwrap(); // $ Alert[rust/non-https-url] + println!("Response: {}", response.text().unwrap()); + } // From UseOfHttpGood.rs - GOOD case - let secure_url = "https://example.com/sensitive-data"; - let _secure_response = reqwest::blocking::get(secure_url).unwrap(); + { + let url = "https://example.com/sensitive-data"; + + // This makes a secure HTTPS request that is encrypted + let response = reqwest::blocking::get(url).unwrap(); + println!("Response: {}", response.text().unwrap()); + } } From 9c7fc583373c353f5bf6cf35d055af3b6f28ad0e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 16 Sep 2025 12:06:05 +0100 Subject: [PATCH 021/160] Rust: Add tests for a few more edge cases. --- .../security/CWE-319/UseOfHttp.expected | 120 ++++++++++-------- .../test/query-tests/security/CWE-319/main.rs | 22 +++- 2 files changed, 79 insertions(+), 63 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected index e8b7d301335..216d11b3606 100644 --- a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected +++ b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected @@ -1,35 +1,39 @@ #select | main.rs:12:22:12:43 | ...::get | main.rs:12:45:12:68 | "http://example.com/api" | main.rs:12:22:12:43 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:12:45:12:68 | "http://example.com/api" | this HTTP URL | -| main.rs:13:22:13:43 | ...::get | main.rs:13:45:13:73 | "http://api.example.com/data" | main.rs:13:22:13:43 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:13:45:13:73 | "http://api.example.com/data" | this HTTP URL | -| main.rs:25:21:25:42 | ...::get | main.rs:22:20:22:39 | "http://example.com" | main.rs:25:21:25:42 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:22:20:22:39 | "http://example.com" | this HTTP URL | -| main.rs:36:30:36:51 | ...::get | main.rs:33:20:33:28 | "http://" | main.rs:36:30:36:51 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:33:20:33:28 | "http://" | this HTTP URL | -| main.rs:63:24:63:45 | ...::get | main.rs:60:19:60:53 | "http://example.com/sensitive-... | main.rs:63:24:63:45 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:60:19:60:53 | "http://example.com/sensitive-... | this HTTP URL | +| main.rs:14:22:14:43 | ...::get | main.rs:14:45:14:73 | "http://api.example.com/data" | main.rs:14:22:14:43 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:14:45:14:73 | "http://api.example.com/data" | this HTTP URL | +| main.rs:26:21:26:42 | ...::get | main.rs:23:20:23:39 | "http://example.com" | main.rs:26:21:26:42 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:23:20:23:39 | "http://example.com" | this HTTP URL | +| main.rs:37:30:37:51 | ...::get | main.rs:34:20:34:28 | "http://" | main.rs:37:30:37:51 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:34:20:34:28 | "http://" | this HTTP URL | +| main.rs:53:19:53:40 | ...::get | main.rs:53:42:53:68 | "http://172.31.255.255/bar" | main.rs:53:19:53:40 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:53:42:53:68 | "http://172.31.255.255/bar" | this HTTP URL | +| main.rs:60:20:60:41 | ...::get | main.rs:60:43:60:65 | "http://172.32.0.0/baz" | main.rs:60:20:60:41 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:60:43:60:65 | "http://172.32.0.0/baz" | this HTTP URL | +| main.rs:71:24:71:45 | ...::get | main.rs:68:19:68:53 | "http://example.com/sensitive-... | main.rs:71:24:71:45 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:68:19:68:53 | "http://example.com/sensitive-... | this HTTP URL | edges | main.rs:12:45:12:68 | "http://example.com/api" | main.rs:12:22:12:43 | ...::get | provenance | MaD:1 Sink:MaD:1 | -| main.rs:13:45:13:73 | "http://api.example.com/data" | main.rs:13:22:13:43 | ...::get | provenance | MaD:1 Sink:MaD:1 | -| main.rs:22:9:22:16 | base_url | main.rs:24:28:24:53 | MacroExpr | provenance | | -| main.rs:22:20:22:39 | "http://example.com" | main.rs:22:9:22:16 | base_url | provenance | | -| main.rs:24:9:24:16 | full_url | main.rs:25:45:25:52 | full_url | provenance | | -| main.rs:24:20:24:26 | res | main.rs:24:28:24:53 | { ... } | provenance | | -| main.rs:24:28:24:53 | ...::format(...) | main.rs:24:20:24:26 | res | provenance | | -| main.rs:24:28:24:53 | ...::must_use(...) | main.rs:24:9:24:16 | full_url | provenance | | -| main.rs:24:28:24:53 | MacroExpr | main.rs:24:28:24:53 | ...::format(...) | provenance | MaD:2 | -| main.rs:24:28:24:53 | { ... } | main.rs:24:28:24:53 | ...::must_use(...) | provenance | MaD:3 | -| main.rs:25:44:25:52 | &full_url [&ref] | main.rs:25:21:25:42 | ...::get | provenance | MaD:1 Sink:MaD:1 | -| main.rs:25:45:25:52 | full_url | main.rs:25:44:25:52 | &full_url [&ref] | provenance | | -| main.rs:33:9:33:16 | protocol | main.rs:35:32:35:53 | MacroExpr | provenance | | -| main.rs:33:20:33:28 | "http://" | main.rs:33:9:33:16 | protocol | provenance | | -| main.rs:35:9:35:20 | insecure_url | main.rs:36:54:36:65 | insecure_url | provenance | | -| main.rs:35:24:35:30 | res | main.rs:35:32:35:53 | { ... } | provenance | | -| main.rs:35:32:35:53 | ...::format(...) | main.rs:35:24:35:30 | res | provenance | | -| main.rs:35:32:35:53 | ...::must_use(...) | main.rs:35:9:35:20 | insecure_url | provenance | | -| main.rs:35:32:35:53 | MacroExpr | main.rs:35:32:35:53 | ...::format(...) | provenance | MaD:2 | -| main.rs:35:32:35:53 | { ... } | main.rs:35:32:35:53 | ...::must_use(...) | provenance | MaD:3 | -| main.rs:36:53:36:65 | &insecure_url [&ref] | main.rs:36:30:36:51 | ...::get | provenance | MaD:1 Sink:MaD:1 | -| main.rs:36:54:36:65 | insecure_url | main.rs:36:53:36:65 | &insecure_url [&ref] | provenance | | -| main.rs:60:13:60:15 | url | main.rs:63:47:63:49 | url | provenance | | -| main.rs:60:19:60:53 | "http://example.com/sensitive-... | main.rs:60:13:60:15 | url | provenance | | -| main.rs:63:47:63:49 | url | main.rs:63:24:63:45 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:14:45:14:73 | "http://api.example.com/data" | main.rs:14:22:14:43 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:23:9:23:16 | base_url | main.rs:25:28:25:53 | MacroExpr | provenance | | +| main.rs:23:20:23:39 | "http://example.com" | main.rs:23:9:23:16 | base_url | provenance | | +| main.rs:25:9:25:16 | full_url | main.rs:26:45:26:52 | full_url | provenance | | +| main.rs:25:20:25:26 | res | main.rs:25:28:25:53 | { ... } | provenance | | +| main.rs:25:28:25:53 | ...::format(...) | main.rs:25:20:25:26 | res | provenance | | +| main.rs:25:28:25:53 | ...::must_use(...) | main.rs:25:9:25:16 | full_url | provenance | | +| main.rs:25:28:25:53 | MacroExpr | main.rs:25:28:25:53 | ...::format(...) | provenance | MaD:2 | +| main.rs:25:28:25:53 | { ... } | main.rs:25:28:25:53 | ...::must_use(...) | provenance | MaD:3 | +| main.rs:26:44:26:52 | &full_url [&ref] | main.rs:26:21:26:42 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:26:45:26:52 | full_url | main.rs:26:44:26:52 | &full_url [&ref] | provenance | | +| main.rs:34:9:34:16 | protocol | main.rs:36:32:36:53 | MacroExpr | provenance | | +| main.rs:34:20:34:28 | "http://" | main.rs:34:9:34:16 | protocol | provenance | | +| main.rs:36:9:36:20 | insecure_url | main.rs:37:54:37:65 | insecure_url | provenance | | +| main.rs:36:24:36:30 | res | main.rs:36:32:36:53 | { ... } | provenance | | +| main.rs:36:32:36:53 | ...::format(...) | main.rs:36:24:36:30 | res | provenance | | +| main.rs:36:32:36:53 | ...::must_use(...) | main.rs:36:9:36:20 | insecure_url | provenance | | +| main.rs:36:32:36:53 | MacroExpr | main.rs:36:32:36:53 | ...::format(...) | provenance | MaD:2 | +| main.rs:36:32:36:53 | { ... } | main.rs:36:32:36:53 | ...::must_use(...) | provenance | MaD:3 | +| main.rs:37:53:37:65 | &insecure_url [&ref] | main.rs:37:30:37:51 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:37:54:37:65 | insecure_url | main.rs:37:53:37:65 | &insecure_url [&ref] | provenance | | +| main.rs:53:42:53:68 | "http://172.31.255.255/bar" | main.rs:53:19:53:40 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:60:43:60:65 | "http://172.32.0.0/baz" | main.rs:60:20:60:41 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:68:13:68:15 | url | main.rs:71:47:71:49 | url | provenance | | +| main.rs:68:19:68:53 | "http://example.com/sensitive-... | main.rs:68:13:68:15 | url | provenance | | +| main.rs:71:47:71:49 | url | main.rs:71:24:71:45 | ...::get | provenance | MaD:1 Sink:MaD:1 | models | 1 | Sink: reqwest::blocking::get; Argument[0]; request-url | | 2 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | @@ -37,32 +41,36 @@ models nodes | main.rs:12:22:12:43 | ...::get | semmle.label | ...::get | | main.rs:12:45:12:68 | "http://example.com/api" | semmle.label | "http://example.com/api" | -| main.rs:13:22:13:43 | ...::get | semmle.label | ...::get | -| main.rs:13:45:13:73 | "http://api.example.com/data" | semmle.label | "http://api.example.com/data" | -| main.rs:22:9:22:16 | base_url | semmle.label | base_url | -| main.rs:22:20:22:39 | "http://example.com" | semmle.label | "http://example.com" | -| main.rs:24:9:24:16 | full_url | semmle.label | full_url | -| main.rs:24:20:24:26 | res | semmle.label | res | -| main.rs:24:28:24:53 | ...::format(...) | semmle.label | ...::format(...) | -| main.rs:24:28:24:53 | ...::must_use(...) | semmle.label | ...::must_use(...) | -| main.rs:24:28:24:53 | MacroExpr | semmle.label | MacroExpr | -| main.rs:24:28:24:53 | { ... } | semmle.label | { ... } | -| main.rs:25:21:25:42 | ...::get | semmle.label | ...::get | -| main.rs:25:44:25:52 | &full_url [&ref] | semmle.label | &full_url [&ref] | -| main.rs:25:45:25:52 | full_url | semmle.label | full_url | -| main.rs:33:9:33:16 | protocol | semmle.label | protocol | -| main.rs:33:20:33:28 | "http://" | semmle.label | "http://" | -| main.rs:35:9:35:20 | insecure_url | semmle.label | insecure_url | -| main.rs:35:24:35:30 | res | semmle.label | res | -| main.rs:35:32:35:53 | ...::format(...) | semmle.label | ...::format(...) | -| main.rs:35:32:35:53 | ...::must_use(...) | semmle.label | ...::must_use(...) | -| main.rs:35:32:35:53 | MacroExpr | semmle.label | MacroExpr | -| main.rs:35:32:35:53 | { ... } | semmle.label | { ... } | -| main.rs:36:30:36:51 | ...::get | semmle.label | ...::get | -| main.rs:36:53:36:65 | &insecure_url [&ref] | semmle.label | &insecure_url [&ref] | -| main.rs:36:54:36:65 | insecure_url | semmle.label | insecure_url | -| main.rs:60:13:60:15 | url | semmle.label | url | -| main.rs:60:19:60:53 | "http://example.com/sensitive-... | semmle.label | "http://example.com/sensitive-... | -| main.rs:63:24:63:45 | ...::get | semmle.label | ...::get | -| main.rs:63:47:63:49 | url | semmle.label | url | +| main.rs:14:22:14:43 | ...::get | semmle.label | ...::get | +| main.rs:14:45:14:73 | "http://api.example.com/data" | semmle.label | "http://api.example.com/data" | +| main.rs:23:9:23:16 | base_url | semmle.label | base_url | +| main.rs:23:20:23:39 | "http://example.com" | semmle.label | "http://example.com" | +| main.rs:25:9:25:16 | full_url | semmle.label | full_url | +| main.rs:25:20:25:26 | res | semmle.label | res | +| main.rs:25:28:25:53 | ...::format(...) | semmle.label | ...::format(...) | +| main.rs:25:28:25:53 | ...::must_use(...) | semmle.label | ...::must_use(...) | +| main.rs:25:28:25:53 | MacroExpr | semmle.label | MacroExpr | +| main.rs:25:28:25:53 | { ... } | semmle.label | { ... } | +| main.rs:26:21:26:42 | ...::get | semmle.label | ...::get | +| main.rs:26:44:26:52 | &full_url [&ref] | semmle.label | &full_url [&ref] | +| main.rs:26:45:26:52 | full_url | semmle.label | full_url | +| main.rs:34:9:34:16 | protocol | semmle.label | protocol | +| main.rs:34:20:34:28 | "http://" | semmle.label | "http://" | +| main.rs:36:9:36:20 | insecure_url | semmle.label | insecure_url | +| main.rs:36:24:36:30 | res | semmle.label | res | +| main.rs:36:32:36:53 | ...::format(...) | semmle.label | ...::format(...) | +| main.rs:36:32:36:53 | ...::must_use(...) | semmle.label | ...::must_use(...) | +| main.rs:36:32:36:53 | MacroExpr | semmle.label | MacroExpr | +| main.rs:36:32:36:53 | { ... } | semmle.label | { ... } | +| main.rs:37:30:37:51 | ...::get | semmle.label | ...::get | +| main.rs:37:53:37:65 | &insecure_url [&ref] | semmle.label | &insecure_url [&ref] | +| main.rs:37:54:37:65 | insecure_url | semmle.label | insecure_url | +| main.rs:53:19:53:40 | ...::get | semmle.label | ...::get | +| main.rs:53:42:53:68 | "http://172.31.255.255/bar" | semmle.label | "http://172.31.255.255/bar" | +| main.rs:60:20:60:41 | ...::get | semmle.label | ...::get | +| main.rs:60:43:60:65 | "http://172.32.0.0/baz" | semmle.label | "http://172.32.0.0/baz" | +| main.rs:68:13:68:15 | url | semmle.label | url | +| main.rs:68:19:68:53 | "http://example.com/sensitive-... | semmle.label | "http://example.com/sensitive-... | +| main.rs:71:24:71:45 | ...::get | semmle.label | ...::get | +| main.rs:71:47:71:49 | url | semmle.label | url | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-319/main.rs b/rust/ql/test/query-tests/security/CWE-319/main.rs index cec94840f29..0dd59ce0880 100644 --- a/rust/ql/test/query-tests/security/CWE-319/main.rs +++ b/rust/ql/test/query-tests/security/CWE-319/main.rs @@ -10,7 +10,8 @@ fn main() { fn test_direct_literals() { // BAD: Direct HTTP URLs that should be flagged let _response1 = reqwest::blocking::get("http://example.com/api").unwrap(); // $ Alert[rust/non-https-url] - let _response2 = reqwest::blocking::get("http://api.example.com/data").unwrap(); // $ Alert[rust/non-https-url] + let _response2 = reqwest::blocking::get("HTTP://EXAMPLE.COM/API").unwrap(); // $ MISSING: Alert[rust/non-https-url] + let _response3 = reqwest::blocking::get("http://api.example.com/data").unwrap(); // $ Alert[rust/non-https-url] // GOOD: HTTPS URLs that should not be flagged let _response3 = reqwest::blocking::get("https://example.com/api").unwrap(); @@ -44,13 +45,20 @@ fn test_dynamic_urls() { fn test_localhost_exemptions() { // GOOD: localhost URLs should not be flagged (local development) let _local1 = reqwest::blocking::get("http://localhost:8080/api").unwrap(); - let _local2 = reqwest::blocking::get("http://127.0.0.1:3000/test").unwrap(); - let _local3 = reqwest::blocking::get("http://192.168.1.100/internal").unwrap(); - let _local4 = reqwest::blocking::get("http://10.0.0.1/admin").unwrap(); + let _local2 = reqwest::blocking::get("HTTP://LOCALHOST:8080/api").unwrap(); + let _local3 = reqwest::blocking::get("http://127.0.0.1:3000/test").unwrap(); + let _local4 = reqwest::blocking::get("http://192.168.1.100/internal").unwrap(); + let _local5 = reqwest::blocking::get("http://10.0.0.1/admin").unwrap(); + let _local6 = reqwest::blocking::get("http://172.16.0.0/foo").unwrap(); + let _local7 = reqwest::blocking::get("http://172.31.255.255/bar").unwrap(); // $ SPURIOUS: Alert[rust/non-https-url] + + // GOOD: test IPv6 localhost variants + let _local8 = reqwest::blocking::get("http://[::1]:8080/api").unwrap(); + let _local9 = reqwest::blocking::get("http://[0:0:0:0:0:0:0:1]/test").unwrap(); + + // BAD: non-private IP address + let _local10 = reqwest::blocking::get("http://172.32.0.0/baz").unwrap(); // $ Alert[rust/non-https-url] - // Test IPv6 localhost variants - let _local5 = reqwest::blocking::get("http://[::1]:8080/api").unwrap(); - let _local6 = reqwest::blocking::get("http://[0:0:0:0:0:0:0:1]/test").unwrap(); } // Additional test cases that mirror the Bad/Good examples From 0f5aa857b874b22bfb53b67b08be2336e14af351 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 16 Sep 2025 11:32:52 +0100 Subject: [PATCH 022/160] Rust: Remove unnecessary import. --- rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll b/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll index 026880785b6..8001e6270dd 100644 --- a/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll @@ -6,7 +6,6 @@ import rust private import codeql.rust.dataflow.DataFlow private import codeql.rust.dataflow.FlowSink -private import codeql.rust.elements.LiteralExprExt private import codeql.rust.Concepts /** From 0b900711bf1d3df6d5d16d7cd7688495b2ca60dd Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 16 Sep 2025 13:48:26 +0200 Subject: [PATCH 023/160] Update javascript/ql/lib/semmle/javascript/frameworks/Express.qll Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- javascript/ql/lib/semmle/javascript/frameworks/Express.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll index 41e4d1c860c..be3cb7b1ccb 100644 --- a/javascript/ql/lib/semmle/javascript/frameworks/Express.qll +++ b/javascript/ql/lib/semmle/javascript/frameworks/Express.qll @@ -803,7 +803,7 @@ module Express { } /** - * An argument passed to the `json` or `json` method of an HTTP response object. + * An argument passed to the `json` or `jsonp` method of an HTTP response object. */ private class ResponseJsonCallArgument extends Http::ResponseSendArgument { ResponseJsonCall call; From 80ce55ab1072fb534776fc7b02a93ca6a2b18ce2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 16 Sep 2025 11:58:23 +0100 Subject: [PATCH 024/160] Rust: Make the private address spaces URL more accurate. --- rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll | 2 +- rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected | 4 ---- rust/ql/test/query-tests/security/CWE-319/main.rs | 2 +- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll b/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll index 8001e6270dd..58466dd0a4f 100644 --- a/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll @@ -38,7 +38,7 @@ module UseOfHttp { exists(string s | this.getTextValue() = s | // Match HTTP URLs that are not private/local s.regexpMatch("\"http://.*\"") and - not s.regexpMatch("\"http://(localhost|127\\.0\\.0\\.1|192\\.168\\.[0-9]+\\.[0-9]+|10\\.[0-9]+\\.[0-9]+\\.[0-9]+|172\\.16\\.[0-9]+\\.[0-9]+|\\[::1\\]|\\[0:0:0:0:0:0:0:1\\]).*\"") + not s.regexpMatch("\"http://(localhost|127\\.0\\.0\\.1|192\\.168\\.[0-9]+\\.[0-9]+|10\\.[0-9]+\\.[0-9]+\\.[0-9]+|172\\.(1[6-9]|2[0-9]|3[01])\\.[0-9]+|\\[::1\\]|\\[0:0:0:0:0:0:0:1\\]).*\"") ) } } diff --git a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected index 216d11b3606..ef99b001fcf 100644 --- a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected +++ b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected @@ -3,7 +3,6 @@ | main.rs:14:22:14:43 | ...::get | main.rs:14:45:14:73 | "http://api.example.com/data" | main.rs:14:22:14:43 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:14:45:14:73 | "http://api.example.com/data" | this HTTP URL | | main.rs:26:21:26:42 | ...::get | main.rs:23:20:23:39 | "http://example.com" | main.rs:26:21:26:42 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:23:20:23:39 | "http://example.com" | this HTTP URL | | main.rs:37:30:37:51 | ...::get | main.rs:34:20:34:28 | "http://" | main.rs:37:30:37:51 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:34:20:34:28 | "http://" | this HTTP URL | -| main.rs:53:19:53:40 | ...::get | main.rs:53:42:53:68 | "http://172.31.255.255/bar" | main.rs:53:19:53:40 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:53:42:53:68 | "http://172.31.255.255/bar" | this HTTP URL | | main.rs:60:20:60:41 | ...::get | main.rs:60:43:60:65 | "http://172.32.0.0/baz" | main.rs:60:20:60:41 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:60:43:60:65 | "http://172.32.0.0/baz" | this HTTP URL | | main.rs:71:24:71:45 | ...::get | main.rs:68:19:68:53 | "http://example.com/sensitive-... | main.rs:71:24:71:45 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:68:19:68:53 | "http://example.com/sensitive-... | this HTTP URL | edges @@ -29,7 +28,6 @@ edges | main.rs:36:32:36:53 | { ... } | main.rs:36:32:36:53 | ...::must_use(...) | provenance | MaD:3 | | main.rs:37:53:37:65 | &insecure_url [&ref] | main.rs:37:30:37:51 | ...::get | provenance | MaD:1 Sink:MaD:1 | | main.rs:37:54:37:65 | insecure_url | main.rs:37:53:37:65 | &insecure_url [&ref] | provenance | | -| main.rs:53:42:53:68 | "http://172.31.255.255/bar" | main.rs:53:19:53:40 | ...::get | provenance | MaD:1 Sink:MaD:1 | | main.rs:60:43:60:65 | "http://172.32.0.0/baz" | main.rs:60:20:60:41 | ...::get | provenance | MaD:1 Sink:MaD:1 | | main.rs:68:13:68:15 | url | main.rs:71:47:71:49 | url | provenance | | | main.rs:68:19:68:53 | "http://example.com/sensitive-... | main.rs:68:13:68:15 | url | provenance | | @@ -65,8 +63,6 @@ nodes | main.rs:37:30:37:51 | ...::get | semmle.label | ...::get | | main.rs:37:53:37:65 | &insecure_url [&ref] | semmle.label | &insecure_url [&ref] | | main.rs:37:54:37:65 | insecure_url | semmle.label | insecure_url | -| main.rs:53:19:53:40 | ...::get | semmle.label | ...::get | -| main.rs:53:42:53:68 | "http://172.31.255.255/bar" | semmle.label | "http://172.31.255.255/bar" | | main.rs:60:20:60:41 | ...::get | semmle.label | ...::get | | main.rs:60:43:60:65 | "http://172.32.0.0/baz" | semmle.label | "http://172.32.0.0/baz" | | main.rs:68:13:68:15 | url | semmle.label | url | diff --git a/rust/ql/test/query-tests/security/CWE-319/main.rs b/rust/ql/test/query-tests/security/CWE-319/main.rs index 0dd59ce0880..908e6c61c2c 100644 --- a/rust/ql/test/query-tests/security/CWE-319/main.rs +++ b/rust/ql/test/query-tests/security/CWE-319/main.rs @@ -50,7 +50,7 @@ fn test_localhost_exemptions() { let _local4 = reqwest::blocking::get("http://192.168.1.100/internal").unwrap(); let _local5 = reqwest::blocking::get("http://10.0.0.1/admin").unwrap(); let _local6 = reqwest::blocking::get("http://172.16.0.0/foo").unwrap(); - let _local7 = reqwest::blocking::get("http://172.31.255.255/bar").unwrap(); // $ SPURIOUS: Alert[rust/non-https-url] + let _local7 = reqwest::blocking::get("http://172.31.255.255/bar").unwrap(); // GOOD: test IPv6 localhost variants let _local8 = reqwest::blocking::get("http://[::1]:8080/api").unwrap(); From 4b281fdf12fb8a64cd194aee324ded70855b4695 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 16 Sep 2025 13:02:54 +0100 Subject: [PATCH 025/160] Rust: Use case insensitive regexps. --- rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll | 4 ++-- rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected | 4 ++++ rust/ql/test/query-tests/security/CWE-319/main.rs | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll b/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll index 58466dd0a4f..5e0d534fb7d 100644 --- a/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll @@ -37,8 +37,8 @@ module UseOfHttp { HttpStringLiteral() { exists(string s | this.getTextValue() = s | // Match HTTP URLs that are not private/local - s.regexpMatch("\"http://.*\"") and - not s.regexpMatch("\"http://(localhost|127\\.0\\.0\\.1|192\\.168\\.[0-9]+\\.[0-9]+|10\\.[0-9]+\\.[0-9]+\\.[0-9]+|172\\.(1[6-9]|2[0-9]|3[01])\\.[0-9]+|\\[::1\\]|\\[0:0:0:0:0:0:0:1\\]).*\"") + s.regexpMatch("(?i)\"http://.*\"") and + not s.regexpMatch("(?i)\"http://(localhost|127\\.0\\.0\\.1|192\\.168\\.[0-9]+\\.[0-9]+|10\\.[0-9]+\\.[0-9]+\\.[0-9]+|172\\.(1[6-9]|2[0-9]|3[01])\\.[0-9]+|\\[::1\\]|\\[0:0:0:0:0:0:0:1\\]).*\"") ) } } diff --git a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected index ef99b001fcf..952bd741d1c 100644 --- a/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected +++ b/rust/ql/test/query-tests/security/CWE-319/UseOfHttp.expected @@ -1,5 +1,6 @@ #select | main.rs:12:22:12:43 | ...::get | main.rs:12:45:12:68 | "http://example.com/api" | main.rs:12:22:12:43 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:12:45:12:68 | "http://example.com/api" | this HTTP URL | +| main.rs:13:22:13:43 | ...::get | main.rs:13:45:13:68 | "HTTP://EXAMPLE.COM/API" | main.rs:13:22:13:43 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:13:45:13:68 | "HTTP://EXAMPLE.COM/API" | this HTTP URL | | main.rs:14:22:14:43 | ...::get | main.rs:14:45:14:73 | "http://api.example.com/data" | main.rs:14:22:14:43 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:14:45:14:73 | "http://api.example.com/data" | this HTTP URL | | main.rs:26:21:26:42 | ...::get | main.rs:23:20:23:39 | "http://example.com" | main.rs:26:21:26:42 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:23:20:23:39 | "http://example.com" | this HTTP URL | | main.rs:37:30:37:51 | ...::get | main.rs:34:20:34:28 | "http://" | main.rs:37:30:37:51 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:34:20:34:28 | "http://" | this HTTP URL | @@ -7,6 +8,7 @@ | main.rs:71:24:71:45 | ...::get | main.rs:68:19:68:53 | "http://example.com/sensitive-... | main.rs:71:24:71:45 | ...::get | This URL may be constructed with the HTTP protocol, from $@. | main.rs:68:19:68:53 | "http://example.com/sensitive-... | this HTTP URL | edges | main.rs:12:45:12:68 | "http://example.com/api" | main.rs:12:22:12:43 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| main.rs:13:45:13:68 | "HTTP://EXAMPLE.COM/API" | main.rs:13:22:13:43 | ...::get | provenance | MaD:1 Sink:MaD:1 | | main.rs:14:45:14:73 | "http://api.example.com/data" | main.rs:14:22:14:43 | ...::get | provenance | MaD:1 Sink:MaD:1 | | main.rs:23:9:23:16 | base_url | main.rs:25:28:25:53 | MacroExpr | provenance | | | main.rs:23:20:23:39 | "http://example.com" | main.rs:23:9:23:16 | base_url | provenance | | @@ -39,6 +41,8 @@ models nodes | main.rs:12:22:12:43 | ...::get | semmle.label | ...::get | | main.rs:12:45:12:68 | "http://example.com/api" | semmle.label | "http://example.com/api" | +| main.rs:13:22:13:43 | ...::get | semmle.label | ...::get | +| main.rs:13:45:13:68 | "HTTP://EXAMPLE.COM/API" | semmle.label | "HTTP://EXAMPLE.COM/API" | | main.rs:14:22:14:43 | ...::get | semmle.label | ...::get | | main.rs:14:45:14:73 | "http://api.example.com/data" | semmle.label | "http://api.example.com/data" | | main.rs:23:9:23:16 | base_url | semmle.label | base_url | diff --git a/rust/ql/test/query-tests/security/CWE-319/main.rs b/rust/ql/test/query-tests/security/CWE-319/main.rs index 908e6c61c2c..0a3539923da 100644 --- a/rust/ql/test/query-tests/security/CWE-319/main.rs +++ b/rust/ql/test/query-tests/security/CWE-319/main.rs @@ -10,7 +10,7 @@ fn main() { fn test_direct_literals() { // BAD: Direct HTTP URLs that should be flagged let _response1 = reqwest::blocking::get("http://example.com/api").unwrap(); // $ Alert[rust/non-https-url] - let _response2 = reqwest::blocking::get("HTTP://EXAMPLE.COM/API").unwrap(); // $ MISSING: Alert[rust/non-https-url] + let _response2 = reqwest::blocking::get("HTTP://EXAMPLE.COM/API").unwrap(); // $ Alert[rust/non-https-url] let _response3 = reqwest::blocking::get("http://api.example.com/data").unwrap(); // $ Alert[rust/non-https-url] // GOOD: HTTPS URLs that should not be flagged From 0eb602aad2991216268e79bbe5db05472f2156c0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:00:43 +0100 Subject: [PATCH 026/160] Rust: Update a redirected URL. --- .../src/queries/security/CWE-319/UseOfHttp.qhelp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp b/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp index a8ca1d9c7c7..a1345b189bb 100644 --- a/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp +++ b/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp @@ -6,21 +6,21 @@

    Constructing URLs with the HTTP protocol can lead to unsecured connections.

    -

    Furthermore, constructing URLs with the HTTP protocol can create problems if other parts of the -code expect HTTPS URLs. A typical pattern is to use libraries that expect secure connections, +

    Furthermore, constructing URLs with the HTTP protocol can create problems if other parts of the +code expect HTTPS URLs. A typical pattern is to use libraries that expect secure connections, which may fail or fall back to insecure behavior when provided with HTTP URLs instead of HTTPS URLs.

    -

    When you construct a URL for network requests, ensure that you use an HTTPS URL rather than an HTTP URL. +

    When you construct a URL for network requests, ensure that you use an HTTPS URL rather than an HTTP URL. Then, any connections that are made using that URL are secure SSL/TLS connections.

    -

    The following example shows two ways of making a network request using a URL. When the request is -made using an HTTP URL rather than an HTTPS URL, the connection is unsecured and can be intercepted +

    The following example shows two ways of making a network request using a URL. When the request is +made using an HTTP URL rather than an HTTPS URL, the connection is unsecured and can be intercepted by attackers. When the request is made using an HTTPS URL, the connection is a secure SSL/TLS connection.

    @@ -34,15 +34,15 @@ by attackers. When the request is made using an HTTPS URL, the connection is a s
  • OWASP: -Transport Layer Protection Cheat Sheet. +Transport Layer Security Cheat Sheet.
  • OWASP Top 10: A08:2021 - Software and Data Integrity Failures.
  • -
  • Rust reqwest documentation: +
  • Rust reqwest documentation: reqwest crate.
  • - \ No newline at end of file + From 31bf86fd1bcb60946c038d1329f132647bc60288 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 16 Sep 2025 14:04:47 +0100 Subject: [PATCH 027/160] Rust: Improve the flow around the qhelp example. --- rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp b/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp index a1345b189bb..e4e0fc5eaa9 100644 --- a/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp +++ b/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp @@ -19,13 +19,14 @@ Then, any connections that are made using that URL are secure SSL/TLS connection -

    The following example shows two ways of making a network request using a URL. When the request is +

    The following examples show two ways of making a network request using a URL. When the request is made using an HTTP URL rather than an HTTPS URL, the connection is unsecured and can be intercepted -by attackers. When the request is made using an HTTPS URL, the connection is a secure SSL/TLS connection.

    +by attackers:

    -

    A better approach is to use HTTPS:

    +

    A better approach is to use HTTPS. When the request is made using an HTTPS URL, the connection +is a secure SSL/TLS connection:

    From ffd32efba274f0b1400d592562f24cae4a286ddf Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Tue, 16 Sep 2025 09:08:07 -0400 Subject: [PATCH 028/160] codeql query format --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 37 ++++++------------- .../library-tests/frameworks/grape/Grape.ql | 2 +- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index faf762f53a0..ea7bc8c576c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -52,9 +52,7 @@ class GrapeApiClass extends DataFlow::ClassNode { /** * Gets a `GrapeEndpoint` defined in this class. */ - GrapeEndpoint getAnEndpoint() { - result.getApiClass() = this - } + GrapeEndpoint getAnEndpoint() { result.getApiClass() = this } /** * Gets a `self` that possibly refers to an instance of this class. @@ -72,9 +70,7 @@ private DataFlow::ConstRef grapeApiBaseClass() { result = DataFlow::getConstant("Grape").getConstant("API") } -private API::Node grapeApiInstance() { - result = any(GrapeApiClass cls).getSelf().track() -} +private API::Node grapeApiInstance() { result = any(GrapeApiClass cls).getSelf().track() } /** * A Grape API endpoint (get, post, put, delete, etc.) call within a `Grape::API` class. @@ -83,15 +79,14 @@ class GrapeEndpoint extends DataFlow::CallNode { private GrapeApiClass apiClass; GrapeEndpoint() { - this = apiClass.getAModuleLevelCall(["get", "post", "put", "delete", "patch", "head", "options"]) + this = + apiClass.getAModuleLevelCall(["get", "post", "put", "delete", "patch", "head", "options"]) } /** * Gets the HTTP method for this endpoint (e.g., "GET", "POST", etc.) */ - string getHttpMethod() { - result = this.getMethodName().toUpperCase() - } + string getHttpMethod() { result = this.getMethodName().toUpperCase() } /** * Gets the API class containing this endpoint. @@ -106,9 +101,7 @@ class GrapeEndpoint extends DataFlow::CallNode { /** * Gets the path pattern for this endpoint, if specified. */ - string getPath() { - result = this.getArgument(0).getConstantValue().getString() - } + string getPath() { result = this.getArgument(0).getConstantValue().getString() } } /** @@ -116,9 +109,7 @@ class GrapeEndpoint extends DataFlow::CallNode { * Grape parameters available via the `params` method within an endpoint. */ class GrapeParamsSource extends Http::Server::RequestInputAccess::Range { - GrapeParamsSource() { - this.asExpr().getExpr() instanceof GrapeParamsCall - } + GrapeParamsSource() { this.asExpr().getExpr() instanceof GrapeParamsCall } override string getSourceType() { result = "Grape::API#params" } @@ -174,9 +165,7 @@ private class GrapeHeadersCall extends MethodCall { * The request object can contain user input. */ class GrapeRequestSource extends Http::Server::RequestInputAccess::Range { - GrapeRequestSource() { - this.asExpr().getExpr() instanceof GrapeRequestCall - } + GrapeRequestSource() { this.asExpr().getExpr() instanceof GrapeRequestCall } override string getSourceType() { result = "Grape::API#request" } @@ -188,9 +177,7 @@ class GrapeRequestSource extends Http::Server::RequestInputAccess::Range { * Route parameters are extracted from the URL path and can be a source of user input. */ class GrapeRouteParamSource extends Http::Server::RequestInputAccess::Range { - GrapeRouteParamSource() { - this.asExpr().getExpr() instanceof GrapeRouteParamCall - } + GrapeRouteParamSource() { this.asExpr().getExpr() instanceof GrapeRouteParamCall } override string getSourceType() { result = "Grape::API#route_param" } @@ -316,12 +303,10 @@ private class GrapeHelperMethodTaintStep extends AdditionalTaintStep { exists(GrapeHelperMethod helperMethod, MethodCall call, int i | // Find calls to helper methods from within Grape endpoints call.getMethodName() = helperMethod.getName() and - exists(GrapeEndpoint endpoint | - call.getParent+() = endpoint.getBody().asExpr().getExpr() - ) and + exists(GrapeEndpoint endpoint | call.getParent+() = endpoint.getBody().asExpr().getExpr()) and // Map argument to parameter nodeFrom.asExpr().getExpr() = call.getArgument(i) and nodeTo.asParameter() = helperMethod.getParameter(i) ) } -} \ No newline at end of file +} diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql index ebfb304dbe7..c9aa7c29082 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql @@ -19,4 +19,4 @@ query predicate grapeRequest(GrapeRequestSource request) { any() } query predicate grapeRouteParam(GrapeRouteParamSource routeParam) { any() } -query predicate grapeCookies(GrapeCookiesSource cookies) { any() } \ No newline at end of file +query predicate grapeCookies(GrapeCookiesSource cookies) { any() } From 220197484489f80467cee4cfcb3e975ed018d0d2 Mon Sep 17 00:00:00 2001 From: Alex Eyers-Taylor Date: Thu, 21 Aug 2025 19:48:21 +0100 Subject: [PATCH 029/160] Jave: Use force local to make parsing local after global regex finding. --- .../semmle/code/java/regex/RegexFlowConfigs.qll | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll index 6a934bdd578..929fa2d6c91 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll @@ -163,6 +163,12 @@ private module RegexFlowConfig implements DataFlow::ConfigSig { private module RegexFlow = DataFlow::Global; +private predicate usedAsRegexImpl(StringLiteral regex, string mode, boolean match_full_string) { + RegexFlow::flow(DataFlow::exprNode(regex), _) and + mode = "None" and // TODO: proper mode detection + (if matchesFullString(regex) then match_full_string = true else match_full_string = false) +} + /** * Holds if `regex` is used as a regex, with the mode `mode` (if known). * If regex mode is not known, `mode` will be `"None"`. @@ -170,11 +176,9 @@ private module RegexFlow = DataFlow::Global; * As an optimisation, only regexes containing an infinite repitition quatifier (`+`, `*`, or `{x,}`) * and therefore may be relevant for ReDoS queries are considered. */ -predicate usedAsRegex(StringLiteral regex, string mode, boolean match_full_string) { - RegexFlow::flow(DataFlow::exprNode(regex), _) and - mode = "None" and // TODO: proper mode detection - (if matchesFullString(regex) then match_full_string = true else match_full_string = false) -} +overlay[local] +predicate usedAsRegex(StringLiteral regex, string mode, boolean match_full_string) = + forceLocal(usedAsRegexImpl/3)(regex, mode, match_full_string) /** * Holds if `regex` is used as a regular expression that is matched against a full string, From 6f1fcbf41bf7484025a208af19a19630dc3a4df9 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 16 Sep 2025 17:08:22 +0100 Subject: [PATCH 030/160] Rust: Add IPv6 private address range (and explanatory comments). --- rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll b/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll index 5e0d534fb7d..bd91cde238f 100644 --- a/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/UseOfHttpExtensions.qll @@ -36,9 +36,12 @@ module UseOfHttp { class HttpStringLiteral extends StringLiteralExpr { HttpStringLiteral() { exists(string s | this.getTextValue() = s | - // Match HTTP URLs that are not private/local + // match HTTP URLs s.regexpMatch("(?i)\"http://.*\"") and - not s.regexpMatch("(?i)\"http://(localhost|127\\.0\\.0\\.1|192\\.168\\.[0-9]+\\.[0-9]+|10\\.[0-9]+\\.[0-9]+\\.[0-9]+|172\\.(1[6-9]|2[0-9]|3[01])\\.[0-9]+|\\[::1\\]|\\[0:0:0:0:0:0:0:1\\]).*\"") + // exclude private/local addresses: + // - IPv4: localhost / 127.0.0.1, 192.168.x.x, 10.x.x.x, 172.16.x.x -> 172.31.x.x + // - IPv6 (address inside []): ::1 (or 0:0:0:0:0:0:0:1), fc00::/7 (i.e. anything beginning `fcxx:` or `fdxx:`) + not s.regexpMatch("(?i)\"http://(localhost|127\\.0\\.0\\.1|192\\.168\\.[0-9]+\\.[0-9]+|10\\.[0-9]+\\.[0-9]+\\.[0-9]+|172\\.(1[6-9]|2[0-9]|3[01])\\.[0-9]+|\\[::1\\]|\\[0:0:0:0:0:0:0:1\\]|\\[f[cd][0-9a-f]{2}:.*\\]).*\"") ) } } From c5e3be2c4cc30b1d8b92dfde67097577d4867dc0 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Tue, 16 Sep 2025 17:09:18 -0400 Subject: [PATCH 031/160] Grape - detect params calls inside helper methods - added unit tests for flow using inline format - removed grape from Arel tests (temporary) --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 28 ++++++- .../frameworks/grape/Flow.expected | 77 +++++++++++++++++++ .../library-tests/frameworks/grape/Flow.ql | 25 ++++++ .../frameworks/grape/Grape.expected | 16 ++++ .../library-tests/frameworks/grape/app.rb | 74 +++++++++++++++++- .../security/cwe-089/ArelInjection.rb | 64 +-------------- .../security/cwe-089/SqlInjection.expected | 66 ---------------- 7 files changed, 216 insertions(+), 134 deletions(-) create mode 100644 ruby/ql/test/library-tests/frameworks/grape/Flow.expected create mode 100644 ruby/ql/test/library-tests/frameworks/grape/Flow.ql diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index ea7bc8c576c..a1646b8654c 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -121,11 +121,18 @@ class GrapeParamsSource extends Http::Server::RequestInputAccess::Range { */ private class GrapeParamsCall extends ParamsCallImpl { GrapeParamsCall() { - // Simplified approach: find params calls that are descendants of Grape API class methods + // Params calls within endpoint blocks exists(GrapeApiClass api | this.getMethodName() = "params" and this.getParent+() = api.getADeclaration() ) + or + // Params calls within helper methods (defined in helpers blocks) + exists(GrapeApiClass api, DataFlow::CallNode helpersCall | + helpersCall = api.getAModuleLevelCall("helpers") and + this.getMethodName() = "params" and + this.getParent+() = helpersCall.getBlock().asExpr().getExpr() + ) } } @@ -295,18 +302,31 @@ private class GrapeHelperMethod extends Method { /** * Additional taint step to model dataflow from method arguments to parameters - * for Grape helper methods defined in `helpers` blocks. + * and from return values back to call sites for Grape helper methods defined in `helpers` blocks. * This bridges the gap where standard dataflow doesn't recognize the Grape DSL semantics. */ private class GrapeHelperMethodTaintStep extends AdditionalTaintStep { override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + // Map arguments to parameters for helper method calls exists(GrapeHelperMethod helperMethod, MethodCall call, int i | - // Find calls to helper methods from within Grape endpoints + // Find calls to helper methods from within Grape endpoints or other helper methods call.getMethodName() = helperMethod.getName() and - exists(GrapeEndpoint endpoint | call.getParent+() = endpoint.getBody().asExpr().getExpr()) and + exists(GrapeApiClass api | call.getParent+() = api.getADeclaration()) and // Map argument to parameter nodeFrom.asExpr().getExpr() = call.getArgument(i) and nodeTo.asParameter() = helperMethod.getParameter(i) ) + or + // Model implicit return values: the last expression in a helper method flows to the call site + exists(GrapeHelperMethod helperMethod, MethodCall helperCall, Expr lastExpr | + // Find calls to helper methods from within Grape endpoints or other helper methods + helperCall.getMethodName() = helperMethod.getName() and + exists(GrapeApiClass api | helperCall.getParent+() = api.getADeclaration()) and + // Get the last expression in the helper method (Ruby's implicit return) + lastExpr = helperMethod.getLastStmt() and + // Flow from the last expression in the helper method to the call site + nodeFrom.asExpr().getExpr() = lastExpr and + nodeTo.asExpr().getExpr() = helperCall + ) } } diff --git a/ruby/ql/test/library-tests/frameworks/grape/Flow.expected b/ruby/ql/test/library-tests/frameworks/grape/Flow.expected new file mode 100644 index 00000000000..0fd19d4eace --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/grape/Flow.expected @@ -0,0 +1,77 @@ +models +edges +| app.rb:103:13:103:18 | call to params | app.rb:103:13:103:70 | call to select | provenance | | +| app.rb:103:13:103:70 | call to select | app.rb:149:21:149:31 | call to user_params | provenance | AdditionalTaintStep | +| app.rb:103:13:103:70 | call to select | app.rb:165:21:165:31 | call to user_params | provenance | AdditionalTaintStep | +| app.rb:107:13:107:32 | call to source | app.rb:143:18:143:43 | call to vulnerable_helper | provenance | AdditionalTaintStep | +| app.rb:111:13:111:33 | call to source | app.rb:150:25:150:37 | call to simple_helper | provenance | AdditionalTaintStep | +| app.rb:126:9:126:15 | user_id | app.rb:133:14:133:20 | user_id | provenance | | +| app.rb:126:19:126:24 | call to params | app.rb:126:19:126:34 | ...[...] | provenance | | +| app.rb:126:19:126:34 | ...[...] | app.rb:126:9:126:15 | user_id | provenance | | +| app.rb:127:9:127:16 | route_id | app.rb:134:14:134:21 | route_id | provenance | | +| app.rb:127:20:127:40 | call to route_param | app.rb:127:9:127:16 | route_id | provenance | | +| app.rb:128:9:128:12 | auth | app.rb:135:14:135:17 | auth | provenance | | +| app.rb:128:16:128:22 | call to headers | app.rb:128:16:128:38 | ...[...] | provenance | | +| app.rb:128:16:128:38 | ...[...] | app.rb:128:9:128:12 | auth | provenance | | +| app.rb:129:9:129:15 | session | app.rb:136:14:136:20 | session | provenance | | +| app.rb:129:19:129:25 | call to cookies | app.rb:129:19:129:38 | ...[...] | provenance | | +| app.rb:129:19:129:38 | ...[...] | app.rb:129:9:129:15 | session | provenance | | +| app.rb:143:9:143:14 | result | app.rb:144:14:144:19 | result | provenance | | +| app.rb:143:18:143:43 | call to vulnerable_helper | app.rb:143:9:143:14 | result | provenance | | +| app.rb:149:9:149:17 | user_data | app.rb:151:14:151:22 | user_data | provenance | | +| app.rb:149:21:149:31 | call to user_params | app.rb:149:9:149:17 | user_data | provenance | | +| app.rb:150:9:150:21 | simple_result | app.rb:152:14:152:26 | simple_result | provenance | | +| app.rb:150:25:150:37 | call to simple_helper | app.rb:150:9:150:21 | simple_result | provenance | | +| app.rb:159:13:159:19 | user_id | app.rb:160:18:160:24 | user_id | provenance | | +| app.rb:159:23:159:28 | call to params | app.rb:159:23:159:33 | ...[...] | provenance | | +| app.rb:159:23:159:33 | ...[...] | app.rb:159:13:159:19 | user_id | provenance | | +| app.rb:165:9:165:17 | user_data | app.rb:166:14:166:22 | user_data | provenance | | +| app.rb:165:21:165:31 | call to user_params | app.rb:165:9:165:17 | user_data | provenance | | +nodes +| app.rb:103:13:103:18 | call to params | semmle.label | call to params | +| app.rb:103:13:103:70 | call to select | semmle.label | call to select | +| app.rb:107:13:107:32 | call to source | semmle.label | call to source | +| app.rb:111:13:111:33 | call to source | semmle.label | call to source | +| app.rb:126:9:126:15 | user_id | semmle.label | user_id | +| app.rb:126:19:126:24 | call to params | semmle.label | call to params | +| app.rb:126:19:126:34 | ...[...] | semmle.label | ...[...] | +| app.rb:127:9:127:16 | route_id | semmle.label | route_id | +| app.rb:127:20:127:40 | call to route_param | semmle.label | call to route_param | +| app.rb:128:9:128:12 | auth | semmle.label | auth | +| app.rb:128:16:128:22 | call to headers | semmle.label | call to headers | +| app.rb:128:16:128:38 | ...[...] | semmle.label | ...[...] | +| app.rb:129:9:129:15 | session | semmle.label | session | +| app.rb:129:19:129:25 | call to cookies | semmle.label | call to cookies | +| app.rb:129:19:129:38 | ...[...] | semmle.label | ...[...] | +| app.rb:133:14:133:20 | user_id | semmle.label | user_id | +| app.rb:134:14:134:21 | route_id | semmle.label | route_id | +| app.rb:135:14:135:17 | auth | semmle.label | auth | +| app.rb:136:14:136:20 | session | semmle.label | session | +| app.rb:143:9:143:14 | result | semmle.label | result | +| app.rb:143:18:143:43 | call to vulnerable_helper | semmle.label | call to vulnerable_helper | +| app.rb:144:14:144:19 | result | semmle.label | result | +| app.rb:149:9:149:17 | user_data | semmle.label | user_data | +| app.rb:149:21:149:31 | call to user_params | semmle.label | call to user_params | +| app.rb:150:9:150:21 | simple_result | semmle.label | simple_result | +| app.rb:150:25:150:37 | call to simple_helper | semmle.label | call to simple_helper | +| app.rb:151:14:151:22 | user_data | semmle.label | user_data | +| app.rb:152:14:152:26 | simple_result | semmle.label | simple_result | +| app.rb:159:13:159:19 | user_id | semmle.label | user_id | +| app.rb:159:23:159:28 | call to params | semmle.label | call to params | +| app.rb:159:23:159:33 | ...[...] | semmle.label | ...[...] | +| app.rb:160:18:160:24 | user_id | semmle.label | user_id | +| app.rb:165:9:165:17 | user_data | semmle.label | user_data | +| app.rb:165:21:165:31 | call to user_params | semmle.label | call to user_params | +| app.rb:166:14:166:22 | user_data | semmle.label | user_data | +subpaths +testFailures +#select +| app.rb:133:14:133:20 | user_id | app.rb:126:19:126:24 | call to params | app.rb:133:14:133:20 | user_id | $@ | app.rb:126:19:126:24 | call to params | call to params | +| app.rb:134:14:134:21 | route_id | app.rb:127:20:127:40 | call to route_param | app.rb:134:14:134:21 | route_id | $@ | app.rb:127:20:127:40 | call to route_param | call to route_param | +| app.rb:135:14:135:17 | auth | app.rb:128:16:128:22 | call to headers | app.rb:135:14:135:17 | auth | $@ | app.rb:128:16:128:22 | call to headers | call to headers | +| app.rb:136:14:136:20 | session | app.rb:129:19:129:25 | call to cookies | app.rb:136:14:136:20 | session | $@ | app.rb:129:19:129:25 | call to cookies | call to cookies | +| app.rb:144:14:144:19 | result | app.rb:107:13:107:32 | call to source | app.rb:144:14:144:19 | result | $@ | app.rb:107:13:107:32 | call to source | call to source | +| app.rb:151:14:151:22 | user_data | app.rb:103:13:103:18 | call to params | app.rb:151:14:151:22 | user_data | $@ | app.rb:103:13:103:18 | call to params | call to params | +| app.rb:152:14:152:26 | simple_result | app.rb:111:13:111:33 | call to source | app.rb:152:14:152:26 | simple_result | $@ | app.rb:111:13:111:33 | call to source | call to source | +| app.rb:160:18:160:24 | user_id | app.rb:159:23:159:28 | call to params | app.rb:160:18:160:24 | user_id | $@ | app.rb:159:23:159:28 | call to params | call to params | +| app.rb:166:14:166:22 | user_data | app.rb:103:13:103:18 | call to params | app.rb:166:14:166:22 | user_data | $@ | app.rb:103:13:103:18 | call to params | call to params | diff --git a/ruby/ql/test/library-tests/frameworks/grape/Flow.ql b/ruby/ql/test/library-tests/frameworks/grape/Flow.ql new file mode 100644 index 00000000000..baa3fa4307f --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/grape/Flow.ql @@ -0,0 +1,25 @@ +/** + * @kind path-problem + */ + +import ruby +import utils.test.InlineFlowTest +import PathGraph +import codeql.ruby.frameworks.Grape +import codeql.ruby.Concepts + +module GrapeConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node source) { + source instanceof Http::Server::RequestInputAccess::Range + or + DefaultFlowConfig::isSource(source) + } + + predicate isSink(DataFlow::Node sink) { DefaultFlowConfig::isSink(sink) } +} + +import FlowTest + +from PathNode source, PathNode sink +where flowPath(source, sink) +select sink, source, sink, "$@", source, source.toString() diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.expected b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected index af4d936e88d..d39d9430f92 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Grape.expected +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected @@ -1,6 +1,7 @@ grapeApiClasses | app.rb:1:1:90:3 | MyAPI | | app.rb:92:1:96:3 | AdminAPI | +| app.rb:98:1:168:3 | UserAPI | grapeEndpoints | app.rb:1:1:90:3 | MyAPI | app.rb:7:3:11:5 | call to get | GET | /hello/:name | | app.rb:1:1:90:3 | MyAPI | app.rb:17:3:20:5 | call to post | POST | /messages | @@ -13,6 +14,10 @@ grapeEndpoints | app.rb:1:1:90:3 | MyAPI | app.rb:78:3:82:5 | call to get | GET | /cookie_test | | app.rb:1:1:90:3 | MyAPI | app.rb:85:3:89:5 | call to get | GET | /header_test | | app.rb:92:1:96:3 | AdminAPI | app.rb:93:3:95:5 | call to get | GET | /admin | +| app.rb:98:1:168:3 | UserAPI | app.rb:124:5:138:7 | call to get | GET | /comprehensive_test/:user_id | +| app.rb:98:1:168:3 | UserAPI | app.rb:140:5:145:7 | call to get | GET | /helper_test/:user_id | +| app.rb:98:1:168:3 | UserAPI | app.rb:147:5:153:7 | call to post | POST | /users | +| app.rb:98:1:168:3 | UserAPI | app.rb:164:5:167:7 | call to post | POST | /users | grapeParams | app.rb:8:12:8:17 | call to params | | app.rb:14:3:16:5 | call to params | @@ -22,19 +27,30 @@ grapeParams | app.rb:36:5:36:10 | call to params | | app.rb:60:12:60:17 | call to params | | app.rb:94:5:94:10 | call to params | +| app.rb:103:13:103:18 | call to params | +| app.rb:126:19:126:24 | call to params | +| app.rb:142:19:142:24 | call to params | +| app.rb:159:23:159:28 | call to params | grapeHeaders | app.rb:9:18:9:24 | call to headers | | app.rb:46:5:46:11 | call to headers | | app.rb:66:3:69:5 | call to headers | | app.rb:86:12:86:18 | call to headers | | app.rb:87:14:87:20 | call to headers | +| app.rb:116:5:118:7 | call to headers | +| app.rb:128:16:128:22 | call to headers | grapeRequest | app.rb:25:12:25:18 | call to request | +| app.rb:130:21:130:27 | call to request | grapeRouteParam | app.rb:51:15:51:35 | call to route_param | | app.rb:52:15:52:36 | call to route_param | | app.rb:57:3:63:5 | call to route_param | +| app.rb:127:20:127:40 | call to route_param | +| app.rb:156:5:162:7 | call to route_param | grapeCookies | app.rb:72:3:75:5 | call to cookies | | app.rb:79:15:79:21 | call to cookies | | app.rb:80:16:80:22 | call to cookies | +| app.rb:120:5:122:7 | call to cookies | +| app.rb:129:19:129:25 | call to cookies | diff --git a/ruby/ql/test/library-tests/frameworks/grape/app.rb b/ruby/ql/test/library-tests/frameworks/grape/app.rb index a034f325f7b..6fbb184cab9 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/app.rb +++ b/ruby/ql/test/library-tests/frameworks/grape/app.rb @@ -93,4 +93,76 @@ class AdminAPI < Grape::API get '/admin' do params[:token] end -end \ No newline at end of file +end + +class UserAPI < Grape::API + VALID_PARAMS = %w(name email password password_confirmation) + + helpers do + def user_params + params.select{|key,value| VALID_PARAMS.include?(key.to_s)} # Real helper implementation + end + + def vulnerable_helper(user_id) + source "paramHelper" # Test parameter passing to helper + end + + def simple_helper + source "simpleHelper" # Test simple helper return + end + end + + # Headers and cookies blocks for DSL testing + headers do + requires :Authorization, type: String + end + + cookies do + requires :session_id, type: String + end + + get '/comprehensive_test/:user_id' do + # Test all Grape input sources + user_id = params[:user_id] # params taint source + route_id = route_param(:user_id) # route_param taint source + auth = headers[:Authorization] # headers taint source + session = cookies[:session_id] # cookies taint source + body_data = request.body.read # request taint source + + # Test sinks for all sources + sink user_id # $ hasTaintFlow + sink route_id # $ hasTaintFlow + sink auth # $ hasTaintFlow + sink session # $ hasTaintFlow + # Note: request.body.read may not be detected by this flow test config + end + + get '/helper_test/:user_id' do + # Test helper method parameter passing dataflow + user_id = params[:user_id] + result = vulnerable_helper(user_id) + sink result # $ hasTaintFlow=paramHelper + end + + post '/users' do + # Test helper method return dataflow + user_data = user_params + simple_result = simple_helper + sink user_data # $ hasTaintFlow + sink simple_result # $ hasTaintFlow=simpleHelper + end + + # Test route_param block pattern + route_param :id do + get do + # params[:id] should be user input from the path + user_id = params[:id] + sink user_id # $ hasTaintFlow + end + end + + post '/users' do + user_data = user_params + sink user_data # $ hasTaintFlow + end +end diff --git a/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb index 8c9c3bff4fb..1cd6782b241 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb +++ b/ruby/ql/test/query-tests/security/cwe-089/ArelInjection.rb @@ -6,66 +6,4 @@ class PotatoController < ActionController::Base sql = Arel.sql("SELECT * FROM users WHERE name = #{name}") sql = Arel::Nodes::SqlLiteral.new("SELECT * FROM users WHERE name = #{name}") end -end - -class PotatoAPI < Grape::API - get '/unsafe_endpoint' do - name = params[:user_name] - # BAD: SQL statement constructed from user input - sql = Arel.sql("SELECT * FROM users WHERE name = #{name}") - sql = Arel::Nodes::SqlLiteral.new("SELECT * FROM users WHERE name = #{name}") - end -end - -class SimpleAPI < Grape::API - get '/test' do - x = params[:name] - Arel.sql("SELECT * FROM users WHERE name = #{x}") - end -end - - # Test helper method pattern in Grape helpers block - class TestAPI < Grape::API - helpers do - def vulnerable_helper(user_id) - # BAD: SQL statement constructed from user input passed as parameter - Arel.sql("SELECT * FROM users WHERE id = #{user_id}") - end - end - - # Headers and cookies blocks for DSL testing - headers do - requires :Authorization, type: String - end - - cookies do - requires :session_id, type: String - end - - get '/comprehensive_test/:user_id' do - # BAD: Comprehensive test using all Grape input sources in one SQL query - user_id = params[:user_id] # params taint source - route_id = route_param(:user_id) # route_param taint source - auth = headers[:Authorization] # headers taint source - session = cookies[:session_id] # cookies taint source - body_data = request.body.read # request taint source - - # All sources flow to SQL injection - Arel.sql("SELECT * FROM users WHERE id = #{user_id} AND route_id = #{route_id} AND auth = #{auth} AND session = #{session} AND data = #{body_data}") - end - - get '/helper_test' do - # BAD: Test helper method dataflow - user_id = params[:user_id] - vulnerable_helper(user_id) - end - - # Test route_param block pattern - route_param :id do - get do - # BAD: params[:id] should be user input from the path - user_id = params[:id] - Arel.sql("SELECT * FROM users WHERE id = #{user_id}") - end - end - end \ No newline at end of file +end \ No newline at end of file diff --git a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected index 34128474cb9..069cb34810f 100644 --- a/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected +++ b/ruby/ql/test/query-tests/security/cwe-089/SqlInjection.expected @@ -81,32 +81,6 @@ edges | ArelInjection.rb:4:5:4:8 | name | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | provenance | AdditionalTaintStep | | ArelInjection.rb:4:12:4:17 | call to params | ArelInjection.rb:4:12:4:29 | ...[...] | provenance | | | ArelInjection.rb:4:12:4:29 | ...[...] | ArelInjection.rb:4:5:4:8 | name | provenance | | -| ArelInjection.rb:13:5:13:8 | name | ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | provenance | AdditionalTaintStep | -| ArelInjection.rb:13:5:13:8 | name | ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | provenance | AdditionalTaintStep | -| ArelInjection.rb:13:12:13:17 | call to params | ArelInjection.rb:13:12:13:29 | ...[...] | provenance | | -| ArelInjection.rb:13:12:13:29 | ...[...] | ArelInjection.rb:13:5:13:8 | name | provenance | | -| ArelInjection.rb:22:5:22:5 | x | ArelInjection.rb:23:14:23:52 | "SELECT * FROM users WHERE nam..." | provenance | AdditionalTaintStep | -| ArelInjection.rb:22:9:22:14 | call to params | ArelInjection.rb:22:9:22:21 | ...[...] | provenance | | -| ArelInjection.rb:22:9:22:21 | ...[...] | ArelInjection.rb:22:5:22:5 | x | provenance | | -| ArelInjection.rb:30:29:30:35 | user_id | ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | -| ArelInjection.rb:47:7:47:13 | user_id | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | -| ArelInjection.rb:47:17:47:22 | call to params | ArelInjection.rb:47:17:47:32 | ...[...] | provenance | | -| ArelInjection.rb:47:17:47:32 | ...[...] | ArelInjection.rb:47:7:47:13 | user_id | provenance | | -| ArelInjection.rb:48:7:48:14 | route_id | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | -| ArelInjection.rb:48:18:48:38 | call to route_param | ArelInjection.rb:48:7:48:14 | route_id | provenance | | -| ArelInjection.rb:49:7:49:10 | auth | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | -| ArelInjection.rb:49:14:49:20 | call to headers | ArelInjection.rb:49:14:49:36 | ...[...] | provenance | | -| ArelInjection.rb:49:14:49:36 | ...[...] | ArelInjection.rb:49:7:49:10 | auth | provenance | | -| ArelInjection.rb:50:7:50:13 | session | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | -| ArelInjection.rb:50:17:50:23 | call to cookies | ArelInjection.rb:50:17:50:36 | ...[...] | provenance | | -| ArelInjection.rb:50:17:50:36 | ...[...] | ArelInjection.rb:50:7:50:13 | session | provenance | | -| ArelInjection.rb:59:7:59:13 | user_id | ArelInjection.rb:60:25:60:31 | user_id | provenance | | -| ArelInjection.rb:59:17:59:22 | call to params | ArelInjection.rb:59:17:59:32 | ...[...] | provenance | | -| ArelInjection.rb:59:17:59:32 | ...[...] | ArelInjection.rb:59:7:59:13 | user_id | provenance | | -| ArelInjection.rb:60:25:60:31 | user_id | ArelInjection.rb:30:29:30:35 | user_id | provenance | AdditionalTaintStep | -| ArelInjection.rb:67:9:67:15 | user_id | ArelInjection.rb:68:18:68:60 | "SELECT * FROM users WHERE id ..." | provenance | AdditionalTaintStep | -| ArelInjection.rb:67:19:67:24 | call to params | ArelInjection.rb:67:19:67:29 | ...[...] | provenance | | -| ArelInjection.rb:67:19:67:29 | ...[...] | ArelInjection.rb:67:9:67:15 | user_id | provenance | | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:13:5:13:8 | qry1 : String | provenance | AdditionalTaintStep | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:19:5:19:8 | qry2 : String | provenance | AdditionalTaintStep | | PgInjection.rb:6:5:6:8 | name | PgInjection.rb:31:5:31:8 | qry3 : String | provenance | AdditionalTaintStep | @@ -235,37 +209,6 @@ nodes | ArelInjection.rb:4:12:4:29 | ...[...] | semmle.label | ...[...] | | ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | -| ArelInjection.rb:13:5:13:8 | name | semmle.label | name | -| ArelInjection.rb:13:12:13:17 | call to params | semmle.label | call to params | -| ArelInjection.rb:13:12:13:29 | ...[...] | semmle.label | ...[...] | -| ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | -| ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | -| ArelInjection.rb:22:5:22:5 | x | semmle.label | x | -| ArelInjection.rb:22:9:22:14 | call to params | semmle.label | call to params | -| ArelInjection.rb:22:9:22:21 | ...[...] | semmle.label | ...[...] | -| ArelInjection.rb:23:14:23:52 | "SELECT * FROM users WHERE nam..." | semmle.label | "SELECT * FROM users WHERE nam..." | -| ArelInjection.rb:30:29:30:35 | user_id | semmle.label | user_id | -| ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | semmle.label | "SELECT * FROM users WHERE id ..." | -| ArelInjection.rb:47:7:47:13 | user_id | semmle.label | user_id | -| ArelInjection.rb:47:17:47:22 | call to params | semmle.label | call to params | -| ArelInjection.rb:47:17:47:32 | ...[...] | semmle.label | ...[...] | -| ArelInjection.rb:48:7:48:14 | route_id | semmle.label | route_id | -| ArelInjection.rb:48:18:48:38 | call to route_param | semmle.label | call to route_param | -| ArelInjection.rb:49:7:49:10 | auth | semmle.label | auth | -| ArelInjection.rb:49:14:49:20 | call to headers | semmle.label | call to headers | -| ArelInjection.rb:49:14:49:36 | ...[...] | semmle.label | ...[...] | -| ArelInjection.rb:50:7:50:13 | session | semmle.label | session | -| ArelInjection.rb:50:17:50:23 | call to cookies | semmle.label | call to cookies | -| ArelInjection.rb:50:17:50:36 | ...[...] | semmle.label | ...[...] | -| ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | semmle.label | "SELECT * FROM users WHERE id ..." | -| ArelInjection.rb:59:7:59:13 | user_id | semmle.label | user_id | -| ArelInjection.rb:59:17:59:22 | call to params | semmle.label | call to params | -| ArelInjection.rb:59:17:59:32 | ...[...] | semmle.label | ...[...] | -| ArelInjection.rb:60:25:60:31 | user_id | semmle.label | user_id | -| ArelInjection.rb:67:9:67:15 | user_id | semmle.label | user_id | -| ArelInjection.rb:67:19:67:24 | call to params | semmle.label | call to params | -| ArelInjection.rb:67:19:67:29 | ...[...] | semmle.label | ...[...] | -| ArelInjection.rb:68:18:68:60 | "SELECT * FROM users WHERE id ..." | semmle.label | "SELECT * FROM users WHERE id ..." | | PgInjection.rb:6:5:6:8 | name | semmle.label | name | | PgInjection.rb:6:12:6:17 | call to params | semmle.label | call to params | | PgInjection.rb:6:12:6:24 | ...[...] | semmle.label | ...[...] | @@ -323,15 +266,6 @@ subpaths | ActiveRecordInjection.rb:216:38:216:53 | "role = #{...}" | ActiveRecordInjection.rb:222:29:222:34 | call to params | ActiveRecordInjection.rb:216:38:216:53 | "role = #{...}" | This SQL query depends on a $@. | ActiveRecordInjection.rb:222:29:222:34 | call to params | user-provided value | | ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:4:12:4:17 | call to params | ArelInjection.rb:6:20:6:61 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:4:12:4:17 | call to params | user-provided value | | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:4:12:4:17 | call to params | ArelInjection.rb:7:39:7:80 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:4:12:4:17 | call to params | user-provided value | -| ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:13:12:13:17 | call to params | ArelInjection.rb:15:20:15:61 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:13:12:13:17 | call to params | user-provided value | -| ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:13:12:13:17 | call to params | ArelInjection.rb:16:39:16:80 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:13:12:13:17 | call to params | user-provided value | -| ArelInjection.rb:23:14:23:52 | "SELECT * FROM users WHERE nam..." | ArelInjection.rb:22:9:22:14 | call to params | ArelInjection.rb:23:14:23:52 | "SELECT * FROM users WHERE nam..." | This SQL query depends on a $@. | ArelInjection.rb:22:9:22:14 | call to params | user-provided value | -| ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:59:17:59:22 | call to params | ArelInjection.rb:32:18:32:60 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:59:17:59:22 | call to params | user-provided value | -| ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:47:17:47:22 | call to params | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:47:17:47:22 | call to params | user-provided value | -| ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:48:18:48:38 | call to route_param | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:48:18:48:38 | call to route_param | user-provided value | -| ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:49:14:49:20 | call to headers | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:49:14:49:20 | call to headers | user-provided value | -| ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:50:17:50:23 | call to cookies | ArelInjection.rb:54:16:54:153 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:50:17:50:23 | call to cookies | user-provided value | -| ArelInjection.rb:68:18:68:60 | "SELECT * FROM users WHERE id ..." | ArelInjection.rb:67:19:67:24 | call to params | ArelInjection.rb:68:18:68:60 | "SELECT * FROM users WHERE id ..." | This SQL query depends on a $@. | ArelInjection.rb:67:19:67:24 | call to params | user-provided value | | PgInjection.rb:14:15:14:18 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:14:15:14:18 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | | PgInjection.rb:15:21:15:24 | qry1 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:15:21:15:24 | qry1 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | | PgInjection.rb:20:22:20:25 | qry2 | PgInjection.rb:6:12:6:17 | call to params | PgInjection.rb:20:22:20:25 | qry2 | This SQL query depends on a $@. | PgInjection.rb:6:12:6:17 | call to params | user-provided value | From 1bccf42556fa214a6e7d44e3f0322cc09d008b09 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:59:54 +0100 Subject: [PATCH 032/160] Rust: Update test results following fix on main. --- .../library-tests/dataflow/local/DataFlowStep.expected | 5 +++-- .../library-tests/dataflow/local/inline-flow.expected | 8 ++++++++ rust/ql/test/library-tests/dataflow/local/main.rs | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 0af30149e74..b2fc845081c 100644 --- a/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/rust/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -111,11 +111,12 @@ localStep | main.rs:77:9:77:9 | k | main.rs:77:5:77:5 | j | | main.rs:77:9:77:9 | k | main.rs:79:10:79:10 | k | | main.rs:81:9:81:13 | mut l | main.rs:81:13:81:13 | l | +| main.rs:81:13:81:13 | [SSA] l | main.rs:82:9:82:9 | l | +| main.rs:81:13:81:13 | l | main.rs:81:13:81:13 | [SSA] l | | main.rs:81:17:81:25 | source(...) | main.rs:81:9:81:13 | mut l | -| main.rs:82:5:82:5 | [SSA] l | main.rs:82:9:82:9 | l | +| main.rs:82:5:82:5 | [SSA] l | main.rs:83:10:83:10 | l | | main.rs:82:5:82:5 | l | main.rs:82:5:82:5 | [SSA] l | | main.rs:82:9:82:9 | l | main.rs:82:5:82:5 | l | -| main.rs:82:9:82:9 | l | main.rs:83:10:83:10 | l | | main.rs:87:9:87:9 | [SSA] a | main.rs:88:5:88:5 | a | | main.rs:87:9:87:9 | a | main.rs:87:9:87:9 | [SSA] a | | main.rs:87:9:87:9 | a | main.rs:87:9:87:9 | a | diff --git a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected index eafe3a7452e..00640ed9aa4 100644 --- a/rust/ql/test/library-tests/dataflow/local/inline-flow.expected +++ b/rust/ql/test/library-tests/dataflow/local/inline-flow.expected @@ -31,6 +31,9 @@ edges | main.rs:76:9:76:9 | k | main.rs:79:10:79:10 | k | provenance | | | main.rs:76:13:76:21 | source(...) | main.rs:76:9:76:9 | k | provenance | | | main.rs:77:5:77:5 | j | main.rs:78:10:78:10 | j | provenance | | +| main.rs:81:9:81:13 | mut l | main.rs:82:5:82:5 | l | provenance | | +| main.rs:81:17:81:25 | source(...) | main.rs:81:9:81:13 | mut l | provenance | | +| main.rs:82:5:82:5 | l | main.rs:83:10:83:10 | l | provenance | | | main.rs:115:9:115:9 | i [&ref] | main.rs:116:11:116:11 | i [&ref] | provenance | | | main.rs:115:13:115:31 | ...::new(...) [&ref] | main.rs:115:9:115:9 | i [&ref] | provenance | | | main.rs:115:22:115:30 | source(...) | main.rs:115:13:115:31 | ...::new(...) [&ref] | provenance | MaD:1 | @@ -279,6 +282,10 @@ nodes | main.rs:77:5:77:5 | j | semmle.label | j | | main.rs:78:10:78:10 | j | semmle.label | j | | main.rs:79:10:79:10 | k | semmle.label | k | +| main.rs:81:9:81:13 | mut l | semmle.label | mut l | +| main.rs:81:17:81:25 | source(...) | semmle.label | source(...) | +| main.rs:82:5:82:5 | l | semmle.label | l | +| main.rs:83:10:83:10 | l | semmle.label | l | | main.rs:115:9:115:9 | i [&ref] | semmle.label | i [&ref] | | main.rs:115:13:115:31 | ...::new(...) [&ref] | semmle.label | ...::new(...) [&ref] | | main.rs:115:22:115:30 | source(...) | semmle.label | source(...) | @@ -553,6 +560,7 @@ testFailures | main.rs:71:10:71:10 | i | main.rs:70:9:70:17 | source(...) | main.rs:71:10:71:10 | i | $@ | main.rs:70:9:70:17 | source(...) | source(...) | | main.rs:78:10:78:10 | j | main.rs:76:13:76:21 | source(...) | main.rs:78:10:78:10 | j | $@ | main.rs:76:13:76:21 | source(...) | source(...) | | main.rs:79:10:79:10 | k | main.rs:76:13:76:21 | source(...) | main.rs:79:10:79:10 | k | $@ | main.rs:76:13:76:21 | source(...) | source(...) | +| main.rs:83:10:83:10 | l | main.rs:81:17:81:25 | source(...) | main.rs:83:10:83:10 | l | $@ | main.rs:81:17:81:25 | source(...) | source(...) | | main.rs:116:10:116:11 | * ... | main.rs:115:22:115:30 | source(...) | main.rs:116:10:116:11 | * ... | $@ | main.rs:115:22:115:30 | source(...) | source(...) | | main.rs:124:10:124:12 | a.0 | main.rs:123:14:123:22 | source(...) | main.rs:124:10:124:12 | a.0 | $@ | main.rs:123:14:123:22 | source(...) | source(...) | | main.rs:132:10:132:11 | a1 | main.rs:129:17:129:26 | source(...) | main.rs:132:10:132:11 | a1 | $@ | main.rs:129:17:129:26 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/local/main.rs b/rust/ql/test/library-tests/dataflow/local/main.rs index d352eb0cbf1..7cab42da52b 100644 --- a/rust/ql/test/library-tests/dataflow/local/main.rs +++ b/rust/ql/test/library-tests/dataflow/local/main.rs @@ -80,7 +80,7 @@ fn assignment() { let mut l = source(8); l = l; - sink(l); // $ MISSING: hasValueFlow=8 + sink(l); // $ hasValueFlow=8 } fn block_expression1() -> i64 { From 34b40a14e876481909726ce811663a9683d1d62a Mon Sep 17 00:00:00 2001 From: Alex Eyers-Taylor Date: Wed, 17 Sep 2025 16:22:22 +0100 Subject: [PATCH 033/160] Java: Make a TC overlay caller. --- java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll index 4b436edc6aa..23e9f680c97 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -83,6 +83,7 @@ overlay[caller?] pragma[inline] predicate localFlow(Node node1, Node node2) { node1 = node2 or localFlowStepPlus(node1, node2) } +overlay[caller?] private predicate localFlowStepPlus(Node node1, Node node2) = fastTC(localFlowStep/2)(node1, node2) /** From 3cd737e40d43fe5108a2f5710bb733e2c37ce454 Mon Sep 17 00:00:00 2001 From: Kasper Svendsen Date: Thu, 18 Sep 2025 10:32:20 +0200 Subject: [PATCH 034/160] Overlay: Future-proof Java config discarding --- java/ql/lib/semmle/code/java/Overlay.qll | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/java/ql/lib/semmle/code/java/Overlay.qll b/java/ql/lib/semmle/code/java/Overlay.qll index 1d1a3896ba7..27e8badc233 100644 --- a/java/ql/lib/semmle/code/java/Overlay.qll +++ b/java/ql/lib/semmle/code/java/Overlay.qll @@ -73,22 +73,24 @@ private predicate discardReferableLocatable(@locatable el) { ) } +/** Gets the raw file for a configLocatable. */ overlay[local] -private predicate baseConfigLocatable(@configLocatable l) { not isOverlay() and exists(l) } +private string getRawFileForConfig(@configLocatable el) { + exists(@location loc, @file file | + configLocations(el, loc) and + locations_default(loc, file, _, _, _, _) and + files(file, result) + ) +} overlay[local] -private predicate overlayHasConfigLocatables() { - isOverlay() and - exists(@configLocatable el) +private string baseConfigLocatable(@configLocatable el) { + not isOverlay() and result = getRawFileForConfig(el) } overlay[discard_entity] private predicate discardBaseConfigLocatable(@configLocatable el) { - // The properties extractor is currently not incremental, so if - // the overlay contains any config locatables, the overlay should - // contain a full extraction and all config locatables from base - // should be discarded. - baseConfigLocatable(el) and overlayHasConfigLocatables() + overlayChangedFiles(baseConfigLocatable(el)) } overlay[local] From dbb9a26f78938a5ddd4763d56e9c7cdb54f204c5 Mon Sep 17 00:00:00 2001 From: Kasper Svendsen Date: Thu, 18 Sep 2025 10:35:11 +0200 Subject: [PATCH 035/160] Overlay: Future-proof Java XML discarding --- java/ql/lib/semmle/code/java/Overlay.qll | 22 +--------------------- java/ql/lib/semmle/code/xml/XML.qll | 11 +++++++++++ 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/java/ql/lib/semmle/code/java/Overlay.qll b/java/ql/lib/semmle/code/java/Overlay.qll index 27e8badc233..0f6033d87b3 100644 --- a/java/ql/lib/semmle/code/java/Overlay.qll +++ b/java/ql/lib/semmle/code/java/Overlay.qll @@ -18,7 +18,7 @@ predicate isOverlay() { databaseMetadata("isOverlay", "true") } overlay[local] string getRawFile(@locatable el) { exists(@location loc, @file file | - hasLocation(el, loc) and + (hasLocation(el, loc) or xmllocations(el, loc)) and locations_default(loc, file, _, _, _, _) and files(file, result) ) @@ -92,23 +92,3 @@ overlay[discard_entity] private predicate discardBaseConfigLocatable(@configLocatable el) { overlayChangedFiles(baseConfigLocatable(el)) } - -overlay[local] -private predicate baseXmlLocatable(@xmllocatable l) { - not isOverlay() and not files(l, _) and not xmlNs(l, _, _, _) -} - -overlay[local] -private predicate overlayHasXmlLocatable() { - isOverlay() and - exists(@xmllocatable l | not files(l, _) and not xmlNs(l, _, _, _)) -} - -overlay[discard_entity] -private predicate discardBaseXmlLocatable(@xmllocatable el) { - // The XML extractor is currently not incremental, so if - // the overlay contains any XML locatables, the overlay should - // contain a full extraction and all XML locatables from base - // should be discarded. - baseXmlLocatable(el) and overlayHasXmlLocatable() -} diff --git a/java/ql/lib/semmle/code/xml/XML.qll b/java/ql/lib/semmle/code/xml/XML.qll index e4073362fc6..cd00991eb65 100644 --- a/java/ql/lib/semmle/code/xml/XML.qll +++ b/java/ql/lib/semmle/code/xml/XML.qll @@ -6,6 +6,7 @@ module; import semmle.files.FileSystem private import codeql.xml.Xml +private import semmle.code.java.Overlay private module Input implements InputSig { class XmlLocatableBase = @xmllocatable or @xmlnamespaceable; @@ -69,3 +70,13 @@ private module Input implements InputSig { } import Make + +private class DiscardableXmlAttribute extends DiscardableLocatable, @xmlattribute { } + +private class DiscardableXmlElement extends DiscardableLocatable, @xmlelement { } + +private class DiscardableXmlComment extends DiscardableLocatable, @xmlcomment { } + +private class DiscardableXmlCharacters extends DiscardableLocatable, @xmlcharacters { } + +private class DiscardableXmlDtd extends DiscardableLocatable, @xmldtd { } From c831a8c2d92d7dd7be628f16b3df9eb528184868 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 17 Sep 2025 13:43:24 +0200 Subject: [PATCH 036/160] Rust: Add more path resolution tests --- .../PathResolutionConsistency.expected | 3 +- .../library-tests/path-resolution/main.rs | 10 +- .../library-tests/path-resolution/my2/mod.rs | 10 +- .../path-resolution/my2/my3/mod.rs | 2 + .../path-resolution/path-resolution.expected | 813 +++++++++--------- 5 files changed, 431 insertions(+), 407 deletions(-) diff --git a/rust/ql/test/library-tests/path-resolution/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/library-tests/path-resolution/CONSISTENCY/PathResolutionConsistency.expected index 9d1761069fe..d945cb4c6c2 100644 --- a/rust/ql/test/library-tests/path-resolution/CONSISTENCY/PathResolutionConsistency.expected +++ b/rust/ql/test/library-tests/path-resolution/CONSISTENCY/PathResolutionConsistency.expected @@ -1,3 +1,4 @@ multipleCallTargets -| main.rs:118:9:118:11 | f(...) | +| main.rs:124:9:124:11 | f(...) | +| main.rs:774:5:774:7 | f(...) | | proc_macro.rs:9:5:9:10 | ...::new(...) | diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs index 1de91a60fe4..db8e4c0f39d 100644 --- a/rust/ql/test/library-tests/path-resolution/main.rs +++ b/rust/ql/test/library-tests/path-resolution/main.rs @@ -8,7 +8,13 @@ mod my2; // I14 use my2::*; // $ item=I14 -use my2::nested2::nested3::nested4::{f, g}; // $ item=I11 item=I12 item=I13 +#[rustfmt::skip] +use my2::nested2::nested3::nested4::{ // $ item=I11 + f, // $ item=I12 + g, // $ item=I13 +}; + +use my2::nested8_f; // $ item=I119 mod m1 { fn f() { @@ -765,7 +771,7 @@ fn main() { my::nested::nested1::nested2::f(); // $ item=I4 my::f(); // $ item=I38 nested2::nested3::nested4::f(); // $ item=I12 - f(); // $ item=I12 + f(); // $ item=I12 $ SPURIOUS: item=I119 g(); // $ item=I13 crate::h(); // $ item=I25 m1::m2::g(); // $ item=I19 diff --git a/rust/ql/test/library-tests/path-resolution/my2/mod.rs b/rust/ql/test/library-tests/path-resolution/my2/mod.rs index 43c1a05e91f..85edb683202 100644 --- a/rust/ql/test/library-tests/path-resolution/my2/mod.rs +++ b/rust/ql/test/library-tests/path-resolution/my2/mod.rs @@ -7,11 +7,17 @@ fn g() { pub use nested2::nested5::*; // $ item=I114 -pub use nested2::nested7::nested8::{self}; // $ item=I118 +#[rustfmt::skip] +pub use nested2::nested7::nested8::{ // $ item=I118 + self, // $ item=I118 + f as nested8_f // $ item=I119 +}; + +use nested2::nested5::nested6::f as nested6_f; // $ item=I116 pub mod my3; #[path = "renamed.rs"] mod mymod; -use mymod::f; // $ item=I1001 +pub use mymod::f; // $ item=I1001 diff --git a/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs b/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs index 6b54377728b..e2d413841c3 100644 --- a/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs +++ b/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs @@ -6,3 +6,5 @@ pub fn f() { use super::super::h; // $ item=I25 use super::g; // $ item=I9 + +use super::nested6_f; // $ MISSING: item=I116 diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected index a51816a5228..8f12af96c02 100644 --- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected +++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected @@ -2,38 +2,38 @@ mod | lib.rs:1:1:1:11 | mod my | | main.rs:1:1:1:7 | mod my | | main.rs:7:1:7:8 | mod my2 | -| main.rs:13:1:37:1 | mod m1 | -| main.rs:18:5:36:5 | mod m2 | -| main.rs:29:9:35:9 | mod m3 | -| main.rs:39:1:46:1 | mod m4 | -| main.rs:103:1:107:1 | mod m5 | -| main.rs:109:1:120:1 | mod m6 | -| main.rs:122:1:141:1 | mod m7 | -| main.rs:143:1:197:1 | mod m8 | -| main.rs:199:1:207:1 | mod m9 | -| main.rs:209:1:228:1 | mod m10 | -| main.rs:230:1:267:1 | mod m11 | -| main.rs:240:5:240:12 | mod f | -| main.rs:269:1:281:1 | mod m12 | -| main.rs:283:1:296:1 | mod m13 | -| main.rs:287:5:295:5 | mod m14 | -| main.rs:298:1:367:1 | mod m15 | -| main.rs:369:1:461:1 | mod m16 | -| main.rs:463:1:513:1 | mod trait_visibility | -| main.rs:464:5:486:5 | mod m | -| main.rs:515:1:545:1 | mod m17 | -| main.rs:547:1:565:1 | mod m18 | -| main.rs:552:5:564:5 | mod m19 | -| main.rs:557:9:563:9 | mod m20 | -| main.rs:567:1:592:1 | mod m21 | -| main.rs:568:5:574:5 | mod m22 | -| main.rs:576:5:591:5 | mod m33 | -| main.rs:594:1:619:1 | mod m23 | -| main.rs:621:1:689:1 | mod m24 | -| main.rs:706:1:758:1 | mod associated_types | +| main.rs:19:1:43:1 | mod m1 | +| main.rs:24:5:42:5 | mod m2 | +| main.rs:35:9:41:9 | mod m3 | +| main.rs:45:1:52:1 | mod m4 | +| main.rs:109:1:113:1 | mod m5 | +| main.rs:115:1:126:1 | mod m6 | +| main.rs:128:1:147:1 | mod m7 | +| main.rs:149:1:203:1 | mod m8 | +| main.rs:205:1:213:1 | mod m9 | +| main.rs:215:1:234:1 | mod m10 | +| main.rs:236:1:273:1 | mod m11 | +| main.rs:246:5:246:12 | mod f | +| main.rs:275:1:287:1 | mod m12 | +| main.rs:289:1:302:1 | mod m13 | +| main.rs:293:5:301:5 | mod m14 | +| main.rs:304:1:373:1 | mod m15 | +| main.rs:375:1:467:1 | mod m16 | +| main.rs:469:1:519:1 | mod trait_visibility | +| main.rs:470:5:492:5 | mod m | +| main.rs:521:1:551:1 | mod m17 | +| main.rs:553:1:571:1 | mod m18 | +| main.rs:558:5:570:5 | mod m19 | +| main.rs:563:9:569:9 | mod m20 | +| main.rs:573:1:598:1 | mod m21 | +| main.rs:574:5:580:5 | mod m22 | +| main.rs:582:5:597:5 | mod m33 | +| main.rs:600:1:625:1 | mod m23 | +| main.rs:627:1:695:1 | mod m24 | +| main.rs:712:1:764:1 | mod associated_types | | my2/mod.rs:1:1:1:16 | mod nested2 | -| my2/mod.rs:12:1:12:12 | mod my3 | -| my2/mod.rs:14:1:15:10 | mod mymod | +| my2/mod.rs:18:1:18:12 | mod my3 | +| my2/mod.rs:20:1:21:10 | mod mymod | | my2/nested2.rs:1:1:11:1 | mod nested3 | | my2/nested2.rs:2:5:10:5 | mod nested4 | | my2/nested2.rs:13:1:19:1 | mod nested5 | @@ -52,385 +52,394 @@ resolvePath | main.rs:5:5:5:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 | | main.rs:5:5:5:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 | | main.rs:9:5:9:7 | my2 | main.rs:7:1:7:8 | mod my2 | -| main.rs:11:5:11:7 | my2 | main.rs:7:1:7:8 | mod my2 | -| main.rs:11:5:11:16 | ...::nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | -| main.rs:11:5:11:25 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | -| main.rs:11:5:11:34 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | -| main.rs:11:38:11:38 | f | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:11:41:11:41 | g | my2/nested2.rs:7:9:9:9 | fn g | -| main.rs:25:13:25:13 | f | main.rs:19:9:21:9 | fn f | -| main.rs:26:13:26:17 | super | main.rs:13:1:37:1 | mod m1 | -| main.rs:26:13:26:20 | ...::f | main.rs:14:5:16:5 | fn f | -| main.rs:30:17:30:21 | super | main.rs:18:5:36:5 | mod m2 | -| main.rs:30:17:30:24 | ...::f | main.rs:19:9:21:9 | fn f | -| main.rs:33:17:33:17 | f | main.rs:19:9:21:9 | fn f | -| main.rs:40:9:40:13 | super | main.rs:1:1:799:2 | SourceFile | -| main.rs:40:9:40:17 | ...::m1 | main.rs:13:1:37:1 | mod m1 | -| main.rs:40:9:40:21 | ...::m2 | main.rs:18:5:36:5 | mod m2 | -| main.rs:40:9:40:24 | ...::g | main.rs:23:9:27:9 | fn g | -| main.rs:44:9:44:9 | g | main.rs:23:9:27:9 | fn g | -| main.rs:56:13:56:14 | m1 | main.rs:13:1:37:1 | mod m1 | -| main.rs:56:13:56:18 | ...::m2 | main.rs:18:5:36:5 | mod m2 | -| main.rs:56:13:56:21 | ...::g | main.rs:23:9:27:9 | fn g | -| main.rs:57:9:57:9 | g | main.rs:23:9:27:9 | fn g | -| main.rs:61:17:61:19 | Foo | main.rs:59:9:59:21 | struct Foo | -| main.rs:64:13:64:15 | Foo | main.rs:53:5:53:17 | struct Foo | -| main.rs:66:5:66:5 | f | main.rs:55:5:62:5 | fn f | -| main.rs:68:5:68:8 | self | main.rs:1:1:799:2 | SourceFile | -| main.rs:68:5:68:11 | ...::i | main.rs:71:1:83:1 | fn i | -| main.rs:74:13:74:15 | Foo | main.rs:48:1:48:13 | struct Foo | -| main.rs:78:16:78:18 | i32 | {EXTERNAL LOCATION} | struct i32 | -| main.rs:81:17:81:19 | Foo | main.rs:77:9:79:9 | struct Foo | -| main.rs:85:5:85:7 | my2 | main.rs:7:1:7:8 | mod my2 | -| main.rs:85:5:85:16 | ...::nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | -| main.rs:87:5:87:21 | my2_nested2_alias | my2/mod.rs:1:1:1:16 | mod nested2 | -| main.rs:87:5:87:30 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | -| main.rs:87:34:87:40 | nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | -| main.rs:87:34:87:43 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:87:57:87:63 | nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | -| main.rs:87:57:87:66 | ...::g | my2/nested2.rs:7:9:9:9 | fn g | -| main.rs:87:80:87:86 | nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | -| main.rs:100:5:100:22 | f_defined_in_macro | main.rs:99:18:99:42 | fn f_defined_in_macro | -| main.rs:117:13:117:17 | super | main.rs:1:1:799:2 | SourceFile | -| main.rs:117:13:117:21 | ...::m5 | main.rs:103:1:107:1 | mod m5 | -| main.rs:118:9:118:9 | f | main.rs:104:5:106:5 | fn f | -| main.rs:118:9:118:9 | f | main.rs:110:5:112:5 | fn f | -| main.rs:125:13:125:15 | i32 | {EXTERNAL LOCATION} | struct i32 | -| main.rs:128:16:128:18 | i32 | {EXTERNAL LOCATION} | struct i32 | -| main.rs:134:19:134:24 | MyEnum | main.rs:123:5:131:5 | enum MyEnum | -| main.rs:137:17:137:22 | MyEnum | main.rs:123:5:131:5 | enum MyEnum | -| main.rs:137:17:137:25 | ...::A | main.rs:124:9:126:9 | A | -| main.rs:138:17:138:22 | MyEnum | main.rs:123:5:131:5 | enum MyEnum | -| main.rs:138:17:138:25 | ...::B | main.rs:126:12:129:9 | B | -| main.rs:139:9:139:14 | MyEnum | main.rs:123:5:131:5 | enum MyEnum | -| main.rs:139:9:139:17 | ...::C | main.rs:129:12:130:9 | C | -| main.rs:149:13:149:13 | f | main.rs:156:5:158:5 | fn f | -| main.rs:150:13:150:16 | Self | main.rs:144:5:152:5 | trait MyTrait | -| main.rs:150:13:150:19 | ...::f | main.rs:145:9:145:20 | fn f | -| main.rs:161:10:161:16 | MyTrait | main.rs:144:5:152:5 | trait MyTrait | -| main.rs:161:22:161:29 | MyStruct | main.rs:154:5:154:22 | struct MyStruct | -| main.rs:164:13:164:13 | f | main.rs:156:5:158:5 | fn f | -| main.rs:165:13:165:16 | Self | main.rs:160:5:171:5 | impl MyTrait for MyStruct { ... } | -| main.rs:165:13:165:19 | ...::g | main.rs:168:9:170:9 | fn g | -| main.rs:174:10:174:17 | MyStruct | main.rs:154:5:154:22 | struct MyStruct | -| main.rs:177:13:177:13 | f | main.rs:156:5:158:5 | fn f | -| main.rs:183:17:183:24 | MyStruct | main.rs:154:5:154:22 | struct MyStruct | -| main.rs:184:9:184:15 | MyTrait | main.rs:144:5:152:5 | trait MyTrait | -| main.rs:184:9:184:18 | ...::f | main.rs:145:9:145:20 | fn f | -| main.rs:185:9:185:16 | MyStruct | main.rs:154:5:154:22 | struct MyStruct | -| main.rs:185:9:185:19 | ...::f | main.rs:161:33:166:9 | fn f | -| main.rs:186:10:186:17 | MyStruct | main.rs:154:5:154:22 | struct MyStruct | -| main.rs:187:10:187:16 | MyTrait | main.rs:144:5:152:5 | trait MyTrait | -| main.rs:190:17:190:24 | MyStruct | main.rs:154:5:154:22 | struct MyStruct | -| main.rs:192:17:192:24 | MyStruct | main.rs:154:5:154:22 | struct MyStruct | -| main.rs:194:9:194:16 | MyStruct | main.rs:154:5:154:22 | struct MyStruct | -| main.rs:194:9:194:19 | ...::h | main.rs:174:21:178:9 | fn h | -| main.rs:203:19:203:22 | self | main.rs:199:1:207:1 | mod m9 | -| main.rs:203:19:203:32 | ...::MyStruct | main.rs:200:5:200:26 | struct MyStruct | -| main.rs:205:9:205:12 | self | main.rs:199:1:207:1 | mod m9 | -| main.rs:205:9:205:22 | ...::MyStruct | main.rs:200:5:200:26 | struct MyStruct | -| main.rs:215:12:215:12 | T | main.rs:212:7:212:7 | T | -| main.rs:220:12:220:12 | T | main.rs:219:14:219:14 | T | -| main.rs:222:7:224:7 | MyStruct::<...> | main.rs:210:5:216:5 | struct MyStruct | -| main.rs:223:9:223:9 | T | main.rs:219:14:219:14 | T | -| main.rs:226:9:226:16 | MyStruct | main.rs:210:5:216:5 | struct MyStruct | -| main.rs:236:17:236:19 | Foo | main.rs:231:5:231:21 | struct Foo | -| main.rs:237:9:237:11 | Foo | main.rs:233:5:233:15 | fn Foo | -| main.rs:246:9:246:11 | Bar | main.rs:242:5:244:5 | enum Bar | -| main.rs:246:9:246:19 | ...::FooBar | main.rs:243:9:243:17 | FooBar | -| main.rs:251:13:251:15 | Foo | main.rs:231:5:231:21 | struct Foo | -| main.rs:252:17:252:22 | FooBar | main.rs:243:9:243:17 | FooBar | -| main.rs:253:17:253:22 | FooBar | main.rs:248:5:248:18 | fn FooBar | -| main.rs:261:9:261:9 | E | main.rs:256:15:259:5 | enum E | -| main.rs:261:9:261:12 | ...::C | main.rs:258:9:258:9 | C | -| main.rs:264:17:264:17 | S | main.rs:256:5:256:13 | struct S | -| main.rs:265:17:265:17 | C | main.rs:258:9:258:9 | C | -| main.rs:278:16:278:16 | T | main.rs:272:7:272:7 | T | -| main.rs:279:14:279:17 | Self | main.rs:270:5:280:5 | trait MyParamTrait | -| main.rs:279:14:279:33 | ...::AssociatedType | main.rs:274:9:274:28 | type AssociatedType | -| main.rs:288:13:288:16 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) | -| main.rs:288:13:288:21 | ...::m13 | main.rs:283:1:296:1 | mod m13 | -| main.rs:288:13:288:24 | ...::f | main.rs:284:5:284:17 | fn f | -| main.rs:288:13:288:24 | ...::f | main.rs:284:19:285:19 | struct f | -| main.rs:291:17:291:17 | f | main.rs:284:19:285:19 | struct f | -| main.rs:292:21:292:21 | f | main.rs:284:19:285:19 | struct f | -| main.rs:293:13:293:13 | f | main.rs:284:5:284:17 | fn f | -| main.rs:307:9:307:14 | Trait1 | main.rs:299:5:303:5 | trait Trait1 | -| main.rs:310:13:310:16 | Self | main.rs:305:5:313:5 | trait Trait2 | -| main.rs:310:13:310:19 | ...::g | main.rs:302:9:302:20 | fn g | -| main.rs:320:9:320:12 | Self | main.rs:315:5:328:5 | trait Trait3 | -| main.rs:320:15:320:20 | Trait1 | main.rs:299:5:303:5 | trait Trait1 | -| main.rs:321:9:321:10 | TT | main.rs:317:9:317:10 | TT | -| main.rs:321:13:321:18 | Trait1 | main.rs:299:5:303:5 | trait Trait1 | -| main.rs:323:25:323:26 | TT | main.rs:317:9:317:10 | TT | -| main.rs:324:13:324:16 | Self | main.rs:315:5:328:5 | trait Trait3 | -| main.rs:324:13:324:19 | ...::g | main.rs:302:9:302:20 | fn g | -| main.rs:325:13:325:14 | TT | main.rs:317:9:317:10 | TT | -| main.rs:325:13:325:17 | ...::g | main.rs:302:9:302:20 | fn g | -| main.rs:333:10:333:15 | Trait1 | main.rs:299:5:303:5 | trait Trait1 | -| main.rs:334:11:334:11 | S | main.rs:330:5:330:13 | struct S | -| main.rs:337:13:337:16 | Self | main.rs:332:5:344:5 | impl Trait1 for S { ... } | -| main.rs:337:13:337:19 | ...::g | main.rs:341:9:343:9 | fn g | -| main.rs:347:10:347:15 | Trait2 | main.rs:305:5:313:5 | trait Trait2 | -| main.rs:348:11:348:11 | S | main.rs:330:5:330:13 | struct S | -| main.rs:357:17:357:17 | S | main.rs:330:5:330:13 | struct S | -| main.rs:358:10:358:10 | S | main.rs:330:5:330:13 | struct S | -| main.rs:359:14:359:19 | Trait1 | main.rs:299:5:303:5 | trait Trait1 | -| main.rs:361:10:361:10 | S | main.rs:330:5:330:13 | struct S | -| main.rs:362:14:362:19 | Trait2 | main.rs:305:5:313:5 | trait Trait2 | -| main.rs:364:9:364:9 | S | main.rs:330:5:330:13 | struct S | -| main.rs:364:9:364:12 | ...::g | main.rs:341:9:343:9 | fn g | -| main.rs:374:24:374:24 | T | main.rs:372:7:372:7 | T | -| main.rs:376:24:376:24 | T | main.rs:372:7:372:7 | T | -| main.rs:379:24:379:24 | T | main.rs:372:7:372:7 | T | -| main.rs:380:13:380:16 | Self | main.rs:370:5:386:5 | trait Trait1 | -| main.rs:380:13:380:19 | ...::g | main.rs:376:9:377:9 | fn g | -| main.rs:384:18:384:18 | T | main.rs:372:7:372:7 | T | -| main.rs:392:9:394:9 | Trait1::<...> | main.rs:370:5:386:5 | trait Trait1 | -| main.rs:393:11:393:11 | T | main.rs:390:7:390:7 | T | -| main.rs:395:24:395:24 | T | main.rs:390:7:390:7 | T | -| main.rs:397:13:397:16 | Self | main.rs:388:5:401:5 | trait Trait2 | -| main.rs:397:13:397:19 | ...::g | main.rs:376:9:377:9 | fn g | -| main.rs:399:13:399:16 | Self | main.rs:388:5:401:5 | trait Trait2 | -| main.rs:399:13:399:19 | ...::c | main.rs:384:9:385:9 | Const | -| main.rs:406:10:408:5 | Trait1::<...> | main.rs:370:5:386:5 | trait Trait1 | -| main.rs:407:7:407:7 | S | main.rs:403:5:403:13 | struct S | -| main.rs:409:11:409:11 | S | main.rs:403:5:403:13 | struct S | -| main.rs:410:24:410:24 | S | main.rs:403:5:403:13 | struct S | -| main.rs:412:13:412:16 | Self | main.rs:405:5:423:5 | impl Trait1::<...> for S { ... } | -| main.rs:412:13:412:19 | ...::g | main.rs:416:9:419:9 | fn g | -| main.rs:416:24:416:24 | S | main.rs:403:5:403:13 | struct S | -| main.rs:418:13:418:16 | Self | main.rs:405:5:423:5 | impl Trait1::<...> for S { ... } | -| main.rs:418:13:418:19 | ...::c | main.rs:421:9:422:9 | Const | -| main.rs:421:18:421:18 | S | main.rs:403:5:403:13 | struct S | -| main.rs:421:22:421:22 | S | main.rs:403:5:403:13 | struct S | -| main.rs:426:10:428:5 | Trait2::<...> | main.rs:388:5:401:5 | trait Trait2 | -| main.rs:427:7:427:7 | S | main.rs:403:5:403:13 | struct S | -| main.rs:429:11:429:11 | S | main.rs:403:5:403:13 | struct S | -| main.rs:430:24:430:24 | S | main.rs:403:5:403:13 | struct S | -| main.rs:432:13:432:16 | Self | main.rs:425:5:434:5 | impl Trait2::<...> for S { ... } | -| main.rs:439:17:439:17 | S | main.rs:403:5:403:13 | struct S | -| main.rs:440:10:440:10 | S | main.rs:403:5:403:13 | struct S | -| main.rs:441:14:443:11 | Trait1::<...> | main.rs:370:5:386:5 | trait Trait1 | -| main.rs:442:13:442:13 | S | main.rs:403:5:403:13 | struct S | -| main.rs:445:10:445:10 | S | main.rs:403:5:403:13 | struct S | -| main.rs:446:14:448:11 | Trait2::<...> | main.rs:388:5:401:5 | trait Trait2 | -| main.rs:447:13:447:13 | S | main.rs:403:5:403:13 | struct S | -| main.rs:450:9:450:9 | S | main.rs:403:5:403:13 | struct S | -| main.rs:450:9:450:12 | ...::g | main.rs:416:9:419:9 | fn g | -| main.rs:452:9:452:9 | S | main.rs:403:5:403:13 | struct S | -| main.rs:452:9:452:12 | ...::h | main.rs:379:9:382:9 | fn h | -| main.rs:454:9:454:9 | S | main.rs:403:5:403:13 | struct S | -| main.rs:454:9:454:12 | ...::c | main.rs:421:9:422:9 | Const | -| main.rs:455:10:455:10 | S | main.rs:403:5:403:13 | struct S | -| main.rs:456:14:458:11 | Trait1::<...> | main.rs:370:5:386:5 | trait Trait1 | -| main.rs:457:13:457:13 | S | main.rs:403:5:403:13 | struct S | -| main.rs:475:14:475:16 | Foo | main.rs:465:9:467:9 | trait Foo | -| main.rs:475:22:475:22 | X | main.rs:473:9:473:21 | struct X | -| main.rs:481:14:481:16 | Bar | main.rs:469:9:471:9 | trait Bar | -| main.rs:481:22:481:22 | X | main.rs:473:9:473:21 | struct X | -| main.rs:488:9:488:9 | m | main.rs:464:5:486:5 | mod m | -| main.rs:488:9:488:12 | ...::X | main.rs:473:9:473:21 | struct X | -| main.rs:491:17:491:17 | X | main.rs:473:9:473:21 | struct X | -| main.rs:494:17:494:17 | m | main.rs:464:5:486:5 | mod m | -| main.rs:494:17:494:22 | ...::Foo | main.rs:465:9:467:9 | trait Foo | -| main.rs:495:13:495:13 | X | main.rs:473:9:473:21 | struct X | -| main.rs:495:13:495:23 | ...::a_method | main.rs:475:26:478:13 | fn a_method | -| main.rs:499:17:499:17 | m | main.rs:464:5:486:5 | mod m | -| main.rs:499:17:499:22 | ...::Bar | main.rs:469:9:471:9 | trait Bar | -| main.rs:500:13:500:13 | X | main.rs:473:9:473:21 | struct X | -| main.rs:500:13:500:23 | ...::a_method | main.rs:481:26:484:13 | fn a_method | -| main.rs:504:17:504:17 | m | main.rs:464:5:486:5 | mod m | -| main.rs:504:17:504:22 | ...::Bar | main.rs:469:9:471:9 | trait Bar | -| main.rs:505:13:505:13 | X | main.rs:473:9:473:21 | struct X | -| main.rs:505:13:505:23 | ...::a_method | main.rs:481:26:484:13 | fn a_method | -| main.rs:510:13:510:13 | m | main.rs:464:5:486:5 | mod m | -| main.rs:510:13:510:18 | ...::Bar | main.rs:469:9:471:9 | trait Bar | -| main.rs:510:13:510:28 | ...::a_method | main.rs:470:13:470:31 | fn a_method | -| main.rs:523:10:523:16 | MyTrait | main.rs:516:5:518:5 | trait MyTrait | -| main.rs:524:9:524:9 | S | main.rs:520:5:520:13 | struct S | -| main.rs:532:7:532:13 | MyTrait | main.rs:516:5:518:5 | trait MyTrait | -| main.rs:533:10:533:10 | T | main.rs:531:10:531:10 | T | -| main.rs:535:9:535:9 | T | main.rs:531:10:531:10 | T | -| main.rs:535:9:535:12 | ...::f | main.rs:517:9:517:20 | fn f | -| main.rs:536:9:536:15 | MyTrait | main.rs:516:5:518:5 | trait MyTrait | -| main.rs:536:9:536:18 | ...::f | main.rs:517:9:517:20 | fn f | -| main.rs:541:9:541:9 | g | main.rs:530:5:537:5 | fn g | -| main.rs:542:11:542:11 | S | main.rs:520:5:520:13 | struct S | -| main.rs:560:17:560:21 | super | main.rs:552:5:564:5 | mod m19 | -| main.rs:560:17:560:24 | ...::f | main.rs:553:9:555:9 | fn f | -| main.rs:561:17:561:21 | super | main.rs:552:5:564:5 | mod m19 | -| main.rs:561:17:561:28 | ...::super | main.rs:547:1:565:1 | mod m18 | -| main.rs:561:17:561:31 | ...::f | main.rs:548:5:550:5 | fn f | -| main.rs:578:13:578:17 | super | main.rs:567:1:592:1 | mod m21 | -| main.rs:578:13:578:22 | ...::m22 | main.rs:568:5:574:5 | mod m22 | -| main.rs:578:13:578:30 | ...::MyEnum | main.rs:569:9:571:9 | enum MyEnum | -| main.rs:579:13:579:16 | self | main.rs:569:9:571:9 | enum MyEnum | -| main.rs:583:13:583:17 | super | main.rs:567:1:592:1 | mod m21 | -| main.rs:583:13:583:22 | ...::m22 | main.rs:568:5:574:5 | mod m22 | -| main.rs:583:13:583:32 | ...::MyStruct | main.rs:573:9:573:28 | struct MyStruct | -| main.rs:584:13:584:16 | self | main.rs:573:9:573:28 | struct MyStruct | -| main.rs:588:21:588:26 | MyEnum | main.rs:569:9:571:9 | enum MyEnum | -| main.rs:588:21:588:29 | ...::A | main.rs:570:13:570:13 | A | -| main.rs:589:21:589:28 | MyStruct | main.rs:573:9:573:28 | struct MyStruct | -| main.rs:605:10:607:5 | Trait1::<...> | main.rs:595:5:600:5 | trait Trait1 | -| main.rs:606:7:606:10 | Self | main.rs:602:5:602:13 | struct S | -| main.rs:608:11:608:11 | S | main.rs:602:5:602:13 | struct S | -| main.rs:616:17:616:17 | S | main.rs:602:5:602:13 | struct S | -| main.rs:632:15:632:15 | T | main.rs:631:26:631:26 | T | -| main.rs:637:9:637:24 | GenericStruct::<...> | main.rs:630:5:633:5 | struct GenericStruct | -| main.rs:637:23:637:23 | T | main.rs:636:10:636:10 | T | -| main.rs:639:9:639:9 | T | main.rs:636:10:636:10 | T | -| main.rs:639:12:639:17 | TraitA | main.rs:622:5:624:5 | trait TraitA | -| main.rs:648:9:648:24 | GenericStruct::<...> | main.rs:630:5:633:5 | struct GenericStruct | -| main.rs:648:23:648:23 | T | main.rs:647:10:647:10 | T | -| main.rs:650:9:650:9 | T | main.rs:647:10:647:10 | T | -| main.rs:650:12:650:17 | TraitB | main.rs:626:5:628:5 | trait TraitB | -| main.rs:651:9:651:9 | T | main.rs:647:10:647:10 | T | -| main.rs:651:12:651:17 | TraitA | main.rs:622:5:624:5 | trait TraitA | -| main.rs:662:10:662:15 | TraitA | main.rs:622:5:624:5 | trait TraitA | -| main.rs:662:21:662:31 | Implementor | main.rs:659:5:659:23 | struct Implementor | -| main.rs:669:10:669:15 | TraitB | main.rs:626:5:628:5 | trait TraitB | -| main.rs:669:21:669:31 | Implementor | main.rs:659:5:659:23 | struct Implementor | -| main.rs:677:24:677:34 | Implementor | main.rs:659:5:659:23 | struct Implementor | -| main.rs:678:23:678:35 | GenericStruct | main.rs:630:5:633:5 | struct GenericStruct | -| main.rs:684:9:684:36 | GenericStruct::<...> | main.rs:630:5:633:5 | struct GenericStruct | -| main.rs:684:9:684:50 | ...::call_trait_a | main.rs:641:9:643:9 | fn call_trait_a | -| main.rs:684:25:684:35 | Implementor | main.rs:659:5:659:23 | struct Implementor | -| main.rs:687:9:687:36 | GenericStruct::<...> | main.rs:630:5:633:5 | struct GenericStruct | -| main.rs:687:9:687:47 | ...::call_both | main.rs:653:9:656:9 | fn call_both | -| main.rs:687:25:687:35 | Implementor | main.rs:659:5:659:23 | struct Implementor | -| main.rs:693:3:693:12 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) | -| main.rs:693:3:693:24 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix | -| main.rs:697:6:697:12 | AStruct | main.rs:696:1:696:17 | struct AStruct | -| main.rs:699:7:699:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) | -| main.rs:699:7:699:28 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix | -| main.rs:702:7:702:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) | -| main.rs:702:7:702:28 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix | -| main.rs:707:9:707:11 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) | -| main.rs:707:9:707:19 | ...::marker | {EXTERNAL LOCATION} | mod marker | -| main.rs:707:9:707:32 | ...::PhantomData | {EXTERNAL LOCATION} | struct PhantomData | -| main.rs:708:9:708:11 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) | -| main.rs:708:9:708:19 | ...::result | {EXTERNAL LOCATION} | mod result | -| main.rs:708:9:708:27 | ...::Result | {EXTERNAL LOCATION} | enum Result | -| main.rs:716:19:716:22 | Self | main.rs:710:5:718:5 | trait Reduce | -| main.rs:716:19:716:29 | ...::Input | main.rs:711:9:711:19 | type Input | -| main.rs:717:14:717:46 | Result::<...> | {EXTERNAL LOCATION} | enum Result | -| main.rs:717:21:717:24 | Self | main.rs:710:5:718:5 | trait Reduce | -| main.rs:717:21:717:32 | ...::Output | main.rs:712:21:713:20 | type Output | -| main.rs:717:35:717:38 | Self | main.rs:710:5:718:5 | trait Reduce | -| main.rs:717:35:717:45 | ...::Error | main.rs:711:21:712:19 | type Error | -| main.rs:721:17:721:34 | PhantomData::<...> | {EXTERNAL LOCATION} | struct PhantomData | -| main.rs:721:29:721:33 | Input | main.rs:720:19:720:23 | Input | -| main.rs:722:17:722:34 | PhantomData::<...> | {EXTERNAL LOCATION} | struct PhantomData | -| main.rs:722:29:722:33 | Error | main.rs:720:26:720:30 | Error | -| main.rs:729:11:729:16 | Reduce | main.rs:710:5:718:5 | trait Reduce | -| main.rs:730:13:733:9 | MyImpl::<...> | main.rs:720:5:723:5 | struct MyImpl | -| main.rs:731:13:731:17 | Input | main.rs:727:13:727:17 | Input | -| main.rs:732:13:732:17 | Error | main.rs:728:13:728:17 | Error | -| main.rs:735:22:738:9 | Result::<...> | {EXTERNAL LOCATION} | enum Result | -| main.rs:736:13:736:17 | Input | main.rs:727:13:727:17 | Input | -| main.rs:737:13:737:16 | Self | main.rs:725:5:757:5 | impl Reduce for MyImpl::<...> { ... } | -| main.rs:737:13:737:23 | ...::Error | main.rs:739:11:743:9 | type Error | -| main.rs:740:22:742:9 | Option::<...> | {EXTERNAL LOCATION} | enum Option | -| main.rs:741:11:741:15 | Error | main.rs:728:13:728:17 | Error | -| main.rs:745:13:745:17 | Input | main.rs:727:13:727:17 | Input | -| main.rs:750:19:750:22 | Self | main.rs:725:5:757:5 | impl Reduce for MyImpl::<...> { ... } | -| main.rs:750:19:750:29 | ...::Input | main.rs:735:9:739:9 | type Input | -| main.rs:751:14:754:9 | Result::<...> | {EXTERNAL LOCATION} | enum Result | -| main.rs:752:13:752:16 | Self | main.rs:725:5:757:5 | impl Reduce for MyImpl::<...> { ... } | -| main.rs:752:13:752:24 | ...::Output | main.rs:743:11:746:9 | type Output | -| main.rs:753:13:753:16 | Self | main.rs:725:5:757:5 | impl Reduce for MyImpl::<...> { ... } | -| main.rs:753:13:753:23 | ...::Error | main.rs:739:11:743:9 | type Error | -| main.rs:760:5:760:7 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) | -| main.rs:760:11:760:14 | self | {EXTERNAL LOCATION} | Crate(std@0.0.0) | -| main.rs:762:15:762:17 | ztd | {EXTERNAL LOCATION} | Crate(std@0.0.0) | -| main.rs:762:15:762:25 | ...::string | {EXTERNAL LOCATION} | mod string | -| main.rs:762:15:762:33 | ...::String | {EXTERNAL LOCATION} | struct String | -| main.rs:765:5:765:6 | my | main.rs:1:1:1:7 | mod my | -| main.rs:765:5:765:14 | ...::nested | my.rs:1:1:1:15 | mod nested | -| main.rs:765:5:765:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 | -| main.rs:765:5:765:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 | -| main.rs:765:5:765:35 | ...::f | my/nested.rs:3:9:5:9 | fn f | -| main.rs:766:5:766:6 | my | main.rs:1:1:1:7 | mod my | -| main.rs:766:5:766:9 | ...::f | my.rs:5:1:7:1 | fn f | -| main.rs:767:5:767:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | -| main.rs:767:5:767:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | -| main.rs:767:5:767:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | -| main.rs:767:5:767:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:768:5:768:5 | f | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:769:5:769:5 | g | my2/nested2.rs:7:9:9:9 | fn g | -| main.rs:770:5:770:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) | -| main.rs:770:5:770:12 | ...::h | main.rs:50:1:69:1 | fn h | -| main.rs:771:5:771:6 | m1 | main.rs:13:1:37:1 | mod m1 | -| main.rs:771:5:771:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 | -| main.rs:771:5:771:13 | ...::g | main.rs:23:9:27:9 | fn g | -| main.rs:772:5:772:6 | m1 | main.rs:13:1:37:1 | mod m1 | -| main.rs:772:5:772:10 | ...::m2 | main.rs:18:5:36:5 | mod m2 | -| main.rs:772:5:772:14 | ...::m3 | main.rs:29:9:35:9 | mod m3 | -| main.rs:772:5:772:17 | ...::h | main.rs:30:27:34:13 | fn h | -| main.rs:773:5:773:6 | m4 | main.rs:39:1:46:1 | mod m4 | -| main.rs:773:5:773:9 | ...::i | main.rs:42:5:45:5 | fn i | -| main.rs:774:5:774:5 | h | main.rs:50:1:69:1 | fn h | -| main.rs:775:5:775:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:776:5:776:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g | -| main.rs:777:5:777:5 | j | main.rs:97:1:101:1 | fn j | -| main.rs:778:5:778:6 | m6 | main.rs:109:1:120:1 | mod m6 | -| main.rs:778:5:778:9 | ...::g | main.rs:114:5:119:5 | fn g | -| main.rs:779:5:779:6 | m7 | main.rs:122:1:141:1 | mod m7 | -| main.rs:779:5:779:9 | ...::f | main.rs:133:5:140:5 | fn f | -| main.rs:780:5:780:6 | m8 | main.rs:143:1:197:1 | mod m8 | -| main.rs:780:5:780:9 | ...::g | main.rs:181:5:196:5 | fn g | -| main.rs:781:5:781:6 | m9 | main.rs:199:1:207:1 | mod m9 | -| main.rs:781:5:781:9 | ...::f | main.rs:202:5:206:5 | fn f | -| main.rs:782:5:782:7 | m11 | main.rs:230:1:267:1 | mod m11 | -| main.rs:782:5:782:10 | ...::f | main.rs:235:5:238:5 | fn f | -| main.rs:783:5:783:7 | m15 | main.rs:298:1:367:1 | mod m15 | -| main.rs:783:5:783:10 | ...::f | main.rs:354:5:366:5 | fn f | -| main.rs:784:5:784:7 | m16 | main.rs:369:1:461:1 | mod m16 | -| main.rs:784:5:784:10 | ...::f | main.rs:436:5:460:5 | fn f | -| main.rs:785:5:785:20 | trait_visibility | main.rs:463:1:513:1 | mod trait_visibility | -| main.rs:785:5:785:23 | ...::f | main.rs:490:5:512:5 | fn f | -| main.rs:786:5:786:7 | m17 | main.rs:515:1:545:1 | mod m17 | -| main.rs:786:5:786:10 | ...::f | main.rs:539:5:544:5 | fn f | -| main.rs:787:5:787:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 | -| main.rs:787:5:787:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f | -| main.rs:788:5:788:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 | -| main.rs:788:5:788:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f | -| main.rs:789:5:789:7 | my3 | my2/mod.rs:12:1:12:12 | mod my3 | -| main.rs:789:5:789:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f | -| main.rs:790:5:790:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f | -| main.rs:791:5:791:7 | m18 | main.rs:547:1:565:1 | mod m18 | -| main.rs:791:5:791:12 | ...::m19 | main.rs:552:5:564:5 | mod m19 | -| main.rs:791:5:791:17 | ...::m20 | main.rs:557:9:563:9 | mod m20 | -| main.rs:791:5:791:20 | ...::g | main.rs:558:13:562:13 | fn g | -| main.rs:792:5:792:7 | m23 | main.rs:594:1:619:1 | mod m23 | -| main.rs:792:5:792:10 | ...::f | main.rs:614:5:618:5 | fn f | -| main.rs:793:5:793:7 | m24 | main.rs:621:1:689:1 | mod m24 | -| main.rs:793:5:793:10 | ...::f | main.rs:675:5:688:5 | fn f | -| main.rs:794:5:794:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) | -| main.rs:794:5:794:11 | ...::h | main.rs:50:1:69:1 | fn h | -| main.rs:796:5:796:11 | AStruct | main.rs:696:1:696:17 | struct AStruct | -| main.rs:797:5:797:11 | AStruct | main.rs:696:1:696:17 | struct AStruct | +| main.rs:12:5:12:7 | my2 | main.rs:7:1:7:8 | mod my2 | +| main.rs:12:5:12:16 | ...::nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | +| main.rs:12:5:12:25 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | +| main.rs:12:5:12:34 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | +| main.rs:13:5:13:5 | f | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:14:5:14:5 | g | my2/nested2.rs:7:9:9:9 | fn g | +| main.rs:17:5:17:7 | my2 | main.rs:7:1:7:8 | mod my2 | +| main.rs:17:5:17:18 | ...::nested8_f | my2/nested2.rs:23:9:25:9 | fn f | +| main.rs:31:13:31:13 | f | main.rs:25:9:27:9 | fn f | +| main.rs:32:13:32:17 | super | main.rs:19:1:43:1 | mod m1 | +| main.rs:32:13:32:20 | ...::f | main.rs:20:5:22:5 | fn f | +| main.rs:36:17:36:21 | super | main.rs:24:5:42:5 | mod m2 | +| main.rs:36:17:36:24 | ...::f | main.rs:25:9:27:9 | fn f | +| main.rs:39:17:39:17 | f | main.rs:25:9:27:9 | fn f | +| main.rs:46:9:46:13 | super | main.rs:1:1:805:2 | SourceFile | +| main.rs:46:9:46:17 | ...::m1 | main.rs:19:1:43:1 | mod m1 | +| main.rs:46:9:46:21 | ...::m2 | main.rs:24:5:42:5 | mod m2 | +| main.rs:46:9:46:24 | ...::g | main.rs:29:9:33:9 | fn g | +| main.rs:50:9:50:9 | g | main.rs:29:9:33:9 | fn g | +| main.rs:62:13:62:14 | m1 | main.rs:19:1:43:1 | mod m1 | +| main.rs:62:13:62:18 | ...::m2 | main.rs:24:5:42:5 | mod m2 | +| main.rs:62:13:62:21 | ...::g | main.rs:29:9:33:9 | fn g | +| main.rs:63:9:63:9 | g | main.rs:29:9:33:9 | fn g | +| main.rs:67:17:67:19 | Foo | main.rs:65:9:65:21 | struct Foo | +| main.rs:70:13:70:15 | Foo | main.rs:59:5:59:17 | struct Foo | +| main.rs:72:5:72:5 | f | main.rs:61:5:68:5 | fn f | +| main.rs:74:5:74:8 | self | main.rs:1:1:805:2 | SourceFile | +| main.rs:74:5:74:11 | ...::i | main.rs:77:1:89:1 | fn i | +| main.rs:80:13:80:15 | Foo | main.rs:54:1:54:13 | struct Foo | +| main.rs:84:16:84:18 | i32 | {EXTERNAL LOCATION} | struct i32 | +| main.rs:87:17:87:19 | Foo | main.rs:83:9:85:9 | struct Foo | +| main.rs:91:5:91:7 | my2 | main.rs:7:1:7:8 | mod my2 | +| main.rs:91:5:91:16 | ...::nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | +| main.rs:93:5:93:21 | my2_nested2_alias | my2/mod.rs:1:1:1:16 | mod nested2 | +| main.rs:93:5:93:30 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | +| main.rs:93:34:93:40 | nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | +| main.rs:93:34:93:43 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:93:57:93:63 | nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | +| main.rs:93:57:93:66 | ...::g | my2/nested2.rs:7:9:9:9 | fn g | +| main.rs:93:80:93:86 | nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | +| main.rs:106:5:106:22 | f_defined_in_macro | main.rs:105:18:105:42 | fn f_defined_in_macro | +| main.rs:123:13:123:17 | super | main.rs:1:1:805:2 | SourceFile | +| main.rs:123:13:123:21 | ...::m5 | main.rs:109:1:113:1 | mod m5 | +| main.rs:124:9:124:9 | f | main.rs:110:5:112:5 | fn f | +| main.rs:124:9:124:9 | f | main.rs:116:5:118:5 | fn f | +| main.rs:131:13:131:15 | i32 | {EXTERNAL LOCATION} | struct i32 | +| main.rs:134:16:134:18 | i32 | {EXTERNAL LOCATION} | struct i32 | +| main.rs:140:19:140:24 | MyEnum | main.rs:129:5:137:5 | enum MyEnum | +| main.rs:143:17:143:22 | MyEnum | main.rs:129:5:137:5 | enum MyEnum | +| main.rs:143:17:143:25 | ...::A | main.rs:130:9:132:9 | A | +| main.rs:144:17:144:22 | MyEnum | main.rs:129:5:137:5 | enum MyEnum | +| main.rs:144:17:144:25 | ...::B | main.rs:132:12:135:9 | B | +| main.rs:145:9:145:14 | MyEnum | main.rs:129:5:137:5 | enum MyEnum | +| main.rs:145:9:145:17 | ...::C | main.rs:135:12:136:9 | C | +| main.rs:155:13:155:13 | f | main.rs:162:5:164:5 | fn f | +| main.rs:156:13:156:16 | Self | main.rs:150:5:158:5 | trait MyTrait | +| main.rs:156:13:156:19 | ...::f | main.rs:151:9:151:20 | fn f | +| main.rs:167:10:167:16 | MyTrait | main.rs:150:5:158:5 | trait MyTrait | +| main.rs:167:22:167:29 | MyStruct | main.rs:160:5:160:22 | struct MyStruct | +| main.rs:170:13:170:13 | f | main.rs:162:5:164:5 | fn f | +| main.rs:171:13:171:16 | Self | main.rs:166:5:177:5 | impl MyTrait for MyStruct { ... } | +| main.rs:171:13:171:19 | ...::g | main.rs:174:9:176:9 | fn g | +| main.rs:180:10:180:17 | MyStruct | main.rs:160:5:160:22 | struct MyStruct | +| main.rs:183:13:183:13 | f | main.rs:162:5:164:5 | fn f | +| main.rs:189:17:189:24 | MyStruct | main.rs:160:5:160:22 | struct MyStruct | +| main.rs:190:9:190:15 | MyTrait | main.rs:150:5:158:5 | trait MyTrait | +| main.rs:190:9:190:18 | ...::f | main.rs:151:9:151:20 | fn f | +| main.rs:191:9:191:16 | MyStruct | main.rs:160:5:160:22 | struct MyStruct | +| main.rs:191:9:191:19 | ...::f | main.rs:167:33:172:9 | fn f | +| main.rs:192:10:192:17 | MyStruct | main.rs:160:5:160:22 | struct MyStruct | +| main.rs:193:10:193:16 | MyTrait | main.rs:150:5:158:5 | trait MyTrait | +| main.rs:196:17:196:24 | MyStruct | main.rs:160:5:160:22 | struct MyStruct | +| main.rs:198:17:198:24 | MyStruct | main.rs:160:5:160:22 | struct MyStruct | +| main.rs:200:9:200:16 | MyStruct | main.rs:160:5:160:22 | struct MyStruct | +| main.rs:200:9:200:19 | ...::h | main.rs:180:21:184:9 | fn h | +| main.rs:209:19:209:22 | self | main.rs:205:1:213:1 | mod m9 | +| main.rs:209:19:209:32 | ...::MyStruct | main.rs:206:5:206:26 | struct MyStruct | +| main.rs:211:9:211:12 | self | main.rs:205:1:213:1 | mod m9 | +| main.rs:211:9:211:22 | ...::MyStruct | main.rs:206:5:206:26 | struct MyStruct | +| main.rs:221:12:221:12 | T | main.rs:218:7:218:7 | T | +| main.rs:226:12:226:12 | T | main.rs:225:14:225:14 | T | +| main.rs:228:7:230:7 | MyStruct::<...> | main.rs:216:5:222:5 | struct MyStruct | +| main.rs:229:9:229:9 | T | main.rs:225:14:225:14 | T | +| main.rs:232:9:232:16 | MyStruct | main.rs:216:5:222:5 | struct MyStruct | +| main.rs:242:17:242:19 | Foo | main.rs:237:5:237:21 | struct Foo | +| main.rs:243:9:243:11 | Foo | main.rs:239:5:239:15 | fn Foo | +| main.rs:252:9:252:11 | Bar | main.rs:248:5:250:5 | enum Bar | +| main.rs:252:9:252:19 | ...::FooBar | main.rs:249:9:249:17 | FooBar | +| main.rs:257:13:257:15 | Foo | main.rs:237:5:237:21 | struct Foo | +| main.rs:258:17:258:22 | FooBar | main.rs:249:9:249:17 | FooBar | +| main.rs:259:17:259:22 | FooBar | main.rs:254:5:254:18 | fn FooBar | +| main.rs:267:9:267:9 | E | main.rs:262:15:265:5 | enum E | +| main.rs:267:9:267:12 | ...::C | main.rs:264:9:264:9 | C | +| main.rs:270:17:270:17 | S | main.rs:262:5:262:13 | struct S | +| main.rs:271:17:271:17 | C | main.rs:264:9:264:9 | C | +| main.rs:284:16:284:16 | T | main.rs:278:7:278:7 | T | +| main.rs:285:14:285:17 | Self | main.rs:276:5:286:5 | trait MyParamTrait | +| main.rs:285:14:285:33 | ...::AssociatedType | main.rs:280:9:280:28 | type AssociatedType | +| main.rs:294:13:294:16 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) | +| main.rs:294:13:294:21 | ...::m13 | main.rs:289:1:302:1 | mod m13 | +| main.rs:294:13:294:24 | ...::f | main.rs:290:5:290:17 | fn f | +| main.rs:294:13:294:24 | ...::f | main.rs:290:19:291:19 | struct f | +| main.rs:297:17:297:17 | f | main.rs:290:19:291:19 | struct f | +| main.rs:298:21:298:21 | f | main.rs:290:19:291:19 | struct f | +| main.rs:299:13:299:13 | f | main.rs:290:5:290:17 | fn f | +| main.rs:313:9:313:14 | Trait1 | main.rs:305:5:309:5 | trait Trait1 | +| main.rs:316:13:316:16 | Self | main.rs:311:5:319:5 | trait Trait2 | +| main.rs:316:13:316:19 | ...::g | main.rs:308:9:308:20 | fn g | +| main.rs:326:9:326:12 | Self | main.rs:321:5:334:5 | trait Trait3 | +| main.rs:326:15:326:20 | Trait1 | main.rs:305:5:309:5 | trait Trait1 | +| main.rs:327:9:327:10 | TT | main.rs:323:9:323:10 | TT | +| main.rs:327:13:327:18 | Trait1 | main.rs:305:5:309:5 | trait Trait1 | +| main.rs:329:25:329:26 | TT | main.rs:323:9:323:10 | TT | +| main.rs:330:13:330:16 | Self | main.rs:321:5:334:5 | trait Trait3 | +| main.rs:330:13:330:19 | ...::g | main.rs:308:9:308:20 | fn g | +| main.rs:331:13:331:14 | TT | main.rs:323:9:323:10 | TT | +| main.rs:331:13:331:17 | ...::g | main.rs:308:9:308:20 | fn g | +| main.rs:339:10:339:15 | Trait1 | main.rs:305:5:309:5 | trait Trait1 | +| main.rs:340:11:340:11 | S | main.rs:336:5:336:13 | struct S | +| main.rs:343:13:343:16 | Self | main.rs:338:5:350:5 | impl Trait1 for S { ... } | +| main.rs:343:13:343:19 | ...::g | main.rs:347:9:349:9 | fn g | +| main.rs:353:10:353:15 | Trait2 | main.rs:311:5:319:5 | trait Trait2 | +| main.rs:354:11:354:11 | S | main.rs:336:5:336:13 | struct S | +| main.rs:363:17:363:17 | S | main.rs:336:5:336:13 | struct S | +| main.rs:364:10:364:10 | S | main.rs:336:5:336:13 | struct S | +| main.rs:365:14:365:19 | Trait1 | main.rs:305:5:309:5 | trait Trait1 | +| main.rs:367:10:367:10 | S | main.rs:336:5:336:13 | struct S | +| main.rs:368:14:368:19 | Trait2 | main.rs:311:5:319:5 | trait Trait2 | +| main.rs:370:9:370:9 | S | main.rs:336:5:336:13 | struct S | +| main.rs:370:9:370:12 | ...::g | main.rs:347:9:349:9 | fn g | +| main.rs:380:24:380:24 | T | main.rs:378:7:378:7 | T | +| main.rs:382:24:382:24 | T | main.rs:378:7:378:7 | T | +| main.rs:385:24:385:24 | T | main.rs:378:7:378:7 | T | +| main.rs:386:13:386:16 | Self | main.rs:376:5:392:5 | trait Trait1 | +| main.rs:386:13:386:19 | ...::g | main.rs:382:9:383:9 | fn g | +| main.rs:390:18:390:18 | T | main.rs:378:7:378:7 | T | +| main.rs:398:9:400:9 | Trait1::<...> | main.rs:376:5:392:5 | trait Trait1 | +| main.rs:399:11:399:11 | T | main.rs:396:7:396:7 | T | +| main.rs:401:24:401:24 | T | main.rs:396:7:396:7 | T | +| main.rs:403:13:403:16 | Self | main.rs:394:5:407:5 | trait Trait2 | +| main.rs:403:13:403:19 | ...::g | main.rs:382:9:383:9 | fn g | +| main.rs:405:13:405:16 | Self | main.rs:394:5:407:5 | trait Trait2 | +| main.rs:405:13:405:19 | ...::c | main.rs:390:9:391:9 | Const | +| main.rs:412:10:414:5 | Trait1::<...> | main.rs:376:5:392:5 | trait Trait1 | +| main.rs:413:7:413:7 | S | main.rs:409:5:409:13 | struct S | +| main.rs:415:11:415:11 | S | main.rs:409:5:409:13 | struct S | +| main.rs:416:24:416:24 | S | main.rs:409:5:409:13 | struct S | +| main.rs:418:13:418:16 | Self | main.rs:411:5:429:5 | impl Trait1::<...> for S { ... } | +| main.rs:418:13:418:19 | ...::g | main.rs:422:9:425:9 | fn g | +| main.rs:422:24:422:24 | S | main.rs:409:5:409:13 | struct S | +| main.rs:424:13:424:16 | Self | main.rs:411:5:429:5 | impl Trait1::<...> for S { ... } | +| main.rs:424:13:424:19 | ...::c | main.rs:427:9:428:9 | Const | +| main.rs:427:18:427:18 | S | main.rs:409:5:409:13 | struct S | +| main.rs:427:22:427:22 | S | main.rs:409:5:409:13 | struct S | +| main.rs:432:10:434:5 | Trait2::<...> | main.rs:394:5:407:5 | trait Trait2 | +| main.rs:433:7:433:7 | S | main.rs:409:5:409:13 | struct S | +| main.rs:435:11:435:11 | S | main.rs:409:5:409:13 | struct S | +| main.rs:436:24:436:24 | S | main.rs:409:5:409:13 | struct S | +| main.rs:438:13:438:16 | Self | main.rs:431:5:440:5 | impl Trait2::<...> for S { ... } | +| main.rs:445:17:445:17 | S | main.rs:409:5:409:13 | struct S | +| main.rs:446:10:446:10 | S | main.rs:409:5:409:13 | struct S | +| main.rs:447:14:449:11 | Trait1::<...> | main.rs:376:5:392:5 | trait Trait1 | +| main.rs:448:13:448:13 | S | main.rs:409:5:409:13 | struct S | +| main.rs:451:10:451:10 | S | main.rs:409:5:409:13 | struct S | +| main.rs:452:14:454:11 | Trait2::<...> | main.rs:394:5:407:5 | trait Trait2 | +| main.rs:453:13:453:13 | S | main.rs:409:5:409:13 | struct S | +| main.rs:456:9:456:9 | S | main.rs:409:5:409:13 | struct S | +| main.rs:456:9:456:12 | ...::g | main.rs:422:9:425:9 | fn g | +| main.rs:458:9:458:9 | S | main.rs:409:5:409:13 | struct S | +| main.rs:458:9:458:12 | ...::h | main.rs:385:9:388:9 | fn h | +| main.rs:460:9:460:9 | S | main.rs:409:5:409:13 | struct S | +| main.rs:460:9:460:12 | ...::c | main.rs:427:9:428:9 | Const | +| main.rs:461:10:461:10 | S | main.rs:409:5:409:13 | struct S | +| main.rs:462:14:464:11 | Trait1::<...> | main.rs:376:5:392:5 | trait Trait1 | +| main.rs:463:13:463:13 | S | main.rs:409:5:409:13 | struct S | +| main.rs:481:14:481:16 | Foo | main.rs:471:9:473:9 | trait Foo | +| main.rs:481:22:481:22 | X | main.rs:479:9:479:21 | struct X | +| main.rs:487:14:487:16 | Bar | main.rs:475:9:477:9 | trait Bar | +| main.rs:487:22:487:22 | X | main.rs:479:9:479:21 | struct X | +| main.rs:494:9:494:9 | m | main.rs:470:5:492:5 | mod m | +| main.rs:494:9:494:12 | ...::X | main.rs:479:9:479:21 | struct X | +| main.rs:497:17:497:17 | X | main.rs:479:9:479:21 | struct X | +| main.rs:500:17:500:17 | m | main.rs:470:5:492:5 | mod m | +| main.rs:500:17:500:22 | ...::Foo | main.rs:471:9:473:9 | trait Foo | +| main.rs:501:13:501:13 | X | main.rs:479:9:479:21 | struct X | +| main.rs:501:13:501:23 | ...::a_method | main.rs:481:26:484:13 | fn a_method | +| main.rs:505:17:505:17 | m | main.rs:470:5:492:5 | mod m | +| main.rs:505:17:505:22 | ...::Bar | main.rs:475:9:477:9 | trait Bar | +| main.rs:506:13:506:13 | X | main.rs:479:9:479:21 | struct X | +| main.rs:506:13:506:23 | ...::a_method | main.rs:487:26:490:13 | fn a_method | +| main.rs:510:17:510:17 | m | main.rs:470:5:492:5 | mod m | +| main.rs:510:17:510:22 | ...::Bar | main.rs:475:9:477:9 | trait Bar | +| main.rs:511:13:511:13 | X | main.rs:479:9:479:21 | struct X | +| main.rs:511:13:511:23 | ...::a_method | main.rs:487:26:490:13 | fn a_method | +| main.rs:516:13:516:13 | m | main.rs:470:5:492:5 | mod m | +| main.rs:516:13:516:18 | ...::Bar | main.rs:475:9:477:9 | trait Bar | +| main.rs:516:13:516:28 | ...::a_method | main.rs:476:13:476:31 | fn a_method | +| main.rs:529:10:529:16 | MyTrait | main.rs:522:5:524:5 | trait MyTrait | +| main.rs:530:9:530:9 | S | main.rs:526:5:526:13 | struct S | +| main.rs:538:7:538:13 | MyTrait | main.rs:522:5:524:5 | trait MyTrait | +| main.rs:539:10:539:10 | T | main.rs:537:10:537:10 | T | +| main.rs:541:9:541:9 | T | main.rs:537:10:537:10 | T | +| main.rs:541:9:541:12 | ...::f | main.rs:523:9:523:20 | fn f | +| main.rs:542:9:542:15 | MyTrait | main.rs:522:5:524:5 | trait MyTrait | +| main.rs:542:9:542:18 | ...::f | main.rs:523:9:523:20 | fn f | +| main.rs:547:9:547:9 | g | main.rs:536:5:543:5 | fn g | +| main.rs:548:11:548:11 | S | main.rs:526:5:526:13 | struct S | +| main.rs:566:17:566:21 | super | main.rs:558:5:570:5 | mod m19 | +| main.rs:566:17:566:24 | ...::f | main.rs:559:9:561:9 | fn f | +| main.rs:567:17:567:21 | super | main.rs:558:5:570:5 | mod m19 | +| main.rs:567:17:567:28 | ...::super | main.rs:553:1:571:1 | mod m18 | +| main.rs:567:17:567:31 | ...::f | main.rs:554:5:556:5 | fn f | +| main.rs:584:13:584:17 | super | main.rs:573:1:598:1 | mod m21 | +| main.rs:584:13:584:22 | ...::m22 | main.rs:574:5:580:5 | mod m22 | +| main.rs:584:13:584:30 | ...::MyEnum | main.rs:575:9:577:9 | enum MyEnum | +| main.rs:585:13:585:16 | self | main.rs:575:9:577:9 | enum MyEnum | +| main.rs:589:13:589:17 | super | main.rs:573:1:598:1 | mod m21 | +| main.rs:589:13:589:22 | ...::m22 | main.rs:574:5:580:5 | mod m22 | +| main.rs:589:13:589:32 | ...::MyStruct | main.rs:579:9:579:28 | struct MyStruct | +| main.rs:590:13:590:16 | self | main.rs:579:9:579:28 | struct MyStruct | +| main.rs:594:21:594:26 | MyEnum | main.rs:575:9:577:9 | enum MyEnum | +| main.rs:594:21:594:29 | ...::A | main.rs:576:13:576:13 | A | +| main.rs:595:21:595:28 | MyStruct | main.rs:579:9:579:28 | struct MyStruct | +| main.rs:611:10:613:5 | Trait1::<...> | main.rs:601:5:606:5 | trait Trait1 | +| main.rs:612:7:612:10 | Self | main.rs:608:5:608:13 | struct S | +| main.rs:614:11:614:11 | S | main.rs:608:5:608:13 | struct S | +| main.rs:622:17:622:17 | S | main.rs:608:5:608:13 | struct S | +| main.rs:638:15:638:15 | T | main.rs:637:26:637:26 | T | +| main.rs:643:9:643:24 | GenericStruct::<...> | main.rs:636:5:639:5 | struct GenericStruct | +| main.rs:643:23:643:23 | T | main.rs:642:10:642:10 | T | +| main.rs:645:9:645:9 | T | main.rs:642:10:642:10 | T | +| main.rs:645:12:645:17 | TraitA | main.rs:628:5:630:5 | trait TraitA | +| main.rs:654:9:654:24 | GenericStruct::<...> | main.rs:636:5:639:5 | struct GenericStruct | +| main.rs:654:23:654:23 | T | main.rs:653:10:653:10 | T | +| main.rs:656:9:656:9 | T | main.rs:653:10:653:10 | T | +| main.rs:656:12:656:17 | TraitB | main.rs:632:5:634:5 | trait TraitB | +| main.rs:657:9:657:9 | T | main.rs:653:10:653:10 | T | +| main.rs:657:12:657:17 | TraitA | main.rs:628:5:630:5 | trait TraitA | +| main.rs:668:10:668:15 | TraitA | main.rs:628:5:630:5 | trait TraitA | +| main.rs:668:21:668:31 | Implementor | main.rs:665:5:665:23 | struct Implementor | +| main.rs:675:10:675:15 | TraitB | main.rs:632:5:634:5 | trait TraitB | +| main.rs:675:21:675:31 | Implementor | main.rs:665:5:665:23 | struct Implementor | +| main.rs:683:24:683:34 | Implementor | main.rs:665:5:665:23 | struct Implementor | +| main.rs:684:23:684:35 | GenericStruct | main.rs:636:5:639:5 | struct GenericStruct | +| main.rs:690:9:690:36 | GenericStruct::<...> | main.rs:636:5:639:5 | struct GenericStruct | +| main.rs:690:9:690:50 | ...::call_trait_a | main.rs:647:9:649:9 | fn call_trait_a | +| main.rs:690:25:690:35 | Implementor | main.rs:665:5:665:23 | struct Implementor | +| main.rs:693:9:693:36 | GenericStruct::<...> | main.rs:636:5:639:5 | struct GenericStruct | +| main.rs:693:9:693:47 | ...::call_both | main.rs:659:9:662:9 | fn call_both | +| main.rs:693:25:693:35 | Implementor | main.rs:665:5:665:23 | struct Implementor | +| main.rs:699:3:699:12 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) | +| main.rs:699:3:699:24 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix | +| main.rs:703:6:703:12 | AStruct | main.rs:702:1:702:17 | struct AStruct | +| main.rs:705:7:705:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) | +| main.rs:705:7:705:28 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix | +| main.rs:708:7:708:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) | +| main.rs:708:7:708:28 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix | +| main.rs:713:9:713:11 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) | +| main.rs:713:9:713:19 | ...::marker | {EXTERNAL LOCATION} | mod marker | +| main.rs:713:9:713:32 | ...::PhantomData | {EXTERNAL LOCATION} | struct PhantomData | +| main.rs:714:9:714:11 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) | +| main.rs:714:9:714:19 | ...::result | {EXTERNAL LOCATION} | mod result | +| main.rs:714:9:714:27 | ...::Result | {EXTERNAL LOCATION} | enum Result | +| main.rs:722:19:722:22 | Self | main.rs:716:5:724:5 | trait Reduce | +| main.rs:722:19:722:29 | ...::Input | main.rs:717:9:717:19 | type Input | +| main.rs:723:14:723:46 | Result::<...> | {EXTERNAL LOCATION} | enum Result | +| main.rs:723:21:723:24 | Self | main.rs:716:5:724:5 | trait Reduce | +| main.rs:723:21:723:32 | ...::Output | main.rs:718:21:719:20 | type Output | +| main.rs:723:35:723:38 | Self | main.rs:716:5:724:5 | trait Reduce | +| main.rs:723:35:723:45 | ...::Error | main.rs:717:21:718:19 | type Error | +| main.rs:727:17:727:34 | PhantomData::<...> | {EXTERNAL LOCATION} | struct PhantomData | +| main.rs:727:29:727:33 | Input | main.rs:726:19:726:23 | Input | +| main.rs:728:17:728:34 | PhantomData::<...> | {EXTERNAL LOCATION} | struct PhantomData | +| main.rs:728:29:728:33 | Error | main.rs:726:26:726:30 | Error | +| main.rs:735:11:735:16 | Reduce | main.rs:716:5:724:5 | trait Reduce | +| main.rs:736:13:739:9 | MyImpl::<...> | main.rs:726:5:729:5 | struct MyImpl | +| main.rs:737:13:737:17 | Input | main.rs:733:13:733:17 | Input | +| main.rs:738:13:738:17 | Error | main.rs:734:13:734:17 | Error | +| main.rs:741:22:744:9 | Result::<...> | {EXTERNAL LOCATION} | enum Result | +| main.rs:742:13:742:17 | Input | main.rs:733:13:733:17 | Input | +| main.rs:743:13:743:16 | Self | main.rs:731:5:763:5 | impl Reduce for MyImpl::<...> { ... } | +| main.rs:743:13:743:23 | ...::Error | main.rs:745:11:749:9 | type Error | +| main.rs:746:22:748:9 | Option::<...> | {EXTERNAL LOCATION} | enum Option | +| main.rs:747:11:747:15 | Error | main.rs:734:13:734:17 | Error | +| main.rs:751:13:751:17 | Input | main.rs:733:13:733:17 | Input | +| main.rs:756:19:756:22 | Self | main.rs:731:5:763:5 | impl Reduce for MyImpl::<...> { ... } | +| main.rs:756:19:756:29 | ...::Input | main.rs:741:9:745:9 | type Input | +| main.rs:757:14:760:9 | Result::<...> | {EXTERNAL LOCATION} | enum Result | +| main.rs:758:13:758:16 | Self | main.rs:731:5:763:5 | impl Reduce for MyImpl::<...> { ... } | +| main.rs:758:13:758:24 | ...::Output | main.rs:749:11:752:9 | type Output | +| main.rs:759:13:759:16 | Self | main.rs:731:5:763:5 | impl Reduce for MyImpl::<...> { ... } | +| main.rs:759:13:759:23 | ...::Error | main.rs:745:11:749:9 | type Error | +| main.rs:766:5:766:7 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) | +| main.rs:766:11:766:14 | self | {EXTERNAL LOCATION} | Crate(std@0.0.0) | +| main.rs:768:15:768:17 | ztd | {EXTERNAL LOCATION} | Crate(std@0.0.0) | +| main.rs:768:15:768:25 | ...::string | {EXTERNAL LOCATION} | mod string | +| main.rs:768:15:768:33 | ...::String | {EXTERNAL LOCATION} | struct String | +| main.rs:771:5:771:6 | my | main.rs:1:1:1:7 | mod my | +| main.rs:771:5:771:14 | ...::nested | my.rs:1:1:1:15 | mod nested | +| main.rs:771:5:771:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 | +| main.rs:771:5:771:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 | +| main.rs:771:5:771:35 | ...::f | my/nested.rs:3:9:5:9 | fn f | +| main.rs:772:5:772:6 | my | main.rs:1:1:1:7 | mod my | +| main.rs:772:5:772:9 | ...::f | my.rs:5:1:7:1 | fn f | +| main.rs:773:5:773:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | +| main.rs:773:5:773:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | +| main.rs:773:5:773:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | +| main.rs:773:5:773:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:774:5:774:5 | f | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:774:5:774:5 | f | my2/nested2.rs:23:9:25:9 | fn f | +| main.rs:775:5:775:5 | g | my2/nested2.rs:7:9:9:9 | fn g | +| main.rs:776:5:776:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) | +| main.rs:776:5:776:12 | ...::h | main.rs:56:1:75:1 | fn h | +| main.rs:777:5:777:6 | m1 | main.rs:19:1:43:1 | mod m1 | +| main.rs:777:5:777:10 | ...::m2 | main.rs:24:5:42:5 | mod m2 | +| main.rs:777:5:777:13 | ...::g | main.rs:29:9:33:9 | fn g | +| main.rs:778:5:778:6 | m1 | main.rs:19:1:43:1 | mod m1 | +| main.rs:778:5:778:10 | ...::m2 | main.rs:24:5:42:5 | mod m2 | +| main.rs:778:5:778:14 | ...::m3 | main.rs:35:9:41:9 | mod m3 | +| main.rs:778:5:778:17 | ...::h | main.rs:36:27:40:13 | fn h | +| main.rs:779:5:779:6 | m4 | main.rs:45:1:52:1 | mod m4 | +| main.rs:779:5:779:9 | ...::i | main.rs:48:5:51:5 | fn i | +| main.rs:780:5:780:5 | h | main.rs:56:1:75:1 | fn h | +| main.rs:781:5:781:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:782:5:782:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g | +| main.rs:783:5:783:5 | j | main.rs:103:1:107:1 | fn j | +| main.rs:784:5:784:6 | m6 | main.rs:115:1:126:1 | mod m6 | +| main.rs:784:5:784:9 | ...::g | main.rs:120:5:125:5 | fn g | +| main.rs:785:5:785:6 | m7 | main.rs:128:1:147:1 | mod m7 | +| main.rs:785:5:785:9 | ...::f | main.rs:139:5:146:5 | fn f | +| main.rs:786:5:786:6 | m8 | main.rs:149:1:203:1 | mod m8 | +| main.rs:786:5:786:9 | ...::g | main.rs:187:5:202:5 | fn g | +| main.rs:787:5:787:6 | m9 | main.rs:205:1:213:1 | mod m9 | +| main.rs:787:5:787:9 | ...::f | main.rs:208:5:212:5 | fn f | +| main.rs:788:5:788:7 | m11 | main.rs:236:1:273:1 | mod m11 | +| main.rs:788:5:788:10 | ...::f | main.rs:241:5:244:5 | fn f | +| main.rs:789:5:789:7 | m15 | main.rs:304:1:373:1 | mod m15 | +| main.rs:789:5:789:10 | ...::f | main.rs:360:5:372:5 | fn f | +| main.rs:790:5:790:7 | m16 | main.rs:375:1:467:1 | mod m16 | +| main.rs:790:5:790:10 | ...::f | main.rs:442:5:466:5 | fn f | +| main.rs:791:5:791:20 | trait_visibility | main.rs:469:1:519:1 | mod trait_visibility | +| main.rs:791:5:791:23 | ...::f | main.rs:496:5:518:5 | fn f | +| main.rs:792:5:792:7 | m17 | main.rs:521:1:551:1 | mod m17 | +| main.rs:792:5:792:10 | ...::f | main.rs:545:5:550:5 | fn f | +| main.rs:793:5:793:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 | +| main.rs:793:5:793:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f | +| main.rs:794:5:794:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 | +| main.rs:794:5:794:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f | +| main.rs:795:5:795:7 | my3 | my2/mod.rs:18:1:18:12 | mod my3 | +| main.rs:795:5:795:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f | +| main.rs:796:5:796:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f | +| main.rs:797:5:797:7 | m18 | main.rs:553:1:571:1 | mod m18 | +| main.rs:797:5:797:12 | ...::m19 | main.rs:558:5:570:5 | mod m19 | +| main.rs:797:5:797:17 | ...::m20 | main.rs:563:9:569:9 | mod m20 | +| main.rs:797:5:797:20 | ...::g | main.rs:564:13:568:13 | fn g | +| main.rs:798:5:798:7 | m23 | main.rs:600:1:625:1 | mod m23 | +| main.rs:798:5:798:10 | ...::f | main.rs:620:5:624:5 | fn f | +| main.rs:799:5:799:7 | m24 | main.rs:627:1:695:1 | mod m24 | +| main.rs:799:5:799:10 | ...::f | main.rs:681:5:694:5 | fn f | +| main.rs:800:5:800:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) | +| main.rs:800:5:800:11 | ...::h | main.rs:56:1:75:1 | fn h | +| main.rs:802:5:802:11 | AStruct | main.rs:702:1:702:17 | struct AStruct | +| main.rs:803:5:803:11 | AStruct | main.rs:702:1:702:17 | struct AStruct | | my2/mod.rs:5:5:5:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | | my2/mod.rs:5:5:5:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | | my2/mod.rs:5:5:5:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | | my2/mod.rs:5:5:5:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | | my2/mod.rs:8:9:8:15 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | | my2/mod.rs:8:9:8:24 | ...::nested5 | my2/nested2.rs:13:1:19:1 | mod nested5 | -| my2/mod.rs:10:9:10:15 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | -| my2/mod.rs:10:9:10:24 | ...::nested7 | my2/nested2.rs:21:1:27:1 | mod nested7 | -| my2/mod.rs:10:9:10:33 | ...::nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 | -| my2/mod.rs:10:37:10:40 | self | my2/nested2.rs:22:5:26:5 | mod nested8 | -| my2/mod.rs:17:5:17:9 | mymod | my2/mod.rs:14:1:15:10 | mod mymod | -| my2/mod.rs:17:5:17:12 | ...::f | my2/renamed.rs:1:1:1:13 | fn f | +| my2/mod.rs:11:9:11:15 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | +| my2/mod.rs:11:9:11:24 | ...::nested7 | my2/nested2.rs:21:1:27:1 | mod nested7 | +| my2/mod.rs:11:9:11:33 | ...::nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 | +| my2/mod.rs:12:5:12:8 | self | my2/nested2.rs:22:5:26:5 | mod nested8 | +| my2/mod.rs:13:5:13:5 | f | my2/nested2.rs:23:9:25:9 | fn f | +| my2/mod.rs:16:5:16:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | +| my2/mod.rs:16:5:16:20 | ...::nested5 | my2/nested2.rs:13:1:19:1 | mod nested5 | +| my2/mod.rs:16:5:16:29 | ...::nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 | +| my2/mod.rs:16:5:16:32 | ...::f | my2/nested2.rs:15:9:17:9 | fn f | +| my2/mod.rs:23:9:23:13 | mymod | my2/mod.rs:20:1:21:10 | mod mymod | +| my2/mod.rs:23:9:23:16 | ...::f | my2/renamed.rs:1:1:1:13 | fn f | | my2/my3/mod.rs:3:5:3:5 | g | my2/mod.rs:3:1:6:1 | fn g | -| my2/my3/mod.rs:4:5:4:5 | h | main.rs:50:1:69:1 | fn h | -| my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:17:30 | SourceFile | -| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:799:2 | SourceFile | -| my2/my3/mod.rs:7:5:7:19 | ...::h | main.rs:50:1:69:1 | fn h | -| my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:17:30 | SourceFile | +| my2/my3/mod.rs:4:5:4:5 | h | main.rs:56:1:75:1 | fn h | +| my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | +| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:805:2 | SourceFile | +| my2/my3/mod.rs:7:5:7:19 | ...::h | main.rs:56:1:75:1 | fn h | +| my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | | my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g | +| my2/my3/mod.rs:10:5:10:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | | my.rs:3:5:3:10 | nested | my.rs:1:1:1:15 | mod nested | | my.rs:3:5:3:13 | ...::g | my/nested.rs:19:1:22:1 | fn g | | my.rs:11:5:11:5 | g | my/nested.rs:19:1:22:1 | fn g | From f6bdfba3b328e8f9d42f5af0fa0cae8363122e84 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 17 Sep 2025 13:43:39 +0200 Subject: [PATCH 037/160] Rust: Path resolution improvements --- .../codeql/rust/internal/PathResolution.qll | 60 +- .../PathResolutionConsistency.expected | 2 + .../dataflow/sources/InlineFlow.expected | 840 +++++++++--------- .../library-tests/dataflow/sources/test.rs | 4 +- .../PathResolutionConsistency.expected | 1 - .../library-tests/path-resolution/main.rs | 2 +- .../path-resolution/my2/my3/mod.rs | 2 +- .../path-resolution/path-resolution.expected | 2 +- 8 files changed, 497 insertions(+), 416 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 4b718fc4399..f819632ce10 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -72,9 +72,9 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki if item instanceof ImplOrTraitItemNode and result instanceof AssocItem then kind.isExternal() else - if result instanceof Use - then kind.isInternal() - else kind.isBoth() + if result.isPublic() + then kind.isBoth() + else kind.isInternal() ) } @@ -165,6 +165,20 @@ abstract class ItemNode extends Locatable { /** Gets the visibility of this item, if any. */ abstract Visibility getVisibility(); + /** + * Holds if this item is public. + * + * This is the case when this item either has `pub` visibility (but is not + * a `use`; a `use` itself is not visible from the outside), or when this + * item is a variant. + */ + predicate isPublic() { + exists(this.getVisibility()) and + not this instanceof Use + or + this instanceof Variant + } + /** Gets the `i`th type parameter of this item, if any. */ abstract TypeParam getTypeParam(int i); @@ -380,9 +394,7 @@ abstract private class ModuleLikeNode extends ItemNode { private class SourceFileItemNode extends ModuleLikeNode, SourceFile { pragma[nomagic] - ModuleLikeNode getSuper() { - result = any(ModuleItemNode mod | fileImport(mod, this)).getASuccessor("super") - } + ModuleLikeNode getSuper() { fileImport(result.getAnItemInScope(), this) } override string getName() { result = "(source file)" } @@ -1300,7 +1312,8 @@ private predicate useTreeDeclares(UseTree tree, string name) { */ pragma[nomagic] private predicate declaresDirectly(ItemNode item, Namespace ns, string name) { - exists(ItemNode child, SuccessorKind kind | child = getAChildSuccessor(item, name, kind) | + exists(ItemNode child, SuccessorKind kind | + child = getAChildSuccessor(item, name, kind) and child.getNamespace() = ns and kind.isInternalOrBoth() ) @@ -1491,6 +1504,13 @@ private ItemNode resolvePathCandQualifier(RelevantPath qualifier, RelevantPath p name = path.getText() } +pragma[nomagic] +private Crate getCrate0(Locatable l) { result.getASourceFile().getFile() = l.getFile() } + +bindingset[l] +pragma[inline_late] +private Crate getCrate(Locatable l) { result = getCrate0(l) } + /** * Gets the item that `path` resolves to in `ns` when `qualifier` is the * qualifier of `path` and `qualifier` resolves to `q`, if any. @@ -1501,8 +1521,17 @@ private ItemNode resolvePathCandQualified( ) { exists(string name, SuccessorKind kind | q = resolvePathCandQualifier(qualifier, path, name) and - result = getASuccessor(q, name, ns, kind) and + result = getASuccessor(q, name, ns, kind) + | kind.isExternalOrBoth() + or + // Non-public items are visible to paths in descendant modules of the declaring + // module; the declaration may happen via a `use` statement, where the item + // being used is _not_ itself in an ancestor module, and we currently don't track + // that information in `getASuccessor`. So, for simplicity, we allow for non-public + // items when the path and the item are in the same crate. + getCrate(path) = getCrate(result) and + not result instanceof TypeParam ) } @@ -1646,10 +1675,12 @@ private ItemNode resolveUseTreeListItemQualifier( pragma[nomagic] private ItemNode resolveUseTreeListItem(Use use, UseTree tree) { - tree = use.getUseTree() and - result = resolvePathCand(tree.getPath()) - or - result = resolveUseTreeListItem(use, tree, tree.getPath(), _) + exists(Path path | path = tree.getPath() | + tree = use.getUseTree() and + result = resolvePathCand(path) + or + result = resolveUseTreeListItem(use, tree, path, _) + ) } /** Holds if `use` imports `item` as `name`. */ @@ -1673,7 +1704,10 @@ private predicate useImportEdge(Use use, string name, ItemNode item, SuccessorKi item = used and ( not tree.hasRename() and - name = item.getName() + exists(string pathName | + pathName = tree.getPath().getText() and + if pathName = "self" then name = item.getName() else name = pathName + ) or exists(Rename rename | rename = tree.getRename() | name = rename.getName().getText() diff --git a/rust/ql/test/library-tests/dataflow/sources/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/library-tests/dataflow/sources/CONSISTENCY/PathResolutionConsistency.expected index 5ba71c14933..0fb7a59f6f4 100644 --- a/rust/ql/test/library-tests/dataflow/sources/CONSISTENCY/PathResolutionConsistency.expected +++ b/rust/ql/test/library-tests/dataflow/sources/CONSISTENCY/PathResolutionConsistency.expected @@ -11,6 +11,8 @@ multipleCallTargets | test.rs:179:30:179:68 | ...::_print(...) | | test.rs:188:26:188:105 | ...::_print(...) | | test.rs:229:22:229:72 | ... .read_to_string(...) | +| test.rs:664:22:664:43 | file.read(...) | +| test.rs:673:22:673:41 | f1.read(...) | | test.rs:697:18:697:38 | ...::_print(...) | | test.rs:702:18:702:45 | ...::_print(...) | | test.rs:720:38:720:42 | ...::_print(...) | diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected index 88a728253d8..db0cb969d5a 100644 --- a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected @@ -1,138 +1,140 @@ models -| 1 | Source: ::connect; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | -| 2 | Source: ::send_request; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | -| 3 | Source: ::file_name; ReturnValue; file | -| 4 | Source: ::path; ReturnValue; file | -| 5 | Source: ::open; ReturnValue.Field[core::result::Result::Ok(0)]; file | -| 6 | Source: ::open; ReturnValue.Field[core::result::Result::Ok(0)]; file | -| 7 | Source: ::connect; ReturnValue.Field[core::result::Result::Ok(0)]; remote | -| 8 | Source: ::connect_timeout; ReturnValue.Field[core::result::Result::Ok(0)]; remote | -| 9 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 10 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 11 | Source: ::file_name; ReturnValue; file | -| 12 | Source: ::path; ReturnValue; file | -| 13 | Source: ::connect; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | -| 14 | Source: reqwest::blocking::get; ReturnValue.Field[core::result::Result::Ok(0)]; remote | -| 15 | Source: reqwest::get; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | -| 16 | Source: std::env::args; ReturnValue.Element; commandargs | -| 17 | Source: std::env::args_os; ReturnValue.Element; commandargs | -| 18 | Source: std::env::current_dir; ReturnValue.Field[core::result::Result::Ok(0)]; commandargs | -| 19 | Source: std::env::current_exe; ReturnValue.Field[core::result::Result::Ok(0)]; commandargs | -| 20 | Source: std::env::home_dir; ReturnValue.Field[core::option::Option::Some(0)]; commandargs | -| 21 | Source: std::env::var; ReturnValue.Field[core::result::Result::Ok(0)]; environment | -| 22 | Source: std::env::var_os; ReturnValue.Field[core::option::Option::Some(0)]; environment | -| 23 | Source: std::fs::read; ReturnValue.Field[core::result::Result::Ok(0)]; file | -| 24 | Source: std::fs::read; ReturnValue; file | -| 25 | Source: std::fs::read_link; ReturnValue.Field[core::result::Result::Ok(0)]; file | -| 26 | Source: std::fs::read_to_string; ReturnValue.Field[core::result::Result::Ok(0)]; file | -| 27 | Source: std::fs::read_to_string; ReturnValue; file | -| 28 | Source: std::io::stdio::stdin; ReturnValue; stdin | -| 29 | Source: tokio::fs::read::read; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 30 | Source: tokio::fs::read_link::read_link; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 31 | Source: tokio::fs::read_to_string::read_to_string; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 32 | Source: tokio::io::stdin::stdin; ReturnValue; stdin | -| 33 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value | -| 34 | Summary: <_ as core::iter::traits::iterator::Iterator>::collect; Argument[self].Element; ReturnValue.Element; value | -| 35 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Element; ReturnValue.Field[core::option::Option::Some(0)]; value | -| 36 | Summary: <_ as futures_io::if_std::AsyncBufRead>::poll_fill_buf; Argument[self].Reference; ReturnValue.Field[core::task::poll::Poll::Ready(0)].Field[core::result::Result::Ok(0)]; taint | -| 37 | Summary: <_ as futures_util::io::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 38 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self].Reference; Argument[0].Reference; taint | -| 39 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | -| 40 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self].Reference; Argument[1].Reference; taint | -| 41 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | -| 42 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint | -| 43 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | -| 44 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self].Reference; Argument[0].Reference; taint | -| 45 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 46 | Summary: <_ as std::io::BufRead>::lines; Argument[self]; ReturnValue; taint | -| 47 | Summary: <_ as std::io::BufRead>::read_line; Argument[self]; Argument[0].Reference; taint | -| 48 | Summary: <_ as std::io::BufRead>::read_until; Argument[self]; Argument[1].Reference; taint | -| 49 | Summary: <_ as std::io::BufRead>::split; Argument[self]; ReturnValue; taint | -| 50 | Summary: <_ as std::io::Read>::bytes; Argument[self]; ReturnValue; taint | -| 51 | Summary: <_ as std::io::Read>::chain; Argument[0]; ReturnValue; taint | -| 52 | Summary: <_ as std::io::Read>::chain; Argument[self]; ReturnValue; taint | -| 53 | Summary: <_ as std::io::Read>::read; Argument[self]; Argument[0].Reference; taint | -| 54 | Summary: <_ as std::io::Read>::read_exact; Argument[self]; Argument[0].Reference; taint | -| 55 | Summary: <_ as std::io::Read>::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 56 | Summary: <_ as std::io::Read>::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 57 | Summary: <_ as std::io::Read>::take; Argument[self]; ReturnValue; taint | -| 58 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 59 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::lines; Argument[self]; ReturnValue; taint | -| 60 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | -| 61 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | -| 62 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::split; Argument[self]; ReturnValue; taint | -| 63 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | -| 64 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_buf; Argument[self]; Argument[0].Reference; taint | -| 65 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_exact; Argument[self]; Argument[0].Reference; taint | -| 66 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_f32; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 67 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i16; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 68 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i64_le; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 69 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 70 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 71 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_u8; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 72 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | -| 73 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 74 | Summary: ::expect; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | -| 75 | Summary: ::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | -| 76 | Summary: ::new; Argument[0].Reference; ReturnValue; value | -| 77 | Summary: ::new; Argument[0]; ReturnValue.Field[core::pin::Pin::__pointer]; value | -| 78 | Summary: ::new; Argument[0]; ReturnValue; value | -| 79 | Summary: ::expect; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 80 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 81 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | -| 82 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 83 | Summary: ::parse; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 84 | Summary: ::connect; Argument[1]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 85 | Summary: ::new; Argument[0]; ReturnValue; taint | -| 86 | Summary: ::bytes; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 87 | Summary: ::chunk; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | -| 88 | Summary: ::text; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 89 | Summary: ::bytes; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 90 | Summary: ::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 91 | Summary: ::text_with_charset; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 92 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | -| 93 | Summary: ::read; Argument[self]; Argument[0]; taint | -| 94 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 95 | Summary: ::read_to_end; Argument[self]; Argument[0]; taint | -| 96 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 97 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | -| 98 | Summary: ::next; Argument[self]; ReturnValue.Field[core::option::Option::Some(0)].Field[core::result::Result::Ok(0)]; taint | -| 99 | Summary: ::fill_buf; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 100 | Summary: ::buffer; Argument[self]; ReturnValue; taint | -| 101 | Summary: ::new; Argument[0]; ReturnValue; taint | -| 102 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | -| 103 | Summary: ::read; Argument[self]; Argument[0]; taint | -| 104 | Summary: ::read_exact; Argument[self]; Argument[0].Reference; taint | -| 105 | Summary: ::read_exact; Argument[self]; Argument[0]; taint | -| 106 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 107 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 108 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | -| 109 | Summary: ::lock; Argument[self]; ReturnValue; taint | -| 110 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 111 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | -| 112 | Summary: ::as_path; Argument[self]; ReturnValue; value | -| 113 | Summary: ::buffer; Argument[self]; ReturnValue; taint | -| 114 | Summary: ::new; Argument[0]; ReturnValue; taint | -| 115 | Summary: ::next_line; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | -| 116 | Summary: ::next_segment; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | -| 117 | Summary: ::peek; Argument[self]; Argument[0].Reference; taint | -| 118 | Summary: ::try_read; Argument[self]; Argument[0].Reference; taint | -| 119 | Summary: ::try_read_buf; Argument[self]; Argument[0].Reference; taint | +| 1 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 2 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 3 | Source: ::connect; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | +| 4 | Source: ::send_request; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | +| 5 | Source: ::file_name; ReturnValue; file | +| 6 | Source: ::path; ReturnValue; file | +| 7 | Source: ::open; ReturnValue.Field[core::result::Result::Ok(0)]; file | +| 8 | Source: ::open; ReturnValue.Field[core::result::Result::Ok(0)]; file | +| 9 | Source: ::connect; ReturnValue.Field[core::result::Result::Ok(0)]; remote | +| 10 | Source: ::connect_timeout; ReturnValue.Field[core::result::Result::Ok(0)]; remote | +| 11 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 12 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 13 | Source: ::file_name; ReturnValue; file | +| 14 | Source: ::path; ReturnValue; file | +| 15 | Source: ::connect; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | +| 16 | Source: reqwest::blocking::get; ReturnValue.Field[core::result::Result::Ok(0)]; remote | +| 17 | Source: reqwest::get; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | +| 18 | Source: std::env::args; ReturnValue.Element; commandargs | +| 19 | Source: std::env::args_os; ReturnValue.Element; commandargs | +| 20 | Source: std::env::current_dir; ReturnValue.Field[core::result::Result::Ok(0)]; commandargs | +| 21 | Source: std::env::current_exe; ReturnValue.Field[core::result::Result::Ok(0)]; commandargs | +| 22 | Source: std::env::home_dir; ReturnValue.Field[core::option::Option::Some(0)]; commandargs | +| 23 | Source: std::env::var; ReturnValue.Field[core::result::Result::Ok(0)]; environment | +| 24 | Source: std::env::var_os; ReturnValue.Field[core::option::Option::Some(0)]; environment | +| 25 | Source: std::fs::read; ReturnValue.Field[core::result::Result::Ok(0)]; file | +| 26 | Source: std::fs::read; ReturnValue; file | +| 27 | Source: std::fs::read_link; ReturnValue.Field[core::result::Result::Ok(0)]; file | +| 28 | Source: std::fs::read_to_string; ReturnValue.Field[core::result::Result::Ok(0)]; file | +| 29 | Source: std::fs::read_to_string; ReturnValue; file | +| 30 | Source: std::io::stdio::stdin; ReturnValue; stdin | +| 31 | Source: tokio::fs::read::read; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 32 | Source: tokio::fs::read_link::read_link; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 33 | Source: tokio::fs::read_to_string::read_to_string; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 34 | Source: tokio::io::stdin::stdin; ReturnValue; stdin | +| 35 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value | +| 36 | Summary: <_ as core::iter::traits::iterator::Iterator>::collect; Argument[self].Element; ReturnValue.Element; value | +| 37 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Element; ReturnValue.Field[core::option::Option::Some(0)]; value | +| 38 | Summary: <_ as futures_io::if_std::AsyncBufRead>::poll_fill_buf; Argument[self].Reference; ReturnValue.Field[core::task::poll::Poll::Ready(0)].Field[core::result::Result::Ok(0)]; taint | +| 39 | Summary: <_ as futures_util::io::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 40 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self].Reference; Argument[0].Reference; taint | +| 41 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | +| 42 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self].Reference; Argument[1].Reference; taint | +| 43 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | +| 44 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint | +| 45 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | +| 46 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self].Reference; Argument[0].Reference; taint | +| 47 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 48 | Summary: <_ as std::io::BufRead>::lines; Argument[self]; ReturnValue; taint | +| 49 | Summary: <_ as std::io::BufRead>::read_line; Argument[self]; Argument[0].Reference; taint | +| 50 | Summary: <_ as std::io::BufRead>::read_until; Argument[self]; Argument[1].Reference; taint | +| 51 | Summary: <_ as std::io::BufRead>::split; Argument[self]; ReturnValue; taint | +| 52 | Summary: <_ as std::io::Read>::bytes; Argument[self]; ReturnValue; taint | +| 53 | Summary: <_ as std::io::Read>::chain; Argument[0]; ReturnValue; taint | +| 54 | Summary: <_ as std::io::Read>::chain; Argument[self]; ReturnValue; taint | +| 55 | Summary: <_ as std::io::Read>::read; Argument[self]; Argument[0].Reference; taint | +| 56 | Summary: <_ as std::io::Read>::read_exact; Argument[self]; Argument[0].Reference; taint | +| 57 | Summary: <_ as std::io::Read>::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 58 | Summary: <_ as std::io::Read>::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 59 | Summary: <_ as std::io::Read>::take; Argument[self]; ReturnValue; taint | +| 60 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 61 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::lines; Argument[self]; ReturnValue; taint | +| 62 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | +| 63 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | +| 64 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::split; Argument[self]; ReturnValue; taint | +| 65 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | +| 66 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_buf; Argument[self]; Argument[0].Reference; taint | +| 67 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_exact; Argument[self]; Argument[0].Reference; taint | +| 68 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_f32; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 69 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i16; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 70 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i64_le; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 71 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 72 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 73 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_u8; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 74 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | +| 75 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 76 | Summary: ::expect; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | +| 77 | Summary: ::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | +| 78 | Summary: ::new; Argument[0].Reference; ReturnValue; value | +| 79 | Summary: ::new; Argument[0]; ReturnValue.Field[core::pin::Pin::__pointer]; value | +| 80 | Summary: ::new; Argument[0]; ReturnValue; value | +| 81 | Summary: ::expect; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | +| 82 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | +| 83 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | +| 84 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 85 | Summary: ::parse; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 86 | Summary: ::connect; Argument[1]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 87 | Summary: ::new; Argument[0]; ReturnValue; taint | +| 88 | Summary: ::bytes; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 89 | Summary: ::chunk; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | +| 90 | Summary: ::text; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 91 | Summary: ::bytes; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 92 | Summary: ::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 93 | Summary: ::text_with_charset; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 94 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | +| 95 | Summary: ::read; Argument[self]; Argument[0]; taint | +| 96 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 97 | Summary: ::read_to_end; Argument[self]; Argument[0]; taint | +| 98 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 99 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | +| 100 | Summary: ::next; Argument[self]; ReturnValue.Field[core::option::Option::Some(0)].Field[core::result::Result::Ok(0)]; taint | +| 101 | Summary: ::fill_buf; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 102 | Summary: ::buffer; Argument[self]; ReturnValue; taint | +| 103 | Summary: ::new; Argument[0]; ReturnValue; taint | +| 104 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | +| 105 | Summary: ::read; Argument[self]; Argument[0]; taint | +| 106 | Summary: ::read_exact; Argument[self]; Argument[0].Reference; taint | +| 107 | Summary: ::read_exact; Argument[self]; Argument[0]; taint | +| 108 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 109 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 110 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | +| 111 | Summary: ::lock; Argument[self]; ReturnValue; taint | +| 112 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 113 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | +| 114 | Summary: ::as_path; Argument[self]; ReturnValue; value | +| 115 | Summary: ::buffer; Argument[self]; ReturnValue; taint | +| 116 | Summary: ::new; Argument[0]; ReturnValue; taint | +| 117 | Summary: ::next_line; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | +| 118 | Summary: ::next_segment; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | +| 119 | Summary: ::peek; Argument[self]; Argument[0].Reference; taint | +| 120 | Summary: ::try_read; Argument[self]; Argument[0].Reference; taint | +| 121 | Summary: ::try_read_buf; Argument[self]; Argument[0].Reference; taint | edges -| test.rs:8:10:8:22 | ...::var | test.rs:8:10:8:30 | ...::var(...) | provenance | Src:MaD:21 | -| test.rs:9:10:9:25 | ...::var_os | test.rs:9:10:9:33 | ...::var_os(...) | provenance | Src:MaD:22 | +| test.rs:8:10:8:22 | ...::var | test.rs:8:10:8:30 | ...::var(...) | provenance | Src:MaD:23 | +| test.rs:9:10:9:25 | ...::var_os | test.rs:9:10:9:33 | ...::var_os(...) | provenance | Src:MaD:24 | | test.rs:11:9:11:12 | var1 | test.rs:14:10:14:13 | var1 | provenance | | -| test.rs:11:16:11:28 | ...::var | test.rs:11:16:11:36 | ...::var(...) [Ok] | provenance | Src:MaD:21 | -| test.rs:11:16:11:36 | ...::var(...) [Ok] | test.rs:11:16:11:59 | ... .expect(...) | provenance | MaD:79 | +| test.rs:11:16:11:28 | ...::var | test.rs:11:16:11:36 | ...::var(...) [Ok] | provenance | Src:MaD:23 | +| test.rs:11:16:11:36 | ...::var(...) [Ok] | test.rs:11:16:11:59 | ... .expect(...) | provenance | MaD:81 | | test.rs:11:16:11:59 | ... .expect(...) | test.rs:11:9:11:12 | var1 | provenance | | | test.rs:12:9:12:12 | var2 | test.rs:15:10:15:13 | var2 | provenance | | -| test.rs:12:16:12:31 | ...::var_os | test.rs:12:16:12:39 | ...::var_os(...) [Some] | provenance | Src:MaD:22 | -| test.rs:12:16:12:39 | ...::var_os(...) [Some] | test.rs:12:16:12:48 | ... .unwrap() | provenance | MaD:75 | +| test.rs:12:16:12:31 | ...::var_os | test.rs:12:16:12:39 | ...::var_os(...) [Some] | provenance | Src:MaD:24 | +| test.rs:12:16:12:39 | ...::var_os(...) [Some] | test.rs:12:16:12:48 | ... .unwrap() | provenance | MaD:77 | | test.rs:12:16:12:48 | ... .unwrap() | test.rs:12:9:12:12 | var2 | provenance | | | test.rs:29:9:29:12 | args [element] | test.rs:30:20:30:23 | args [element] | provenance | | | test.rs:29:9:29:12 | args [element] | test.rs:31:17:31:20 | args [element] | provenance | | -| test.rs:29:29:29:42 | ...::args | test.rs:29:29:29:44 | ...::args(...) [element] | provenance | Src:MaD:16 | -| test.rs:29:29:29:44 | ...::args(...) [element] | test.rs:29:29:29:54 | ... .collect() [element] | provenance | MaD:34 | +| test.rs:29:29:29:42 | ...::args | test.rs:29:29:29:44 | ...::args(...) [element] | provenance | Src:MaD:18 | +| test.rs:29:29:29:44 | ...::args(...) [element] | test.rs:29:29:29:54 | ... .collect() [element] | provenance | MaD:36 | | test.rs:29:29:29:54 | ... .collect() [element] | test.rs:29:9:29:12 | args [element] | provenance | | | test.rs:30:9:30:15 | my_path [&ref] | test.rs:36:10:36:16 | my_path | provenance | | | test.rs:30:19:30:26 | &... [&ref] | test.rs:30:9:30:15 | my_path [&ref] | provenance | | @@ -143,89 +145,89 @@ edges | test.rs:31:17:31:20 | args [element] | test.rs:31:17:31:23 | args[1] | provenance | | | test.rs:31:17:31:23 | args[1] | test.rs:31:16:31:23 | &... [&ref] | provenance | | | test.rs:32:9:32:12 | arg2 | test.rs:38:10:38:13 | arg2 | provenance | | -| test.rs:32:16:32:29 | ...::args | test.rs:32:16:32:31 | ...::args(...) [element] | provenance | Src:MaD:16 | -| test.rs:32:16:32:31 | ...::args(...) [element] | test.rs:32:16:32:38 | ... .nth(...) [Some] | provenance | MaD:35 | -| test.rs:32:16:32:38 | ... .nth(...) [Some] | test.rs:32:16:32:47 | ... .unwrap() | provenance | MaD:75 | +| test.rs:32:16:32:29 | ...::args | test.rs:32:16:32:31 | ...::args(...) [element] | provenance | Src:MaD:18 | +| test.rs:32:16:32:31 | ...::args(...) [element] | test.rs:32:16:32:38 | ... .nth(...) [Some] | provenance | MaD:37 | +| test.rs:32:16:32:38 | ... .nth(...) [Some] | test.rs:32:16:32:47 | ... .unwrap() | provenance | MaD:77 | | test.rs:32:16:32:47 | ... .unwrap() | test.rs:32:9:32:12 | arg2 | provenance | | | test.rs:33:9:33:12 | arg3 | test.rs:39:10:39:13 | arg3 | provenance | | -| test.rs:33:16:33:32 | ...::args_os | test.rs:33:16:33:34 | ...::args_os(...) [element] | provenance | Src:MaD:17 | -| test.rs:33:16:33:34 | ...::args_os(...) [element] | test.rs:33:16:33:41 | ... .nth(...) [Some] | provenance | MaD:35 | -| test.rs:33:16:33:41 | ... .nth(...) [Some] | test.rs:33:16:33:50 | ... .unwrap() | provenance | MaD:75 | +| test.rs:33:16:33:32 | ...::args_os | test.rs:33:16:33:34 | ...::args_os(...) [element] | provenance | Src:MaD:19 | +| test.rs:33:16:33:34 | ...::args_os(...) [element] | test.rs:33:16:33:41 | ... .nth(...) [Some] | provenance | MaD:37 | +| test.rs:33:16:33:41 | ... .nth(...) [Some] | test.rs:33:16:33:50 | ... .unwrap() | provenance | MaD:77 | | test.rs:33:16:33:50 | ... .unwrap() | test.rs:33:9:33:12 | arg3 | provenance | | | test.rs:34:9:34:12 | arg4 | test.rs:40:10:40:13 | arg4 | provenance | | -| test.rs:34:16:34:29 | ...::args | test.rs:34:16:34:31 | ...::args(...) [element] | provenance | Src:MaD:16 | -| test.rs:34:16:34:31 | ...::args(...) [element] | test.rs:34:16:34:38 | ... .nth(...) [Some] | provenance | MaD:35 | -| test.rs:34:16:34:38 | ... .nth(...) [Some] | test.rs:34:16:34:47 | ... .unwrap() | provenance | MaD:75 | -| test.rs:34:16:34:47 | ... .unwrap() | test.rs:34:16:34:64 | ... .parse() [Ok] | provenance | MaD:83 | -| test.rs:34:16:34:64 | ... .parse() [Ok] | test.rs:34:16:34:73 | ... .unwrap() | provenance | MaD:80 | +| test.rs:34:16:34:29 | ...::args | test.rs:34:16:34:31 | ...::args(...) [element] | provenance | Src:MaD:18 | +| test.rs:34:16:34:31 | ...::args(...) [element] | test.rs:34:16:34:38 | ... .nth(...) [Some] | provenance | MaD:37 | +| test.rs:34:16:34:38 | ... .nth(...) [Some] | test.rs:34:16:34:47 | ... .unwrap() | provenance | MaD:77 | +| test.rs:34:16:34:47 | ... .unwrap() | test.rs:34:16:34:64 | ... .parse() [Ok] | provenance | MaD:85 | +| test.rs:34:16:34:64 | ... .parse() [Ok] | test.rs:34:16:34:73 | ... .unwrap() | provenance | MaD:82 | | test.rs:34:16:34:73 | ... .unwrap() | test.rs:34:9:34:12 | arg4 | provenance | | | test.rs:42:9:42:11 | arg | test.rs:43:14:43:16 | arg | provenance | | -| test.rs:42:16:42:29 | ...::args | test.rs:42:16:42:31 | ...::args(...) [element] | provenance | Src:MaD:16 | +| test.rs:42:16:42:29 | ...::args | test.rs:42:16:42:31 | ...::args(...) [element] | provenance | Src:MaD:18 | | test.rs:42:16:42:31 | ...::args(...) [element] | test.rs:42:9:42:11 | arg | provenance | | | test.rs:46:9:46:11 | arg | test.rs:47:14:47:16 | arg | provenance | | -| test.rs:46:16:46:32 | ...::args_os | test.rs:46:16:46:34 | ...::args_os(...) [element] | provenance | Src:MaD:17 | +| test.rs:46:16:46:32 | ...::args_os | test.rs:46:16:46:34 | ...::args_os(...) [element] | provenance | Src:MaD:19 | | test.rs:46:16:46:34 | ...::args_os(...) [element] | test.rs:46:9:46:11 | arg | provenance | | | test.rs:52:9:52:11 | dir | test.rs:56:10:56:12 | dir | provenance | | -| test.rs:52:15:52:35 | ...::current_dir | test.rs:52:15:52:37 | ...::current_dir(...) [Ok] | provenance | Src:MaD:18 | -| test.rs:52:15:52:37 | ...::current_dir(...) [Ok] | test.rs:52:15:52:54 | ... .expect(...) | provenance | MaD:79 | +| test.rs:52:15:52:35 | ...::current_dir | test.rs:52:15:52:37 | ...::current_dir(...) [Ok] | provenance | Src:MaD:20 | +| test.rs:52:15:52:37 | ...::current_dir(...) [Ok] | test.rs:52:15:52:54 | ... .expect(...) | provenance | MaD:81 | | test.rs:52:15:52:54 | ... .expect(...) | test.rs:52:9:52:11 | dir | provenance | | | test.rs:53:9:53:11 | exe | test.rs:57:10:57:12 | exe | provenance | | -| test.rs:53:15:53:35 | ...::current_exe | test.rs:53:15:53:37 | ...::current_exe(...) [Ok] | provenance | Src:MaD:19 | -| test.rs:53:15:53:37 | ...::current_exe(...) [Ok] | test.rs:53:15:53:54 | ... .expect(...) | provenance | MaD:79 | +| test.rs:53:15:53:35 | ...::current_exe | test.rs:53:15:53:37 | ...::current_exe(...) [Ok] | provenance | Src:MaD:21 | +| test.rs:53:15:53:37 | ...::current_exe(...) [Ok] | test.rs:53:15:53:54 | ... .expect(...) | provenance | MaD:81 | | test.rs:53:15:53:54 | ... .expect(...) | test.rs:53:9:53:11 | exe | provenance | | | test.rs:54:9:54:12 | home | test.rs:58:10:58:13 | home | provenance | | -| test.rs:54:16:54:33 | ...::home_dir | test.rs:54:16:54:35 | ...::home_dir(...) [Some] | provenance | Src:MaD:20 | -| test.rs:54:16:54:35 | ...::home_dir(...) [Some] | test.rs:54:16:54:52 | ... .expect(...) | provenance | MaD:74 | +| test.rs:54:16:54:33 | ...::home_dir | test.rs:54:16:54:35 | ...::home_dir(...) [Some] | provenance | Src:MaD:22 | +| test.rs:54:16:54:35 | ...::home_dir(...) [Some] | test.rs:54:16:54:52 | ... .expect(...) | provenance | MaD:76 | | test.rs:54:16:54:52 | ... .expect(...) | test.rs:54:9:54:12 | home | provenance | | | test.rs:62:9:62:22 | remote_string1 | test.rs:63:10:63:23 | remote_string1 | provenance | | -| test.rs:62:26:62:47 | ...::get | test.rs:62:26:62:62 | ...::get(...) [Ok] | provenance | Src:MaD:14 | +| test.rs:62:26:62:47 | ...::get | test.rs:62:26:62:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | | test.rs:62:26:62:62 | ...::get(...) [Ok] | test.rs:62:26:62:63 | TryExpr | provenance | | -| test.rs:62:26:62:63 | TryExpr | test.rs:62:26:62:70 | ... .text() [Ok] | provenance | MaD:90 | +| test.rs:62:26:62:63 | TryExpr | test.rs:62:26:62:70 | ... .text() [Ok] | provenance | MaD:92 | | test.rs:62:26:62:70 | ... .text() [Ok] | test.rs:62:26:62:71 | TryExpr | provenance | | | test.rs:62:26:62:71 | TryExpr | test.rs:62:9:62:22 | remote_string1 | provenance | | | test.rs:65:9:65:22 | remote_string2 | test.rs:66:10:66:23 | remote_string2 | provenance | | -| test.rs:65:26:65:47 | ...::get | test.rs:65:26:65:62 | ...::get(...) [Ok] | provenance | Src:MaD:14 | -| test.rs:65:26:65:62 | ...::get(...) [Ok] | test.rs:65:26:65:71 | ... .unwrap() | provenance | MaD:80 | -| test.rs:65:26:65:71 | ... .unwrap() | test.rs:65:26:65:78 | ... .text() [Ok] | provenance | MaD:90 | -| test.rs:65:26:65:78 | ... .text() [Ok] | test.rs:65:26:65:87 | ... .unwrap() | provenance | MaD:80 | +| test.rs:65:26:65:47 | ...::get | test.rs:65:26:65:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | +| test.rs:65:26:65:62 | ...::get(...) [Ok] | test.rs:65:26:65:71 | ... .unwrap() | provenance | MaD:82 | +| test.rs:65:26:65:71 | ... .unwrap() | test.rs:65:26:65:78 | ... .text() [Ok] | provenance | MaD:92 | +| test.rs:65:26:65:78 | ... .text() [Ok] | test.rs:65:26:65:87 | ... .unwrap() | provenance | MaD:82 | | test.rs:65:26:65:87 | ... .unwrap() | test.rs:65:9:65:22 | remote_string2 | provenance | | | test.rs:68:9:68:22 | remote_string3 | test.rs:69:10:69:23 | remote_string3 | provenance | | -| test.rs:68:26:68:47 | ...::get | test.rs:68:26:68:62 | ...::get(...) [Ok] | provenance | Src:MaD:14 | -| test.rs:68:26:68:62 | ...::get(...) [Ok] | test.rs:68:26:68:71 | ... .unwrap() | provenance | MaD:80 | -| test.rs:68:26:68:71 | ... .unwrap() | test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | provenance | MaD:91 | -| test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | test.rs:68:26:68:107 | ... .unwrap() | provenance | MaD:80 | +| test.rs:68:26:68:47 | ...::get | test.rs:68:26:68:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | +| test.rs:68:26:68:62 | ...::get(...) [Ok] | test.rs:68:26:68:71 | ... .unwrap() | provenance | MaD:82 | +| test.rs:68:26:68:71 | ... .unwrap() | test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | provenance | MaD:93 | +| test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | test.rs:68:26:68:107 | ... .unwrap() | provenance | MaD:82 | | test.rs:68:26:68:107 | ... .unwrap() | test.rs:68:9:68:22 | remote_string3 | provenance | | | test.rs:71:9:71:22 | remote_string4 | test.rs:72:10:72:23 | remote_string4 | provenance | | -| test.rs:71:26:71:47 | ...::get | test.rs:71:26:71:62 | ...::get(...) [Ok] | provenance | Src:MaD:14 | -| test.rs:71:26:71:62 | ...::get(...) [Ok] | test.rs:71:26:71:71 | ... .unwrap() | provenance | MaD:80 | -| test.rs:71:26:71:71 | ... .unwrap() | test.rs:71:26:71:79 | ... .bytes() [Ok] | provenance | MaD:89 | -| test.rs:71:26:71:79 | ... .bytes() [Ok] | test.rs:71:26:71:88 | ... .unwrap() | provenance | MaD:80 | +| test.rs:71:26:71:47 | ...::get | test.rs:71:26:71:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | +| test.rs:71:26:71:62 | ...::get(...) [Ok] | test.rs:71:26:71:71 | ... .unwrap() | provenance | MaD:82 | +| test.rs:71:26:71:71 | ... .unwrap() | test.rs:71:26:71:79 | ... .bytes() [Ok] | provenance | MaD:91 | +| test.rs:71:26:71:79 | ... .bytes() [Ok] | test.rs:71:26:71:88 | ... .unwrap() | provenance | MaD:82 | | test.rs:71:26:71:88 | ... .unwrap() | test.rs:71:9:71:22 | remote_string4 | provenance | | | test.rs:74:9:74:22 | remote_string5 | test.rs:75:10:75:23 | remote_string5 | provenance | | -| test.rs:74:26:74:37 | ...::get | test.rs:74:26:74:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:15 | +| test.rs:74:26:74:37 | ...::get | test.rs:74:26:74:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:17 | | test.rs:74:26:74:52 | ...::get(...) [future, Ok] | test.rs:74:26:74:58 | await ... [Ok] | provenance | | | test.rs:74:26:74:58 | await ... [Ok] | test.rs:74:26:74:59 | TryExpr | provenance | | -| test.rs:74:26:74:59 | TryExpr | test.rs:74:26:74:66 | ... .text() [future, Ok] | provenance | MaD:88 | +| test.rs:74:26:74:59 | TryExpr | test.rs:74:26:74:66 | ... .text() [future, Ok] | provenance | MaD:90 | | test.rs:74:26:74:66 | ... .text() [future, Ok] | test.rs:74:26:74:72 | await ... [Ok] | provenance | | | test.rs:74:26:74:72 | await ... [Ok] | test.rs:74:26:74:73 | TryExpr | provenance | | | test.rs:74:26:74:73 | TryExpr | test.rs:74:9:74:22 | remote_string5 | provenance | | | test.rs:77:9:77:22 | remote_string6 | test.rs:78:10:78:23 | remote_string6 | provenance | | -| test.rs:77:26:77:37 | ...::get | test.rs:77:26:77:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:15 | +| test.rs:77:26:77:37 | ...::get | test.rs:77:26:77:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:17 | | test.rs:77:26:77:52 | ...::get(...) [future, Ok] | test.rs:77:26:77:58 | await ... [Ok] | provenance | | | test.rs:77:26:77:58 | await ... [Ok] | test.rs:77:26:77:59 | TryExpr | provenance | | -| test.rs:77:26:77:59 | TryExpr | test.rs:77:26:77:67 | ... .bytes() [future, Ok] | provenance | MaD:86 | +| test.rs:77:26:77:59 | TryExpr | test.rs:77:26:77:67 | ... .bytes() [future, Ok] | provenance | MaD:88 | | test.rs:77:26:77:67 | ... .bytes() [future, Ok] | test.rs:77:26:77:73 | await ... [Ok] | provenance | | | test.rs:77:26:77:73 | await ... [Ok] | test.rs:77:26:77:74 | TryExpr | provenance | | | test.rs:77:26:77:74 | TryExpr | test.rs:77:9:77:22 | remote_string6 | provenance | | -| test.rs:80:9:80:20 | mut request1 | test.rs:81:10:81:25 | request1.chunk() [future, Ok, Some] | provenance | MaD:87 | -| test.rs:80:9:80:20 | mut request1 | test.rs:82:29:82:44 | request1.chunk() [future, Ok, Some] | provenance | MaD:87 | -| test.rs:80:24:80:35 | ...::get | test.rs:80:24:80:50 | ...::get(...) [future, Ok] | provenance | Src:MaD:15 | +| test.rs:80:9:80:20 | mut request1 | test.rs:81:10:81:25 | request1.chunk() [future, Ok, Some] | provenance | MaD:89 | +| test.rs:80:9:80:20 | mut request1 | test.rs:82:29:82:44 | request1.chunk() [future, Ok, Some] | provenance | MaD:89 | +| test.rs:80:24:80:35 | ...::get | test.rs:80:24:80:50 | ...::get(...) [future, Ok] | provenance | Src:MaD:17 | | test.rs:80:24:80:50 | ...::get(...) [future, Ok] | test.rs:80:24:80:56 | await ... [Ok] | provenance | | | test.rs:80:24:80:56 | await ... [Ok] | test.rs:80:24:80:57 | TryExpr | provenance | | | test.rs:80:24:80:57 | TryExpr | test.rs:80:9:80:20 | mut request1 | provenance | | | test.rs:81:10:81:25 | request1.chunk() [future, Ok, Some] | test.rs:81:10:81:31 | await ... [Ok, Some] | provenance | | | test.rs:81:10:81:31 | await ... [Ok, Some] | test.rs:81:10:81:32 | TryExpr [Some] | provenance | | -| test.rs:81:10:81:32 | TryExpr [Some] | test.rs:81:10:81:41 | ... .unwrap() | provenance | MaD:75 | +| test.rs:81:10:81:32 | TryExpr [Some] | test.rs:81:10:81:41 | ... .unwrap() | provenance | MaD:77 | | test.rs:82:15:82:25 | Some(...) [Some] | test.rs:82:20:82:24 | chunk | provenance | | | test.rs:82:20:82:24 | chunk | test.rs:83:14:83:18 | chunk | provenance | | | test.rs:82:29:82:44 | request1.chunk() [future, Ok, Some] | test.rs:82:29:82:50 | await ... [Ok, Some] | provenance | | @@ -236,129 +238,129 @@ edges | test.rs:114:24:114:51 | sender.send_request(...) [future, Ok] | test.rs:114:24:114:57 | await ... [Ok] | provenance | | | test.rs:114:24:114:57 | await ... [Ok] | test.rs:114:24:114:58 | TryExpr | provenance | | | test.rs:114:24:114:58 | TryExpr | test.rs:114:13:114:20 | response | provenance | | -| test.rs:114:31:114:42 | send_request | test.rs:114:24:114:51 | sender.send_request(...) [future, Ok] | provenance | Src:MaD:2 | +| test.rs:114:31:114:42 | send_request | test.rs:114:24:114:51 | sender.send_request(...) [future, Ok] | provenance | Src:MaD:4 | | test.rs:115:15:115:22 | response | test.rs:115:14:115:22 | &response | provenance | | | test.rs:121:9:121:20 | mut response | test.rs:122:11:122:18 | response | provenance | | | test.rs:121:24:121:51 | sender.send_request(...) [future, Ok] | test.rs:121:24:121:57 | await ... [Ok] | provenance | | | test.rs:121:24:121:57 | await ... [Ok] | test.rs:121:24:121:58 | TryExpr | provenance | | | test.rs:121:24:121:58 | TryExpr | test.rs:121:9:121:20 | mut response | provenance | | -| test.rs:121:31:121:42 | send_request | test.rs:121:24:121:51 | sender.send_request(...) [future, Ok] | provenance | Src:MaD:2 | +| test.rs:121:31:121:42 | send_request | test.rs:121:24:121:51 | sender.send_request(...) [future, Ok] | provenance | Src:MaD:4 | | test.rs:122:11:122:18 | response | test.rs:122:10:122:18 | &response | provenance | | -| test.rs:211:22:211:35 | ...::stdin | test.rs:211:22:211:37 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer | provenance | MaD:103 | -| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:53 | -| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:102 | +| test.rs:211:22:211:35 | ...::stdin | test.rs:211:22:211:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer | provenance | MaD:105 | +| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:55 | +| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:104 | | test.rs:211:44:211:54 | [post] &mut buffer | test.rs:212:15:212:20 | buffer | provenance | | | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | test.rs:211:49:211:54 | [post] buffer | provenance | | | test.rs:211:49:211:54 | [post] buffer | test.rs:212:15:212:20 | buffer | provenance | | | test.rs:212:15:212:20 | buffer | test.rs:212:14:212:20 | &buffer | provenance | | -| test.rs:217:22:217:35 | ...::stdin | test.rs:217:22:217:37 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:55 | -| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:106 | +| test.rs:217:22:217:35 | ...::stdin | test.rs:217:22:217:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:57 | +| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:108 | | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | test.rs:217:56:217:61 | [post] buffer | provenance | | | test.rs:217:56:217:61 | [post] buffer | test.rs:218:15:218:20 | buffer | provenance | | | test.rs:218:15:218:20 | buffer | test.rs:218:14:218:20 | &buffer | provenance | | -| test.rs:223:22:223:35 | ...::stdin | test.rs:223:22:223:37 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer | provenance | MaD:108 | -| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:56 | -| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:107 | +| test.rs:223:22:223:35 | ...::stdin | test.rs:223:22:223:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer | provenance | MaD:110 | +| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:58 | +| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:109 | | test.rs:223:54:223:64 | [post] &mut buffer | test.rs:224:15:224:20 | buffer | provenance | | | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | test.rs:223:59:223:64 | [post] buffer | provenance | | | test.rs:223:59:223:64 | [post] buffer | test.rs:224:15:224:20 | buffer | provenance | | | test.rs:224:15:224:20 | buffer | test.rs:224:14:224:20 | &buffer | provenance | | -| test.rs:229:22:229:35 | ...::stdin | test.rs:229:22:229:37 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:229:22:229:37 | ...::stdin(...) | test.rs:229:22:229:44 | ... .lock() | provenance | MaD:109 | -| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:56 | -| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:110 | +| test.rs:229:22:229:35 | ...::stdin | test.rs:229:22:229:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:229:22:229:37 | ...::stdin(...) | test.rs:229:22:229:44 | ... .lock() | provenance | MaD:111 | +| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:58 | +| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:112 | | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | test.rs:229:66:229:71 | [post] buffer | provenance | | | test.rs:229:66:229:71 | [post] buffer | test.rs:230:15:230:20 | buffer | provenance | | | test.rs:230:15:230:20 | buffer | test.rs:230:14:230:20 | &buffer | provenance | | -| test.rs:235:9:235:22 | ...::stdin | test.rs:235:9:235:24 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer | provenance | MaD:105 | -| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:54 | -| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:104 | +| test.rs:235:9:235:22 | ...::stdin | test.rs:235:9:235:24 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer | provenance | MaD:107 | +| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:56 | +| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:106 | | test.rs:235:37:235:47 | [post] &mut buffer | test.rs:236:15:236:20 | buffer | provenance | | | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | test.rs:235:42:235:47 | [post] buffer | provenance | | | test.rs:235:42:235:47 | [post] buffer | test.rs:236:15:236:20 | buffer | provenance | | | test.rs:236:15:236:20 | buffer | test.rs:236:14:236:20 | &buffer | provenance | | -| test.rs:239:17:239:30 | ...::stdin | test.rs:239:17:239:32 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:239:17:239:32 | ...::stdin(...) | test.rs:239:17:239:40 | ... .bytes() | provenance | MaD:50 | +| test.rs:239:17:239:30 | ...::stdin | test.rs:239:17:239:32 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:239:17:239:32 | ...::stdin(...) | test.rs:239:17:239:40 | ... .bytes() | provenance | MaD:52 | | test.rs:239:17:239:40 | ... .bytes() | test.rs:240:14:240:17 | byte | provenance | | -| test.rs:246:13:246:22 | mut reader | test.rs:247:20:247:36 | reader.fill_buf() [Ok] | provenance | MaD:99 | +| test.rs:246:13:246:22 | mut reader | test.rs:247:20:247:36 | reader.fill_buf() [Ok] | provenance | MaD:101 | | test.rs:246:26:246:66 | ...::new(...) | test.rs:246:13:246:22 | mut reader | provenance | | -| test.rs:246:50:246:63 | ...::stdin | test.rs:246:50:246:65 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:246:50:246:65 | ...::stdin(...) | test.rs:246:26:246:66 | ...::new(...) | provenance | MaD:101 | +| test.rs:246:50:246:63 | ...::stdin | test.rs:246:50:246:65 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:246:50:246:65 | ...::stdin(...) | test.rs:246:26:246:66 | ...::new(...) | provenance | MaD:103 | | test.rs:247:13:247:16 | data | test.rs:248:15:248:18 | data | provenance | | | test.rs:247:20:247:36 | reader.fill_buf() [Ok] | test.rs:247:20:247:37 | TryExpr | provenance | | | test.rs:247:20:247:37 | TryExpr | test.rs:247:13:247:16 | data | provenance | | | test.rs:248:15:248:18 | data | test.rs:248:14:248:18 | &data | provenance | | -| test.rs:252:13:252:18 | reader | test.rs:253:20:253:34 | reader.buffer() | provenance | MaD:100 | +| test.rs:252:13:252:18 | reader | test.rs:253:20:253:34 | reader.buffer() | provenance | MaD:102 | | test.rs:252:22:252:62 | ...::new(...) | test.rs:252:13:252:18 | reader | provenance | | -| test.rs:252:46:252:59 | ...::stdin | test.rs:252:46:252:61 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:252:46:252:61 | ...::stdin(...) | test.rs:252:22:252:62 | ...::new(...) | provenance | MaD:101 | +| test.rs:252:46:252:59 | ...::stdin | test.rs:252:46:252:61 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:252:46:252:61 | ...::stdin(...) | test.rs:252:22:252:62 | ...::new(...) | provenance | MaD:103 | | test.rs:253:13:253:16 | data | test.rs:254:15:254:18 | data | provenance | | | test.rs:253:20:253:34 | reader.buffer() | test.rs:253:13:253:16 | data | provenance | | | test.rs:254:15:254:18 | data | test.rs:254:14:254:18 | &data | provenance | | -| test.rs:259:13:259:22 | mut reader | test.rs:260:26:260:36 | [post] &mut buffer [&ref] | provenance | MaD:47 | +| test.rs:259:13:259:22 | mut reader | test.rs:260:26:260:36 | [post] &mut buffer [&ref] | provenance | MaD:49 | | test.rs:259:26:259:66 | ...::new(...) | test.rs:259:13:259:22 | mut reader | provenance | | -| test.rs:259:50:259:63 | ...::stdin | test.rs:259:50:259:65 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:259:50:259:65 | ...::stdin(...) | test.rs:259:26:259:66 | ...::new(...) | provenance | MaD:101 | +| test.rs:259:50:259:63 | ...::stdin | test.rs:259:50:259:65 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:259:50:259:65 | ...::stdin(...) | test.rs:259:26:259:66 | ...::new(...) | provenance | MaD:103 | | test.rs:260:26:260:36 | [post] &mut buffer [&ref] | test.rs:260:31:260:36 | [post] buffer | provenance | | | test.rs:260:31:260:36 | [post] buffer | test.rs:261:15:261:20 | buffer | provenance | | | test.rs:261:15:261:20 | buffer | test.rs:261:14:261:20 | &buffer | provenance | | -| test.rs:266:13:266:22 | mut reader | test.rs:267:33:267:43 | [post] &mut buffer [&ref] | provenance | MaD:48 | +| test.rs:266:13:266:22 | mut reader | test.rs:267:33:267:43 | [post] &mut buffer [&ref] | provenance | MaD:50 | | test.rs:266:26:266:66 | ...::new(...) | test.rs:266:13:266:22 | mut reader | provenance | | -| test.rs:266:50:266:63 | ...::stdin | test.rs:266:50:266:65 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:266:50:266:65 | ...::stdin(...) | test.rs:266:26:266:66 | ...::new(...) | provenance | MaD:101 | +| test.rs:266:50:266:63 | ...::stdin | test.rs:266:50:266:65 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:266:50:266:65 | ...::stdin(...) | test.rs:266:26:266:66 | ...::new(...) | provenance | MaD:103 | | test.rs:267:33:267:43 | [post] &mut buffer [&ref] | test.rs:267:38:267:43 | [post] buffer | provenance | | | test.rs:267:38:267:43 | [post] buffer | test.rs:268:15:268:20 | buffer | provenance | | | test.rs:267:38:267:43 | [post] buffer | test.rs:269:14:269:22 | buffer[0] | provenance | | | test.rs:268:15:268:20 | buffer | test.rs:268:14:268:20 | &buffer | provenance | | -| test.rs:273:13:273:28 | mut reader_split | test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | provenance | MaD:98 | -| test.rs:273:13:273:28 | mut reader_split | test.rs:275:33:275:51 | reader_split.next() [Some, Ok] | provenance | MaD:98 | -| test.rs:273:32:273:72 | ...::new(...) | test.rs:273:32:273:84 | ... .split(...) | provenance | MaD:49 | +| test.rs:273:13:273:28 | mut reader_split | test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | provenance | MaD:100 | +| test.rs:273:13:273:28 | mut reader_split | test.rs:275:33:275:51 | reader_split.next() [Some, Ok] | provenance | MaD:100 | +| test.rs:273:32:273:72 | ...::new(...) | test.rs:273:32:273:84 | ... .split(...) | provenance | MaD:51 | | test.rs:273:32:273:84 | ... .split(...) | test.rs:273:13:273:28 | mut reader_split | provenance | | -| test.rs:273:56:273:69 | ...::stdin | test.rs:273:56:273:71 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:273:56:273:71 | ...::stdin(...) | test.rs:273:32:273:72 | ...::new(...) | provenance | MaD:101 | -| test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | test.rs:274:14:274:41 | ... .unwrap() [Ok] | provenance | MaD:75 | -| test.rs:274:14:274:41 | ... .unwrap() [Ok] | test.rs:274:14:274:50 | ... .unwrap() | provenance | MaD:80 | +| test.rs:273:56:273:69 | ...::stdin | test.rs:273:56:273:71 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:273:56:273:71 | ...::stdin(...) | test.rs:273:32:273:72 | ...::new(...) | provenance | MaD:103 | +| test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | test.rs:274:14:274:41 | ... .unwrap() [Ok] | provenance | MaD:77 | +| test.rs:274:14:274:41 | ... .unwrap() [Ok] | test.rs:274:14:274:50 | ... .unwrap() | provenance | MaD:82 | | test.rs:275:19:275:29 | Some(...) [Some, Ok] | test.rs:275:24:275:28 | chunk [Ok] | provenance | | -| test.rs:275:24:275:28 | chunk [Ok] | test.rs:276:18:276:31 | chunk.unwrap() | provenance | MaD:80 | +| test.rs:275:24:275:28 | chunk [Ok] | test.rs:276:18:276:31 | chunk.unwrap() | provenance | MaD:82 | | test.rs:275:33:275:51 | reader_split.next() [Some, Ok] | test.rs:275:19:275:29 | Some(...) [Some, Ok] | provenance | | -| test.rs:281:13:281:18 | reader | test.rs:282:21:282:34 | reader.lines() | provenance | MaD:46 | +| test.rs:281:13:281:18 | reader | test.rs:282:21:282:34 | reader.lines() | provenance | MaD:48 | | test.rs:281:22:281:62 | ...::new(...) | test.rs:281:13:281:18 | reader | provenance | | -| test.rs:281:46:281:59 | ...::stdin | test.rs:281:46:281:61 | ...::stdin(...) | provenance | Src:MaD:28 MaD:28 | -| test.rs:281:46:281:61 | ...::stdin(...) | test.rs:281:22:281:62 | ...::new(...) | provenance | MaD:101 | +| test.rs:281:46:281:59 | ...::stdin | test.rs:281:46:281:61 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | +| test.rs:281:46:281:61 | ...::stdin(...) | test.rs:281:22:281:62 | ...::new(...) | provenance | MaD:103 | | test.rs:282:21:282:34 | reader.lines() | test.rs:283:18:283:21 | line | provenance | | -| test.rs:309:13:309:21 | mut stdin | test.rs:311:33:311:43 | [post] &mut buffer [&ref] | provenance | MaD:63 | -| test.rs:309:25:309:40 | ...::stdin | test.rs:309:25:309:42 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | +| test.rs:309:13:309:21 | mut stdin | test.rs:311:33:311:43 | [post] &mut buffer [&ref] | provenance | MaD:65 | +| test.rs:309:25:309:40 | ...::stdin | test.rs:309:25:309:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:309:25:309:42 | ...::stdin(...) | test.rs:309:13:309:21 | mut stdin | provenance | | | test.rs:311:33:311:43 | [post] &mut buffer [&ref] | test.rs:311:38:311:43 | [post] buffer | provenance | | | test.rs:311:38:311:43 | [post] buffer | test.rs:312:15:312:20 | buffer | provenance | | | test.rs:312:15:312:20 | buffer | test.rs:312:14:312:20 | &buffer | provenance | | -| test.rs:316:13:316:21 | mut stdin | test.rs:318:40:318:50 | [post] &mut buffer [&ref] | provenance | MaD:69 | -| test.rs:316:25:316:40 | ...::stdin | test.rs:316:25:316:42 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | +| test.rs:316:13:316:21 | mut stdin | test.rs:318:40:318:50 | [post] &mut buffer [&ref] | provenance | MaD:71 | +| test.rs:316:25:316:40 | ...::stdin | test.rs:316:25:316:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:316:25:316:42 | ...::stdin(...) | test.rs:316:13:316:21 | mut stdin | provenance | | | test.rs:318:40:318:50 | [post] &mut buffer [&ref] | test.rs:318:45:318:50 | [post] buffer | provenance | | | test.rs:318:45:318:50 | [post] buffer | test.rs:319:15:319:20 | buffer | provenance | | | test.rs:319:15:319:20 | buffer | test.rs:319:14:319:20 | &buffer | provenance | | -| test.rs:323:13:323:21 | mut stdin | test.rs:325:43:325:53 | [post] &mut buffer [&ref] | provenance | MaD:70 | -| test.rs:323:25:323:40 | ...::stdin | test.rs:323:25:323:42 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | +| test.rs:323:13:323:21 | mut stdin | test.rs:325:43:325:53 | [post] &mut buffer [&ref] | provenance | MaD:72 | +| test.rs:323:25:323:40 | ...::stdin | test.rs:323:25:323:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:323:25:323:42 | ...::stdin(...) | test.rs:323:13:323:21 | mut stdin | provenance | | | test.rs:325:43:325:53 | [post] &mut buffer [&ref] | test.rs:325:48:325:53 | [post] buffer | provenance | | | test.rs:325:48:325:53 | [post] buffer | test.rs:326:15:326:20 | buffer | provenance | | | test.rs:326:15:326:20 | buffer | test.rs:326:14:326:20 | &buffer | provenance | | -| test.rs:330:13:330:21 | mut stdin | test.rs:332:26:332:36 | [post] &mut buffer [&ref] | provenance | MaD:65 | -| test.rs:330:25:330:40 | ...::stdin | test.rs:330:25:330:42 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | +| test.rs:330:13:330:21 | mut stdin | test.rs:332:26:332:36 | [post] &mut buffer [&ref] | provenance | MaD:67 | +| test.rs:330:25:330:40 | ...::stdin | test.rs:330:25:330:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:330:25:330:42 | ...::stdin(...) | test.rs:330:13:330:21 | mut stdin | provenance | | | test.rs:332:26:332:36 | [post] &mut buffer [&ref] | test.rs:332:31:332:36 | [post] buffer | provenance | | | test.rs:332:31:332:36 | [post] buffer | test.rs:333:15:333:20 | buffer | provenance | | | test.rs:333:15:333:20 | buffer | test.rs:333:14:333:20 | &buffer | provenance | | -| test.rs:337:13:337:21 | mut stdin | test.rs:338:18:338:32 | stdin.read_u8() [future, Ok] | provenance | MaD:71 | -| test.rs:337:13:337:21 | mut stdin | test.rs:339:18:339:33 | stdin.read_i16() [future, Ok] | provenance | MaD:67 | -| test.rs:337:13:337:21 | mut stdin | test.rs:340:18:340:33 | stdin.read_f32() [future, Ok] | provenance | MaD:66 | -| test.rs:337:13:337:21 | mut stdin | test.rs:341:18:341:36 | stdin.read_i64_le() [future, Ok] | provenance | MaD:68 | -| test.rs:337:25:337:40 | ...::stdin | test.rs:337:25:337:42 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | +| test.rs:337:13:337:21 | mut stdin | test.rs:338:18:338:32 | stdin.read_u8() [future, Ok] | provenance | MaD:73 | +| test.rs:337:13:337:21 | mut stdin | test.rs:339:18:339:33 | stdin.read_i16() [future, Ok] | provenance | MaD:69 | +| test.rs:337:13:337:21 | mut stdin | test.rs:340:18:340:33 | stdin.read_f32() [future, Ok] | provenance | MaD:68 | +| test.rs:337:13:337:21 | mut stdin | test.rs:341:18:341:36 | stdin.read_i64_le() [future, Ok] | provenance | MaD:70 | +| test.rs:337:25:337:40 | ...::stdin | test.rs:337:25:337:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:337:25:337:42 | ...::stdin(...) | test.rs:337:13:337:21 | mut stdin | provenance | | | test.rs:338:13:338:14 | v1 | test.rs:342:14:342:15 | v1 | provenance | | | test.rs:338:18:338:32 | stdin.read_u8() [future, Ok] | test.rs:338:18:338:38 | await ... [Ok] | provenance | | @@ -376,150 +378,150 @@ edges | test.rs:341:18:341:36 | stdin.read_i64_le() [future, Ok] | test.rs:341:18:341:42 | await ... [Ok] | provenance | | | test.rs:341:18:341:42 | await ... [Ok] | test.rs:341:18:341:43 | TryExpr | provenance | | | test.rs:341:18:341:43 | TryExpr | test.rs:341:13:341:14 | v4 | provenance | | -| test.rs:349:13:349:21 | mut stdin | test.rs:351:24:351:34 | [post] &mut buffer [&ref] | provenance | MaD:64 | -| test.rs:349:25:349:40 | ...::stdin | test.rs:349:25:349:42 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | +| test.rs:349:13:349:21 | mut stdin | test.rs:351:24:351:34 | [post] &mut buffer [&ref] | provenance | MaD:66 | +| test.rs:349:25:349:40 | ...::stdin | test.rs:349:25:349:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:349:25:349:42 | ...::stdin(...) | test.rs:349:13:349:21 | mut stdin | provenance | | | test.rs:351:24:351:34 | [post] &mut buffer [&ref] | test.rs:351:29:351:34 | [post] buffer | provenance | | | test.rs:351:29:351:34 | [post] buffer | test.rs:352:15:352:20 | buffer | provenance | | | test.rs:352:15:352:20 | buffer | test.rs:352:14:352:20 | &buffer | provenance | | -| test.rs:358:13:358:22 | mut reader | test.rs:359:20:359:36 | reader.fill_buf() [future, Ok] | provenance | MaD:58 | +| test.rs:358:13:358:22 | mut reader | test.rs:359:20:359:36 | reader.fill_buf() [future, Ok] | provenance | MaD:60 | | test.rs:358:26:358:70 | ...::new(...) | test.rs:358:13:358:22 | mut reader | provenance | | -| test.rs:358:52:358:67 | ...::stdin | test.rs:358:52:358:69 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | -| test.rs:358:52:358:69 | ...::stdin(...) | test.rs:358:26:358:70 | ...::new(...) | provenance | MaD:114 | +| test.rs:358:52:358:67 | ...::stdin | test.rs:358:52:358:69 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:358:52:358:69 | ...::stdin(...) | test.rs:358:26:358:70 | ...::new(...) | provenance | MaD:116 | | test.rs:359:13:359:16 | data | test.rs:360:15:360:18 | data | provenance | | | test.rs:359:20:359:36 | reader.fill_buf() [future, Ok] | test.rs:359:20:359:42 | await ... [Ok] | provenance | | | test.rs:359:20:359:42 | await ... [Ok] | test.rs:359:20:359:43 | TryExpr | provenance | | | test.rs:359:20:359:43 | TryExpr | test.rs:359:13:359:16 | data | provenance | | | test.rs:360:15:360:18 | data | test.rs:360:14:360:18 | &data | provenance | | -| test.rs:364:13:364:18 | reader | test.rs:365:20:365:34 | reader.buffer() | provenance | MaD:113 | +| test.rs:364:13:364:18 | reader | test.rs:365:20:365:34 | reader.buffer() | provenance | MaD:115 | | test.rs:364:22:364:66 | ...::new(...) | test.rs:364:13:364:18 | reader | provenance | | -| test.rs:364:48:364:63 | ...::stdin | test.rs:364:48:364:65 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | -| test.rs:364:48:364:65 | ...::stdin(...) | test.rs:364:22:364:66 | ...::new(...) | provenance | MaD:114 | +| test.rs:364:48:364:63 | ...::stdin | test.rs:364:48:364:65 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:364:48:364:65 | ...::stdin(...) | test.rs:364:22:364:66 | ...::new(...) | provenance | MaD:116 | | test.rs:365:13:365:16 | data | test.rs:366:15:366:18 | data | provenance | | | test.rs:365:20:365:34 | reader.buffer() | test.rs:365:13:365:16 | data | provenance | | | test.rs:366:15:366:18 | data | test.rs:366:14:366:18 | &data | provenance | | -| test.rs:371:13:371:22 | mut reader | test.rs:372:26:372:36 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:371:13:371:22 | mut reader | test.rs:372:26:372:36 | [post] &mut buffer [&ref] | provenance | MaD:62 | | test.rs:371:26:371:70 | ...::new(...) | test.rs:371:13:371:22 | mut reader | provenance | | -| test.rs:371:52:371:67 | ...::stdin | test.rs:371:52:371:69 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | -| test.rs:371:52:371:69 | ...::stdin(...) | test.rs:371:26:371:70 | ...::new(...) | provenance | MaD:114 | +| test.rs:371:52:371:67 | ...::stdin | test.rs:371:52:371:69 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:371:52:371:69 | ...::stdin(...) | test.rs:371:26:371:70 | ...::new(...) | provenance | MaD:116 | | test.rs:372:26:372:36 | [post] &mut buffer [&ref] | test.rs:372:31:372:36 | [post] buffer | provenance | | | test.rs:372:31:372:36 | [post] buffer | test.rs:373:15:373:20 | buffer | provenance | | | test.rs:373:15:373:20 | buffer | test.rs:373:14:373:20 | &buffer | provenance | | -| test.rs:378:13:378:22 | mut reader | test.rs:379:33:379:43 | [post] &mut buffer [&ref] | provenance | MaD:61 | +| test.rs:378:13:378:22 | mut reader | test.rs:379:33:379:43 | [post] &mut buffer [&ref] | provenance | MaD:63 | | test.rs:378:26:378:70 | ...::new(...) | test.rs:378:13:378:22 | mut reader | provenance | | -| test.rs:378:52:378:67 | ...::stdin | test.rs:378:52:378:69 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | -| test.rs:378:52:378:69 | ...::stdin(...) | test.rs:378:26:378:70 | ...::new(...) | provenance | MaD:114 | +| test.rs:378:52:378:67 | ...::stdin | test.rs:378:52:378:69 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:378:52:378:69 | ...::stdin(...) | test.rs:378:26:378:70 | ...::new(...) | provenance | MaD:116 | | test.rs:379:33:379:43 | [post] &mut buffer [&ref] | test.rs:379:38:379:43 | [post] buffer | provenance | | | test.rs:379:38:379:43 | [post] buffer | test.rs:380:15:380:20 | buffer | provenance | | | test.rs:379:38:379:43 | [post] buffer | test.rs:381:14:381:22 | buffer[0] | provenance | | | test.rs:380:15:380:20 | buffer | test.rs:380:14:380:20 | &buffer | provenance | | -| test.rs:385:13:385:28 | mut reader_split | test.rs:386:14:386:40 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:116 | -| test.rs:385:13:385:28 | mut reader_split | test.rs:387:33:387:59 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:116 | -| test.rs:385:32:385:76 | ...::new(...) | test.rs:385:32:385:88 | ... .split(...) | provenance | MaD:62 | +| test.rs:385:13:385:28 | mut reader_split | test.rs:386:14:386:40 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:118 | +| test.rs:385:13:385:28 | mut reader_split | test.rs:387:33:387:59 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:118 | +| test.rs:385:32:385:76 | ...::new(...) | test.rs:385:32:385:88 | ... .split(...) | provenance | MaD:64 | | test.rs:385:32:385:88 | ... .split(...) | test.rs:385:13:385:28 | mut reader_split | provenance | | -| test.rs:385:58:385:73 | ...::stdin | test.rs:385:58:385:75 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | -| test.rs:385:58:385:75 | ...::stdin(...) | test.rs:385:32:385:76 | ...::new(...) | provenance | MaD:114 | +| test.rs:385:58:385:73 | ...::stdin | test.rs:385:58:385:75 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:385:58:385:75 | ...::stdin(...) | test.rs:385:32:385:76 | ...::new(...) | provenance | MaD:116 | | test.rs:386:14:386:40 | reader_split.next_segment() [future, Ok, Some] | test.rs:386:14:386:46 | await ... [Ok, Some] | provenance | | | test.rs:386:14:386:46 | await ... [Ok, Some] | test.rs:386:14:386:47 | TryExpr [Some] | provenance | | -| test.rs:386:14:386:47 | TryExpr [Some] | test.rs:386:14:386:56 | ... .unwrap() | provenance | MaD:75 | +| test.rs:386:14:386:47 | TryExpr [Some] | test.rs:386:14:386:56 | ... .unwrap() | provenance | MaD:77 | | test.rs:387:19:387:29 | Some(...) [Some] | test.rs:387:24:387:28 | chunk | provenance | | | test.rs:387:24:387:28 | chunk | test.rs:388:18:388:22 | chunk | provenance | | | test.rs:387:33:387:59 | reader_split.next_segment() [future, Ok, Some] | test.rs:387:33:387:65 | await ... [Ok, Some] | provenance | | | test.rs:387:33:387:65 | await ... [Ok, Some] | test.rs:387:33:387:66 | TryExpr [Some] | provenance | | | test.rs:387:33:387:66 | TryExpr [Some] | test.rs:387:19:387:29 | Some(...) [Some] | provenance | | -| test.rs:393:13:393:18 | reader | test.rs:394:25:394:38 | reader.lines() | provenance | MaD:59 | +| test.rs:393:13:393:18 | reader | test.rs:394:25:394:38 | reader.lines() | provenance | MaD:61 | | test.rs:393:22:393:66 | ...::new(...) | test.rs:393:13:393:18 | reader | provenance | | -| test.rs:393:48:393:63 | ...::stdin | test.rs:393:48:393:65 | ...::stdin(...) | provenance | Src:MaD:32 MaD:32 | -| test.rs:393:48:393:65 | ...::stdin(...) | test.rs:393:22:393:66 | ...::new(...) | provenance | MaD:114 | -| test.rs:394:13:394:21 | mut lines | test.rs:395:14:395:30 | lines.next_line() [future, Ok, Some] | provenance | MaD:115 | -| test.rs:394:13:394:21 | mut lines | test.rs:396:32:396:48 | lines.next_line() [future, Ok, Some] | provenance | MaD:115 | +| test.rs:393:48:393:63 | ...::stdin | test.rs:393:48:393:65 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:393:48:393:65 | ...::stdin(...) | test.rs:393:22:393:66 | ...::new(...) | provenance | MaD:116 | +| test.rs:394:13:394:21 | mut lines | test.rs:395:14:395:30 | lines.next_line() [future, Ok, Some] | provenance | MaD:117 | +| test.rs:394:13:394:21 | mut lines | test.rs:396:32:396:48 | lines.next_line() [future, Ok, Some] | provenance | MaD:117 | | test.rs:394:25:394:38 | reader.lines() | test.rs:394:13:394:21 | mut lines | provenance | | | test.rs:395:14:395:30 | lines.next_line() [future, Ok, Some] | test.rs:395:14:395:36 | await ... [Ok, Some] | provenance | | | test.rs:395:14:395:36 | await ... [Ok, Some] | test.rs:395:14:395:37 | TryExpr [Some] | provenance | | -| test.rs:395:14:395:37 | TryExpr [Some] | test.rs:395:14:395:46 | ... .unwrap() | provenance | MaD:75 | +| test.rs:395:14:395:37 | TryExpr [Some] | test.rs:395:14:395:46 | ... .unwrap() | provenance | MaD:77 | | test.rs:396:19:396:28 | Some(...) [Some] | test.rs:396:24:396:27 | line | provenance | | | test.rs:396:24:396:27 | line | test.rs:397:18:397:21 | line | provenance | | | test.rs:396:32:396:48 | lines.next_line() [future, Ok, Some] | test.rs:396:32:396:54 | await ... [Ok, Some] | provenance | | | test.rs:396:32:396:54 | await ... [Ok, Some] | test.rs:396:32:396:55 | TryExpr [Some] | provenance | | | test.rs:396:32:396:55 | TryExpr [Some] | test.rs:396:19:396:28 | Some(...) [Some] | provenance | | | test.rs:408:13:408:18 | buffer | test.rs:409:14:409:19 | buffer | provenance | | -| test.rs:408:31:408:43 | ...::read | test.rs:408:31:408:43 | ...::read [Ok] | provenance | Src:MaD:23 | -| test.rs:408:31:408:43 | ...::read | test.rs:408:31:408:55 | ...::read(...) [Ok] | provenance | Src:MaD:23 | -| test.rs:408:31:408:43 | ...::read [Ok] | test.rs:408:31:408:55 | ...::read(...) [Ok] | provenance | MaD:24 | +| test.rs:408:31:408:43 | ...::read | test.rs:408:31:408:43 | ...::read [Ok] | provenance | Src:MaD:25 | +| test.rs:408:31:408:43 | ...::read | test.rs:408:31:408:55 | ...::read(...) [Ok] | provenance | Src:MaD:25 | +| test.rs:408:31:408:43 | ...::read [Ok] | test.rs:408:31:408:55 | ...::read(...) [Ok] | provenance | MaD:26 | | test.rs:408:31:408:55 | ...::read(...) [Ok] | test.rs:408:31:408:56 | TryExpr | provenance | | | test.rs:408:31:408:56 | TryExpr | test.rs:408:13:408:18 | buffer | provenance | | | test.rs:413:13:413:18 | buffer | test.rs:414:14:414:19 | buffer | provenance | | -| test.rs:413:31:413:38 | ...::read | test.rs:413:31:413:38 | ...::read [Ok] | provenance | Src:MaD:23 | -| test.rs:413:31:413:38 | ...::read | test.rs:413:31:413:50 | ...::read(...) [Ok] | provenance | Src:MaD:23 | -| test.rs:413:31:413:38 | ...::read [Ok] | test.rs:413:31:413:50 | ...::read(...) [Ok] | provenance | MaD:24 | +| test.rs:413:31:413:38 | ...::read | test.rs:413:31:413:38 | ...::read [Ok] | provenance | Src:MaD:25 | +| test.rs:413:31:413:38 | ...::read | test.rs:413:31:413:50 | ...::read(...) [Ok] | provenance | Src:MaD:25 | +| test.rs:413:31:413:38 | ...::read [Ok] | test.rs:413:31:413:50 | ...::read(...) [Ok] | provenance | MaD:26 | | test.rs:413:31:413:50 | ...::read(...) [Ok] | test.rs:413:31:413:51 | TryExpr | provenance | | | test.rs:413:31:413:51 | TryExpr | test.rs:413:13:413:18 | buffer | provenance | | | test.rs:418:13:418:18 | buffer | test.rs:419:14:419:19 | buffer | provenance | | -| test.rs:418:22:418:39 | ...::read_to_string | test.rs:418:22:418:39 | ...::read_to_string [Ok] | provenance | Src:MaD:26 | -| test.rs:418:22:418:39 | ...::read_to_string | test.rs:418:22:418:51 | ...::read_to_string(...) [Ok] | provenance | Src:MaD:26 | -| test.rs:418:22:418:39 | ...::read_to_string [Ok] | test.rs:418:22:418:51 | ...::read_to_string(...) [Ok] | provenance | MaD:27 | +| test.rs:418:22:418:39 | ...::read_to_string | test.rs:418:22:418:39 | ...::read_to_string [Ok] | provenance | Src:MaD:28 | +| test.rs:418:22:418:39 | ...::read_to_string | test.rs:418:22:418:51 | ...::read_to_string(...) [Ok] | provenance | Src:MaD:28 | +| test.rs:418:22:418:39 | ...::read_to_string [Ok] | test.rs:418:22:418:51 | ...::read_to_string(...) [Ok] | provenance | MaD:29 | | test.rs:418:22:418:51 | ...::read_to_string(...) [Ok] | test.rs:418:22:418:52 | TryExpr | provenance | | | test.rs:418:22:418:52 | TryExpr | test.rs:418:13:418:18 | buffer | provenance | | | test.rs:425:13:425:16 | path | test.rs:426:14:426:17 | path | provenance | | -| test.rs:425:13:425:16 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:33 | +| test.rs:425:13:425:16 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:35 | | test.rs:425:13:425:16 | path | test.rs:427:14:427:17 | path | provenance | | -| test.rs:425:13:425:16 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:33 | +| test.rs:425:13:425:16 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:35 | | test.rs:425:13:425:16 | path | test.rs:437:14:437:17 | path | provenance | | | test.rs:425:20:425:27 | e.path() | test.rs:425:13:425:16 | path | provenance | | -| test.rs:425:22:425:25 | path | test.rs:425:20:425:27 | e.path() | provenance | Src:MaD:4 MaD:4 | -| test.rs:426:14:426:17 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:33 | -| test.rs:427:14:427:17 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:33 | -| test.rs:427:14:427:25 | path.clone() | test.rs:427:14:427:35 | ... .as_path() | provenance | MaD:112 | +| test.rs:425:22:425:25 | path | test.rs:425:20:425:27 | e.path() | provenance | Src:MaD:6 MaD:6 | +| test.rs:426:14:426:17 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:35 | +| test.rs:427:14:427:17 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:35 | +| test.rs:427:14:427:25 | path.clone() | test.rs:427:14:427:35 | ... .as_path() | provenance | MaD:114 | | test.rs:439:13:439:21 | file_name | test.rs:440:14:440:22 | file_name | provenance | | -| test.rs:439:13:439:21 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:33 | +| test.rs:439:13:439:21 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:35 | | test.rs:439:13:439:21 | file_name | test.rs:445:14:445:22 | file_name | provenance | | | test.rs:439:25:439:37 | e.file_name() | test.rs:439:13:439:21 | file_name | provenance | | -| test.rs:439:27:439:35 | file_name | test.rs:439:25:439:37 | e.file_name() | provenance | Src:MaD:3 MaD:3 | -| test.rs:440:14:440:22 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:33 | +| test.rs:439:27:439:35 | file_name | test.rs:439:25:439:37 | e.file_name() | provenance | Src:MaD:5 MaD:5 | +| test.rs:440:14:440:22 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:35 | | test.rs:461:13:461:18 | target | test.rs:462:14:462:19 | target | provenance | | -| test.rs:461:22:461:34 | ...::read_link | test.rs:461:22:461:49 | ...::read_link(...) [Ok] | provenance | Src:MaD:25 | +| test.rs:461:22:461:34 | ...::read_link | test.rs:461:22:461:49 | ...::read_link(...) [Ok] | provenance | Src:MaD:27 | | test.rs:461:22:461:49 | ...::read_link(...) [Ok] | test.rs:461:22:461:50 | TryExpr | provenance | | | test.rs:461:22:461:50 | TryExpr | test.rs:461:13:461:18 | target | provenance | | | test.rs:470:13:470:18 | buffer | test.rs:471:14:471:19 | buffer | provenance | | -| test.rs:470:31:470:45 | ...::read | test.rs:470:31:470:57 | ...::read(...) [future, Ok] | provenance | Src:MaD:29 | +| test.rs:470:31:470:45 | ...::read | test.rs:470:31:470:57 | ...::read(...) [future, Ok] | provenance | Src:MaD:31 | | test.rs:470:31:470:57 | ...::read(...) [future, Ok] | test.rs:470:31:470:63 | await ... [Ok] | provenance | | | test.rs:470:31:470:63 | await ... [Ok] | test.rs:470:31:470:64 | TryExpr | provenance | | | test.rs:470:31:470:64 | TryExpr | test.rs:470:13:470:18 | buffer | provenance | | | test.rs:475:13:475:18 | buffer | test.rs:476:14:476:19 | buffer | provenance | | -| test.rs:475:31:475:45 | ...::read | test.rs:475:31:475:57 | ...::read(...) [future, Ok] | provenance | Src:MaD:29 | +| test.rs:475:31:475:45 | ...::read | test.rs:475:31:475:57 | ...::read(...) [future, Ok] | provenance | Src:MaD:31 | | test.rs:475:31:475:57 | ...::read(...) [future, Ok] | test.rs:475:31:475:63 | await ... [Ok] | provenance | | | test.rs:475:31:475:63 | await ... [Ok] | test.rs:475:31:475:64 | TryExpr | provenance | | | test.rs:475:31:475:64 | TryExpr | test.rs:475:13:475:18 | buffer | provenance | | | test.rs:480:13:480:18 | buffer | test.rs:481:14:481:19 | buffer | provenance | | -| test.rs:480:22:480:46 | ...::read_to_string | test.rs:480:22:480:58 | ...::read_to_string(...) [future, Ok] | provenance | Src:MaD:31 | +| test.rs:480:22:480:46 | ...::read_to_string | test.rs:480:22:480:58 | ...::read_to_string(...) [future, Ok] | provenance | Src:MaD:33 | | test.rs:480:22:480:58 | ...::read_to_string(...) [future, Ok] | test.rs:480:22:480:64 | await ... [Ok] | provenance | | | test.rs:480:22:480:64 | await ... [Ok] | test.rs:480:22:480:65 | TryExpr | provenance | | | test.rs:480:22:480:65 | TryExpr | test.rs:480:13:480:18 | buffer | provenance | | | test.rs:486:13:486:16 | path | test.rs:488:14:488:17 | path | provenance | | | test.rs:486:20:486:31 | entry.path() | test.rs:486:13:486:16 | path | provenance | | -| test.rs:486:26:486:29 | path | test.rs:486:20:486:31 | entry.path() | provenance | Src:MaD:12 MaD:12 | -| test.rs:486:26:486:29 | path | test.rs:486:20:486:31 | entry.path() | provenance | Src:MaD:12 MaD:12 | +| test.rs:486:26:486:29 | path | test.rs:486:20:486:31 | entry.path() | provenance | Src:MaD:14 MaD:14 | +| test.rs:486:26:486:29 | path | test.rs:486:20:486:31 | entry.path() | provenance | Src:MaD:14 MaD:14 | | test.rs:487:13:487:21 | file_name | test.rs:489:14:489:22 | file_name | provenance | | | test.rs:487:25:487:41 | entry.file_name() | test.rs:487:13:487:21 | file_name | provenance | | -| test.rs:487:31:487:39 | file_name | test.rs:487:25:487:41 | entry.file_name() | provenance | Src:MaD:11 MaD:11 | -| test.rs:487:31:487:39 | file_name | test.rs:487:25:487:41 | entry.file_name() | provenance | Src:MaD:11 MaD:11 | +| test.rs:487:31:487:39 | file_name | test.rs:487:25:487:41 | entry.file_name() | provenance | Src:MaD:13 MaD:13 | +| test.rs:487:31:487:39 | file_name | test.rs:487:25:487:41 | entry.file_name() | provenance | Src:MaD:13 MaD:13 | | test.rs:493:13:493:18 | target | test.rs:494:14:494:19 | target | provenance | | -| test.rs:493:22:493:41 | ...::read_link | test.rs:493:22:493:56 | ...::read_link(...) [future, Ok] | provenance | Src:MaD:30 | +| test.rs:493:22:493:41 | ...::read_link | test.rs:493:22:493:56 | ...::read_link(...) [future, Ok] | provenance | Src:MaD:32 | | test.rs:493:22:493:56 | ...::read_link(...) [future, Ok] | test.rs:493:22:493:62 | await ... [Ok] | provenance | | | test.rs:493:22:493:62 | await ... [Ok] | test.rs:493:22:493:63 | TryExpr | provenance | | | test.rs:493:22:493:63 | TryExpr | test.rs:493:13:493:18 | target | provenance | | -| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer | provenance | MaD:93 | -| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:53 | -| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:92 | -| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer | provenance | MaD:95 | -| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:55 | -| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:94 | -| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer | provenance | MaD:97 | -| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:56 | -| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:96 | -| test.rs:503:9:503:16 | mut file | test.rs:525:25:525:35 | [post] &mut buffer [&ref] | provenance | MaD:54 | -| test.rs:503:9:503:16 | mut file | test.rs:529:17:529:28 | file.bytes() | provenance | MaD:50 | -| test.rs:503:20:503:38 | ...::open | test.rs:503:20:503:50 | ...::open(...) [Ok] | provenance | Src:MaD:5 | +| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer | provenance | MaD:95 | +| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:55 | +| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:94 | +| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer | provenance | MaD:97 | +| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:57 | +| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:96 | +| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer | provenance | MaD:99 | +| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:58 | +| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:98 | +| test.rs:503:9:503:16 | mut file | test.rs:525:25:525:35 | [post] &mut buffer [&ref] | provenance | MaD:56 | +| test.rs:503:9:503:16 | mut file | test.rs:529:17:529:28 | file.bytes() | provenance | MaD:52 | +| test.rs:503:20:503:38 | ...::open | test.rs:503:20:503:50 | ...::open(...) [Ok] | provenance | Src:MaD:7 | | test.rs:503:20:503:50 | ...::open(...) [Ok] | test.rs:503:20:503:51 | TryExpr | provenance | | | test.rs:503:20:503:51 | TryExpr | test.rs:503:9:503:16 | mut file | provenance | | | test.rs:507:32:507:42 | [post] &mut buffer | test.rs:508:15:508:20 | buffer | provenance | | @@ -538,69 +540,69 @@ edges | test.rs:525:30:525:35 | [post] buffer | test.rs:526:15:526:20 | buffer | provenance | | | test.rs:526:15:526:20 | buffer | test.rs:526:14:526:20 | &buffer | provenance | | | test.rs:529:17:529:28 | file.bytes() | test.rs:530:14:530:17 | byte | provenance | | -| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer | provenance | MaD:93 | -| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:53 | -| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:92 | -| test.rs:536:22:536:63 | ... .open(...) [Ok] | test.rs:536:22:536:72 | ... .unwrap() | provenance | MaD:80 | +| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer | provenance | MaD:95 | +| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:55 | +| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:94 | +| test.rs:536:22:536:63 | ... .open(...) [Ok] | test.rs:536:22:536:72 | ... .unwrap() | provenance | MaD:82 | | test.rs:536:22:536:72 | ... .unwrap() | test.rs:536:13:536:18 | mut f1 | provenance | | -| test.rs:536:50:536:53 | open | test.rs:536:22:536:63 | ... .open(...) [Ok] | provenance | Src:MaD:6 | +| test.rs:536:50:536:53 | open | test.rs:536:22:536:63 | ... .open(...) [Ok] | provenance | Src:MaD:8 | | test.rs:538:30:538:40 | [post] &mut buffer | test.rs:539:15:539:20 | buffer | provenance | | | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | test.rs:538:35:538:40 | [post] buffer | provenance | | | test.rs:538:35:538:40 | [post] buffer | test.rs:539:15:539:20 | buffer | provenance | | | test.rs:539:15:539:20 | buffer | test.rs:539:14:539:20 | &buffer | provenance | | -| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer | provenance | MaD:93 | -| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:53 | -| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:92 | -| test.rs:543:22:543:80 | ... .open(...) [Ok] | test.rs:543:22:543:89 | ... .unwrap() | provenance | MaD:80 | +| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer | provenance | MaD:95 | +| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:55 | +| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:94 | +| test.rs:543:22:543:80 | ... .open(...) [Ok] | test.rs:543:22:543:89 | ... .unwrap() | provenance | MaD:82 | | test.rs:543:22:543:89 | ... .unwrap() | test.rs:543:13:543:18 | mut f2 | provenance | | -| test.rs:543:67:543:70 | open | test.rs:543:22:543:80 | ... .open(...) [Ok] | provenance | Src:MaD:6 | +| test.rs:543:67:543:70 | open | test.rs:543:22:543:80 | ... .open(...) [Ok] | provenance | Src:MaD:8 | | test.rs:545:30:545:40 | [post] &mut buffer | test.rs:546:15:546:20 | buffer | provenance | | | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | test.rs:545:35:545:40 | [post] buffer | provenance | | | test.rs:545:35:545:40 | [post] buffer | test.rs:546:15:546:20 | buffer | provenance | | | test.rs:546:15:546:20 | buffer | test.rs:546:14:546:20 | &buffer | provenance | | -| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer | provenance | MaD:93 | -| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:53 | -| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:92 | -| test.rs:550:22:550:114 | ... .open(...) [Ok] | test.rs:550:22:550:123 | ... .unwrap() | provenance | MaD:80 | +| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer | provenance | MaD:95 | +| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:55 | +| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:94 | +| test.rs:550:22:550:114 | ... .open(...) [Ok] | test.rs:550:22:550:123 | ... .unwrap() | provenance | MaD:82 | | test.rs:550:22:550:123 | ... .unwrap() | test.rs:550:13:550:18 | mut f3 | provenance | | -| test.rs:550:101:550:104 | open | test.rs:550:22:550:114 | ... .open(...) [Ok] | provenance | Src:MaD:6 | +| test.rs:550:101:550:104 | open | test.rs:550:22:550:114 | ... .open(...) [Ok] | provenance | Src:MaD:8 | | test.rs:552:30:552:40 | [post] &mut buffer | test.rs:553:15:553:20 | buffer | provenance | | | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | test.rs:552:35:552:40 | [post] buffer | provenance | | | test.rs:552:35:552:40 | [post] buffer | test.rs:553:15:553:20 | buffer | provenance | | | test.rs:553:15:553:20 | buffer | test.rs:553:14:553:20 | &buffer | provenance | | -| test.rs:560:13:560:17 | file1 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:52 | -| test.rs:560:21:560:39 | ...::open | test.rs:560:21:560:51 | ...::open(...) [Ok] | provenance | Src:MaD:5 | +| test.rs:560:13:560:17 | file1 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:54 | +| test.rs:560:21:560:39 | ...::open | test.rs:560:21:560:51 | ...::open(...) [Ok] | provenance | Src:MaD:7 | | test.rs:560:21:560:51 | ...::open(...) [Ok] | test.rs:560:21:560:52 | TryExpr | provenance | | | test.rs:560:21:560:52 | TryExpr | test.rs:560:13:560:17 | file1 | provenance | | | test.rs:561:13:561:17 | file2 | test.rs:562:38:562:42 | file2 | provenance | | -| test.rs:561:21:561:39 | ...::open | test.rs:561:21:561:59 | ...::open(...) [Ok] | provenance | Src:MaD:5 | +| test.rs:561:21:561:39 | ...::open | test.rs:561:21:561:59 | ...::open(...) [Ok] | provenance | Src:MaD:7 | | test.rs:561:21:561:59 | ...::open(...) [Ok] | test.rs:561:21:561:60 | TryExpr | provenance | | | test.rs:561:21:561:60 | TryExpr | test.rs:561:13:561:17 | file2 | provenance | | -| test.rs:562:13:562:22 | mut reader | test.rs:563:31:563:41 | [post] &mut buffer [&ref] | provenance | MaD:56 | +| test.rs:562:13:562:22 | mut reader | test.rs:563:31:563:41 | [post] &mut buffer [&ref] | provenance | MaD:58 | | test.rs:562:26:562:43 | file1.chain(...) | test.rs:562:13:562:22 | mut reader | provenance | | -| test.rs:562:38:562:42 | file2 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:51 | +| test.rs:562:38:562:42 | file2 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:53 | | test.rs:563:31:563:41 | [post] &mut buffer [&ref] | test.rs:563:36:563:41 | [post] buffer | provenance | | | test.rs:563:36:563:41 | [post] buffer | test.rs:564:15:564:20 | buffer | provenance | | | test.rs:564:15:564:20 | buffer | test.rs:564:14:564:20 | &buffer | provenance | | -| test.rs:569:13:569:17 | file1 | test.rs:570:26:570:40 | file1.take(...) | provenance | MaD:57 | -| test.rs:569:21:569:39 | ...::open | test.rs:569:21:569:51 | ...::open(...) [Ok] | provenance | Src:MaD:5 | +| test.rs:569:13:569:17 | file1 | test.rs:570:26:570:40 | file1.take(...) | provenance | MaD:59 | +| test.rs:569:21:569:39 | ...::open | test.rs:569:21:569:51 | ...::open(...) [Ok] | provenance | Src:MaD:7 | | test.rs:569:21:569:51 | ...::open(...) [Ok] | test.rs:569:21:569:52 | TryExpr | provenance | | | test.rs:569:21:569:52 | TryExpr | test.rs:569:13:569:17 | file1 | provenance | | -| test.rs:570:13:570:22 | mut reader | test.rs:571:31:571:41 | [post] &mut buffer [&ref] | provenance | MaD:56 | +| test.rs:570:13:570:22 | mut reader | test.rs:571:31:571:41 | [post] &mut buffer [&ref] | provenance | MaD:58 | | test.rs:570:26:570:40 | file1.take(...) | test.rs:570:13:570:22 | mut reader | provenance | | | test.rs:571:31:571:41 | [post] &mut buffer [&ref] | test.rs:571:36:571:41 | [post] buffer | provenance | | | test.rs:571:36:571:41 | [post] buffer | test.rs:572:15:572:20 | buffer | provenance | | | test.rs:572:15:572:20 | buffer | test.rs:572:14:572:20 | &buffer | provenance | | -| test.rs:581:9:581:16 | mut file | test.rs:585:32:585:42 | [post] &mut buffer [&ref] | provenance | MaD:63 | -| test.rs:581:9:581:16 | mut file | test.rs:591:39:591:49 | [post] &mut buffer [&ref] | provenance | MaD:69 | -| test.rs:581:9:581:16 | mut file | test.rs:597:42:597:52 | [post] &mut buffer [&ref] | provenance | MaD:70 | -| test.rs:581:9:581:16 | mut file | test.rs:603:25:603:35 | [post] &mut buffer [&ref] | provenance | MaD:65 | -| test.rs:581:9:581:16 | mut file | test.rs:608:18:608:31 | file.read_u8() [future, Ok] | provenance | MaD:71 | -| test.rs:581:9:581:16 | mut file | test.rs:609:18:609:32 | file.read_i16() [future, Ok] | provenance | MaD:67 | -| test.rs:581:9:581:16 | mut file | test.rs:610:18:610:32 | file.read_f32() [future, Ok] | provenance | MaD:66 | -| test.rs:581:9:581:16 | mut file | test.rs:611:18:611:35 | file.read_i64_le() [future, Ok] | provenance | MaD:68 | -| test.rs:581:9:581:16 | mut file | test.rs:620:23:620:33 | [post] &mut buffer [&ref] | provenance | MaD:64 | -| test.rs:581:20:581:40 | ...::open | test.rs:581:20:581:52 | ...::open(...) [future, Ok] | provenance | Src:MaD:9 | +| test.rs:581:9:581:16 | mut file | test.rs:585:32:585:42 | [post] &mut buffer [&ref] | provenance | MaD:65 | +| test.rs:581:9:581:16 | mut file | test.rs:591:39:591:49 | [post] &mut buffer [&ref] | provenance | MaD:71 | +| test.rs:581:9:581:16 | mut file | test.rs:597:42:597:52 | [post] &mut buffer [&ref] | provenance | MaD:72 | +| test.rs:581:9:581:16 | mut file | test.rs:603:25:603:35 | [post] &mut buffer [&ref] | provenance | MaD:67 | +| test.rs:581:9:581:16 | mut file | test.rs:608:18:608:31 | file.read_u8() [future, Ok] | provenance | MaD:73 | +| test.rs:581:9:581:16 | mut file | test.rs:609:18:609:32 | file.read_i16() [future, Ok] | provenance | MaD:69 | +| test.rs:581:9:581:16 | mut file | test.rs:610:18:610:32 | file.read_f32() [future, Ok] | provenance | MaD:68 | +| test.rs:581:9:581:16 | mut file | test.rs:611:18:611:35 | file.read_i64_le() [future, Ok] | provenance | MaD:70 | +| test.rs:581:9:581:16 | mut file | test.rs:620:23:620:33 | [post] &mut buffer [&ref] | provenance | MaD:66 | +| test.rs:581:20:581:40 | ...::open | test.rs:581:20:581:52 | ...::open(...) [future, Ok] | provenance | Src:MaD:11 | | test.rs:581:20:581:52 | ...::open(...) [future, Ok] | test.rs:581:20:581:58 | await ... [Ok] | provenance | | | test.rs:581:20:581:58 | await ... [Ok] | test.rs:581:20:581:59 | TryExpr | provenance | | | test.rs:581:20:581:59 | TryExpr | test.rs:581:9:581:16 | mut file | provenance | | @@ -635,17 +637,39 @@ edges | test.rs:620:23:620:33 | [post] &mut buffer [&ref] | test.rs:620:28:620:33 | [post] buffer | provenance | | | test.rs:620:28:620:33 | [post] buffer | test.rs:621:15:621:20 | buffer | provenance | | | test.rs:621:15:621:20 | buffer | test.rs:621:14:621:20 | &buffer | provenance | | -| test.rs:627:13:627:18 | mut f1 | test.rs:629:30:629:40 | [post] &mut buffer [&ref] | provenance | MaD:63 | +| test.rs:627:13:627:18 | mut f1 | test.rs:629:30:629:40 | [post] &mut buffer [&ref] | provenance | MaD:65 | | test.rs:627:22:627:65 | ... .open(...) [future, Ok] | test.rs:627:22:627:71 | await ... [Ok] | provenance | | | test.rs:627:22:627:71 | await ... [Ok] | test.rs:627:22:627:72 | TryExpr | provenance | | | test.rs:627:22:627:72 | TryExpr | test.rs:627:13:627:18 | mut f1 | provenance | | -| test.rs:627:52:627:55 | open | test.rs:627:22:627:65 | ... .open(...) [future, Ok] | provenance | Src:MaD:10 | +| test.rs:627:52:627:55 | open | test.rs:627:22:627:65 | ... .open(...) [future, Ok] | provenance | Src:MaD:12 | | test.rs:629:30:629:40 | [post] &mut buffer [&ref] | test.rs:629:35:629:40 | [post] buffer | provenance | | | test.rs:629:35:629:40 | [post] buffer | test.rs:630:15:630:20 | buffer | provenance | | | test.rs:630:15:630:20 | buffer | test.rs:630:14:630:20 | &buffer | provenance | | -| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:53 | -| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:111 | -| test.rs:688:26:688:53 | ...::connect | test.rs:688:26:688:62 | ...::connect(...) [Ok] | provenance | Src:MaD:7 | +| test.rs:660:9:660:16 | mut file | test.rs:664:22:664:25 | file | provenance | | +| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:44 | +| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:45 | +| test.rs:660:20:660:44 | ...::open | test.rs:660:20:660:56 | ...::open(...) [future, Ok] | provenance | Src:MaD:1 | +| test.rs:660:20:660:56 | ...::open(...) [future, Ok] | test.rs:660:20:660:62 | await ... [Ok] | provenance | | +| test.rs:660:20:660:62 | await ... [Ok] | test.rs:660:20:660:63 | TryExpr | provenance | | +| test.rs:660:20:660:63 | TryExpr | test.rs:660:9:660:16 | mut file | provenance | | +| test.rs:664:22:664:25 | file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:44 | +| test.rs:664:32:664:42 | [post] &mut buffer [&ref] | test.rs:664:37:664:42 | [post] buffer | provenance | | +| test.rs:664:37:664:42 | [post] buffer | test.rs:665:15:665:20 | buffer | provenance | | +| test.rs:665:15:665:20 | buffer | test.rs:665:14:665:20 | &buffer | provenance | | +| test.rs:671:13:671:18 | mut f1 | test.rs:673:22:673:23 | f1 | provenance | | +| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:44 | +| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:45 | +| test.rs:671:22:671:69 | ... .open(...) [future, Ok] | test.rs:671:22:671:75 | await ... [Ok] | provenance | | +| test.rs:671:22:671:75 | await ... [Ok] | test.rs:671:22:671:76 | TryExpr | provenance | | +| test.rs:671:22:671:76 | TryExpr | test.rs:671:13:671:18 | mut f1 | provenance | | +| test.rs:671:56:671:59 | open | test.rs:671:22:671:69 | ... .open(...) [future, Ok] | provenance | Src:MaD:2 | +| test.rs:673:22:673:23 | f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:44 | +| test.rs:673:30:673:40 | [post] &mut buffer [&ref] | test.rs:673:35:673:40 | [post] buffer | provenance | | +| test.rs:673:35:673:40 | [post] buffer | test.rs:674:15:674:20 | buffer | provenance | | +| test.rs:674:15:674:20 | buffer | test.rs:674:14:674:20 | &buffer | provenance | | +| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:55 | +| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:113 | +| test.rs:688:26:688:53 | ...::connect | test.rs:688:26:688:62 | ...::connect(...) [Ok] | provenance | Src:MaD:9 | | test.rs:688:26:688:62 | ...::connect(...) [Ok] | test.rs:688:26:688:63 | TryExpr | provenance | | | test.rs:688:26:688:63 | TryExpr | test.rs:688:13:688:22 | mut stream | provenance | | | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | test.rs:695:34:695:39 | [post] buffer | provenance | | @@ -653,21 +677,21 @@ edges | test.rs:695:34:695:39 | [post] buffer | test.rs:699:14:699:22 | buffer[0] | provenance | | | test.rs:698:15:698:20 | buffer | test.rs:698:14:698:20 | &buffer | provenance | | | test.rs:707:13:707:22 | mut stream | test.rs:715:58:715:63 | stream | provenance | | -| test.rs:707:26:707:61 | ...::connect_timeout | test.rs:707:26:707:105 | ...::connect_timeout(...) [Ok] | provenance | Src:MaD:8 | +| test.rs:707:26:707:61 | ...::connect_timeout | test.rs:707:26:707:105 | ...::connect_timeout(...) [Ok] | provenance | Src:MaD:10 | | test.rs:707:26:707:105 | ...::connect_timeout(...) [Ok] | test.rs:707:26:707:106 | TryExpr | provenance | | | test.rs:707:26:707:106 | TryExpr | test.rs:707:13:707:22 | mut stream | provenance | | -| test.rs:715:21:715:30 | mut reader | test.rs:718:44:718:52 | [post] &mut line [&ref] | provenance | MaD:47 | -| test.rs:715:34:715:64 | ...::new(...) | test.rs:715:34:715:74 | ... .take(...) | provenance | MaD:57 | +| test.rs:715:21:715:30 | mut reader | test.rs:718:44:718:52 | [post] &mut line [&ref] | provenance | MaD:49 | +| test.rs:715:34:715:64 | ...::new(...) | test.rs:715:34:715:74 | ... .take(...) | provenance | MaD:59 | | test.rs:715:34:715:74 | ... .take(...) | test.rs:715:21:715:30 | mut reader | provenance | | -| test.rs:715:58:715:63 | stream | test.rs:715:34:715:64 | ...::new(...) | provenance | MaD:101 | +| test.rs:715:58:715:63 | stream | test.rs:715:34:715:64 | ...::new(...) | provenance | MaD:103 | | test.rs:718:44:718:52 | [post] &mut line [&ref] | test.rs:718:49:718:52 | [post] line | provenance | | | test.rs:718:49:718:52 | [post] line | test.rs:725:35:725:38 | line | provenance | | | test.rs:725:35:725:38 | line | test.rs:725:34:725:38 | &line | provenance | | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:767:35:767:46 | [post] &mut buffer1 [&ref] | provenance | MaD:117 | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:771:36:771:47 | [post] &mut buffer2 [&ref] | provenance | MaD:63 | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:787:41:787:51 | [post] &mut buffer [&ref] | provenance | MaD:118 | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:810:45:810:55 | [post] &mut buffer [&ref] | provenance | MaD:119 | -| test.rs:759:28:759:57 | ...::connect | test.rs:759:28:759:66 | ...::connect(...) [future, Ok] | provenance | Src:MaD:13 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:767:35:767:46 | [post] &mut buffer1 [&ref] | provenance | MaD:119 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:771:36:771:47 | [post] &mut buffer2 [&ref] | provenance | MaD:65 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:787:41:787:51 | [post] &mut buffer [&ref] | provenance | MaD:120 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:810:45:810:55 | [post] &mut buffer [&ref] | provenance | MaD:121 | +| test.rs:759:28:759:57 | ...::connect | test.rs:759:28:759:66 | ...::connect(...) [future, Ok] | provenance | Src:MaD:15 | | test.rs:759:28:759:66 | ...::connect(...) [future, Ok] | test.rs:759:28:759:72 | await ... [Ok] | provenance | | | test.rs:759:28:759:72 | await ... [Ok] | test.rs:759:28:759:73 | TryExpr | provenance | | | test.rs:759:28:759:73 | TryExpr | test.rs:759:9:759:24 | mut tokio_stream | provenance | | @@ -687,7 +711,7 @@ edges | test.rs:817:27:817:32 | buffer | test.rs:817:26:817:32 | &buffer | provenance | | | test_futures_io.rs:19:9:19:11 | tcp | test_futures_io.rs:20:11:20:13 | tcp | provenance | | | test_futures_io.rs:19:9:19:11 | tcp | test_futures_io.rs:26:53:26:55 | tcp | provenance | | -| test_futures_io.rs:19:15:19:32 | ...::connect | test_futures_io.rs:19:15:19:37 | ...::connect(...) [future, Ok] | provenance | Src:MaD:1 | +| test_futures_io.rs:19:15:19:32 | ...::connect | test_futures_io.rs:19:15:19:37 | ...::connect(...) [future, Ok] | provenance | Src:MaD:3 | | test_futures_io.rs:19:15:19:37 | ...::connect(...) [future, Ok] | test_futures_io.rs:19:15:19:43 | await ... [Ok] | provenance | | | test_futures_io.rs:19:15:19:43 | await ... [Ok] | test_futures_io.rs:19:15:19:44 | TryExpr | provenance | | | test_futures_io.rs:19:15:19:44 | TryExpr | test_futures_io.rs:19:9:19:11 | tcp | provenance | | @@ -696,13 +720,13 @@ edges | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:32:40:32:45 | reader | provenance | | | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:45:64:45:69 | reader | provenance | | | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:27:49:32 | reader | provenance | | -| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:42 | -| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:43 | +| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:44 | +| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:45 | | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:54:51:54:56 | reader | provenance | | | test_futures_io.rs:26:22:26:56 | connector.connect(...) [future, Ok] | test_futures_io.rs:26:22:26:62 | await ... [Ok] | provenance | | | test_futures_io.rs:26:22:26:62 | await ... [Ok] | test_futures_io.rs:26:22:26:63 | TryExpr | provenance | | | test_futures_io.rs:26:22:26:63 | TryExpr | test_futures_io.rs:26:9:26:18 | mut reader | provenance | | -| test_futures_io.rs:26:53:26:55 | tcp | test_futures_io.rs:26:22:26:56 | connector.connect(...) [future, Ok] | provenance | MaD:84 | +| test_futures_io.rs:26:53:26:55 | tcp | test_futures_io.rs:26:22:26:56 | connector.connect(...) [future, Ok] | provenance | MaD:86 | | test_futures_io.rs:27:11:27:16 | reader | test_futures_io.rs:27:10:27:16 | &reader | provenance | | | test_futures_io.rs:32:13:32:22 | mut pinned | test_futures_io.rs:33:15:33:20 | pinned | provenance | | | test_futures_io.rs:32:13:32:22 | mut pinned [&ref] | test_futures_io.rs:33:15:33:20 | pinned [&ref] | provenance | | @@ -710,56 +734,56 @@ edges | test_futures_io.rs:32:26:32:46 | ...::new(...) | test_futures_io.rs:32:13:32:22 | mut pinned | provenance | | | test_futures_io.rs:32:26:32:46 | ...::new(...) [&ref] | test_futures_io.rs:32:13:32:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:32:26:32:46 | ...::new(...) [Pin, &ref] | test_futures_io.rs:32:13:32:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) | provenance | MaD:76 | -| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [&ref] | provenance | MaD:78 | -| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [Pin, &ref] | provenance | MaD:77 | +| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) | provenance | MaD:78 | +| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [&ref] | provenance | MaD:80 | +| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [Pin, &ref] | provenance | MaD:79 | | test_futures_io.rs:32:40:32:45 | reader | test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | provenance | | | test_futures_io.rs:33:15:33:20 | pinned | test_futures_io.rs:33:14:33:20 | &pinned | provenance | | | test_futures_io.rs:33:15:33:20 | pinned [&ref] | test_futures_io.rs:33:14:33:20 | &pinned | provenance | | | test_futures_io.rs:33:15:33:20 | pinned [Pin, &ref] | test_futures_io.rs:33:14:33:20 | &pinned | provenance | | -| test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | provenance | MaD:42 | +| test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | provenance | MaD:44 | | test_futures_io.rs:45:64:45:69 | reader | test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | provenance | | | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | test_futures_io.rs:45:77:45:83 | [post] buffer1 | provenance | | | test_futures_io.rs:45:77:45:83 | [post] buffer1 | test_futures_io.rs:46:15:46:36 | buffer1[...] | provenance | | | test_futures_io.rs:46:15:46:36 | buffer1[...] | test_futures_io.rs:46:14:46:36 | &... | provenance | | -| test_futures_io.rs:49:27:49:32 | reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:42 | +| test_futures_io.rs:49:27:49:32 | reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:44 | | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | test_futures_io.rs:49:44:49:50 | [post] buffer2 | provenance | | | test_futures_io.rs:49:44:49:50 | [post] buffer2 | test_futures_io.rs:51:15:51:36 | buffer2[...] | provenance | | | test_futures_io.rs:51:15:51:36 | buffer2[...] | test_futures_io.rs:51:14:51:36 | &... | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:55:11:55:17 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:59:40:59:46 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:69:37:69:43 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:83:22:83:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:37 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:83:22:83:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:39 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:90:40:90:46 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:103:64:103:70 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:27:107:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:42 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:43 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:44 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:45 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:113:40:113:46 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:125:22:125:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:37 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:125:22:125:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:39 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:27:132:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:40 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:41 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:42 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:43 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:27:139:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:38 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:39 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:40 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:41 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:27:146:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:44 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:45 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:46 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:47 | | test_futures_io.rs:54:23:54:57 | ...::new(...) | test_futures_io.rs:54:9:54:19 | mut reader2 | provenance | | -| test_futures_io.rs:54:51:54:56 | reader | test_futures_io.rs:54:23:54:57 | ...::new(...) | provenance | MaD:85 | +| test_futures_io.rs:54:51:54:56 | reader | test_futures_io.rs:54:23:54:57 | ...::new(...) | provenance | MaD:87 | | test_futures_io.rs:55:11:55:17 | reader2 | test_futures_io.rs:55:10:55:17 | &reader2 | provenance | | | test_futures_io.rs:59:13:59:22 | mut pinned | test_futures_io.rs:60:15:60:20 | pinned | provenance | | -| test_futures_io.rs:59:13:59:22 | mut pinned | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:36 | +| test_futures_io.rs:59:13:59:22 | mut pinned | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | | test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | test_futures_io.rs:60:15:60:20 | pinned [&ref] | provenance | | -| test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:36 | +| test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | | test_futures_io.rs:59:13:59:22 | mut pinned [Pin, &ref] | test_futures_io.rs:60:15:60:20 | pinned [Pin, &ref] | provenance | | | test_futures_io.rs:59:26:59:47 | ...::new(...) | test_futures_io.rs:59:13:59:22 | mut pinned | provenance | | | test_futures_io.rs:59:26:59:47 | ...::new(...) [&ref] | test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:59:26:59:47 | ...::new(...) [Pin, &ref] | test_futures_io.rs:59:13:59:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) | provenance | MaD:76 | -| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [&ref] | provenance | MaD:78 | -| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [Pin, &ref] | provenance | MaD:77 | +| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) | provenance | MaD:78 | +| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [&ref] | provenance | MaD:80 | +| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [Pin, &ref] | provenance | MaD:79 | | test_futures_io.rs:59:40:59:46 | reader2 | test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:60:15:60:20 | pinned | test_futures_io.rs:60:14:60:20 | &pinned | provenance | | | test_futures_io.rs:60:15:60:20 | pinned [&ref] | test_futures_io.rs:60:14:60:20 | &pinned | provenance | | @@ -772,11 +796,11 @@ edges | test_futures_io.rs:63:31:63:33 | buf | test_futures_io.rs:65:18:65:20 | buf | provenance | | | test_futures_io.rs:64:19:64:24 | buffer [Ready, Ok] | test_futures_io.rs:64:18:64:24 | &buffer | provenance | | | test_futures_io.rs:69:13:69:19 | buffer2 [Ready, Ok] | test_futures_io.rs:70:16:70:22 | buffer2 [Ready, Ok] | provenance | | -| test_futures_io.rs:69:23:69:44 | ...::new(...) | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:36 | -| test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:36 | +| test_futures_io.rs:69:23:69:44 | ...::new(...) | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | +| test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | test_futures_io.rs:69:13:69:19 | buffer2 [Ready, Ok] | provenance | | -| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) | provenance | MaD:76 | -| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | provenance | MaD:78 | +| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) | provenance | MaD:78 | +| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | provenance | MaD:80 | | test_futures_io.rs:69:37:69:43 | reader2 | test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:70:16:70:22 | buffer2 [Ready, Ok] | test_futures_io.rs:71:13:71:32 | ...::Ready(...) [Ready, Ok] | provenance | | | test_futures_io.rs:70:16:70:22 | buffer2 [Ready, Ok] | test_futures_io.rs:72:23:72:29 | buffer2 [Ready, Ok] | provenance | | @@ -794,33 +818,33 @@ edges | test_futures_io.rs:90:26:90:47 | ...::new(...) | test_futures_io.rs:90:13:90:22 | mut pinned | provenance | | | test_futures_io.rs:90:26:90:47 | ...::new(...) [&ref] | test_futures_io.rs:90:13:90:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:90:26:90:47 | ...::new(...) [Pin, &ref] | test_futures_io.rs:90:13:90:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) | provenance | MaD:76 | -| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [&ref] | provenance | MaD:78 | -| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [Pin, &ref] | provenance | MaD:77 | +| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) | provenance | MaD:78 | +| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [&ref] | provenance | MaD:80 | +| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [Pin, &ref] | provenance | MaD:79 | | test_futures_io.rs:90:40:90:46 | reader2 | test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:91:15:91:20 | pinned | test_futures_io.rs:91:14:91:20 | &pinned | provenance | | | test_futures_io.rs:91:15:91:20 | pinned [&ref] | test_futures_io.rs:91:14:91:20 | &pinned | provenance | | | test_futures_io.rs:91:15:91:20 | pinned [Pin, &ref] | test_futures_io.rs:91:14:91:20 | &pinned | provenance | | -| test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | provenance | MaD:42 | +| test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | provenance | MaD:44 | | test_futures_io.rs:103:64:103:70 | reader2 | test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | test_futures_io.rs:103:78:103:84 | [post] buffer1 | provenance | | | test_futures_io.rs:103:78:103:84 | [post] buffer1 | test_futures_io.rs:104:15:104:36 | buffer1[...] | provenance | | | test_futures_io.rs:104:15:104:36 | buffer1[...] | test_futures_io.rs:104:14:104:36 | &... | provenance | | -| test_futures_io.rs:107:27:107:33 | reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:42 | +| test_futures_io.rs:107:27:107:33 | reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:44 | | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | test_futures_io.rs:107:45:107:51 | [post] buffer2 | provenance | | | test_futures_io.rs:107:45:107:51 | [post] buffer2 | test_futures_io.rs:108:15:108:36 | buffer2[...] | provenance | | | test_futures_io.rs:108:15:108:36 | buffer2[...] | test_futures_io.rs:108:14:108:36 | &... | provenance | | | test_futures_io.rs:113:13:113:22 | mut pinned | test_futures_io.rs:114:15:114:20 | pinned | provenance | | -| test_futures_io.rs:113:13:113:22 | mut pinned | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:36 | +| test_futures_io.rs:113:13:113:22 | mut pinned | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | | test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | test_futures_io.rs:114:15:114:20 | pinned [&ref] | provenance | | -| test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:36 | +| test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | | test_futures_io.rs:113:13:113:22 | mut pinned [Pin, &ref] | test_futures_io.rs:114:15:114:20 | pinned [Pin, &ref] | provenance | | | test_futures_io.rs:113:26:113:47 | ...::new(...) | test_futures_io.rs:113:13:113:22 | mut pinned | provenance | | | test_futures_io.rs:113:26:113:47 | ...::new(...) [&ref] | test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:113:26:113:47 | ...::new(...) [Pin, &ref] | test_futures_io.rs:113:13:113:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) | provenance | MaD:76 | -| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [&ref] | provenance | MaD:78 | -| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [Pin, &ref] | provenance | MaD:77 | +| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) | provenance | MaD:78 | +| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [&ref] | provenance | MaD:80 | +| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [Pin, &ref] | provenance | MaD:79 | | test_futures_io.rs:113:40:113:46 | reader2 | test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:114:15:114:20 | pinned | test_futures_io.rs:114:14:114:20 | &pinned | provenance | | | test_futures_io.rs:114:15:114:20 | pinned [&ref] | test_futures_io.rs:114:14:114:20 | &pinned | provenance | | @@ -836,40 +860,40 @@ edges | test_futures_io.rs:125:22:125:39 | reader2.fill_buf() [future, Ok] | test_futures_io.rs:125:22:125:45 | await ... [Ok] | provenance | | | test_futures_io.rs:125:22:125:45 | await ... [Ok] | test_futures_io.rs:125:22:125:46 | TryExpr | provenance | | | test_futures_io.rs:125:22:125:46 | TryExpr | test_futures_io.rs:125:13:125:18 | buffer | provenance | | -| test_futures_io.rs:132:27:132:33 | reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:40 | +| test_futures_io.rs:132:27:132:33 | reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:42 | | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | test_futures_io.rs:132:58:132:61 | [post] line | provenance | | | test_futures_io.rs:132:58:132:61 | [post] line | test_futures_io.rs:133:15:133:18 | line | provenance | | | test_futures_io.rs:133:15:133:18 | line | test_futures_io.rs:133:14:133:18 | &line | provenance | | -| test_futures_io.rs:139:27:139:33 | reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:38 | +| test_futures_io.rs:139:27:139:33 | reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:40 | | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | test_futures_io.rs:139:50:139:53 | [post] line | provenance | | | test_futures_io.rs:139:50:139:53 | [post] line | test_futures_io.rs:140:15:140:18 | line | provenance | | | test_futures_io.rs:140:15:140:18 | line | test_futures_io.rs:140:14:140:18 | &line | provenance | | -| test_futures_io.rs:146:27:146:33 | reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:44 | +| test_futures_io.rs:146:27:146:33 | reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:46 | | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | test_futures_io.rs:146:52:146:57 | [post] buffer | provenance | | | test_futures_io.rs:146:52:146:57 | [post] buffer | test_futures_io.rs:147:15:147:20 | buffer | provenance | | | test_futures_io.rs:147:15:147:20 | buffer | test_futures_io.rs:147:14:147:20 | &buffer | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:14 | a | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:14 | a | provenance | | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:73 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:82 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:73 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:82 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:75 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:84 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:75 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:84 | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:14 | a | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:14 | a | provenance | | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:72 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:81 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:72 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:81 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:74 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:83 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:74 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:83 | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:15:14:15:14 | a | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:15:14:15:14 | a | provenance | | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:73 | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:82 | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:73 | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:82 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:72 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:81 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:72 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:81 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:75 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:84 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:75 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:84 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:74 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:83 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:74 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:83 | | web_frameworks.rs:68:15:68:15 | a | web_frameworks.rs:70:14:70:14 | a | provenance | | | web_frameworks.rs:68:15:68:15 | a | web_frameworks.rs:70:14:70:14 | a | provenance | | nodes @@ -1437,6 +1461,26 @@ nodes | test.rs:629:35:629:40 | [post] buffer | semmle.label | [post] buffer | | test.rs:630:14:630:20 | &buffer | semmle.label | &buffer | | test.rs:630:15:630:20 | buffer | semmle.label | buffer | +| test.rs:660:9:660:16 | mut file | semmle.label | mut file | +| test.rs:660:20:660:44 | ...::open | semmle.label | ...::open | +| test.rs:660:20:660:56 | ...::open(...) [future, Ok] | semmle.label | ...::open(...) [future, Ok] | +| test.rs:660:20:660:62 | await ... [Ok] | semmle.label | await ... [Ok] | +| test.rs:660:20:660:63 | TryExpr | semmle.label | TryExpr | +| test.rs:664:22:664:25 | file | semmle.label | file | +| test.rs:664:32:664:42 | [post] &mut buffer [&ref] | semmle.label | [post] &mut buffer [&ref] | +| test.rs:664:37:664:42 | [post] buffer | semmle.label | [post] buffer | +| test.rs:665:14:665:20 | &buffer | semmle.label | &buffer | +| test.rs:665:15:665:20 | buffer | semmle.label | buffer | +| test.rs:671:13:671:18 | mut f1 | semmle.label | mut f1 | +| test.rs:671:22:671:69 | ... .open(...) [future, Ok] | semmle.label | ... .open(...) [future, Ok] | +| test.rs:671:22:671:75 | await ... [Ok] | semmle.label | await ... [Ok] | +| test.rs:671:22:671:76 | TryExpr | semmle.label | TryExpr | +| test.rs:671:56:671:59 | open | semmle.label | open | +| test.rs:673:22:673:23 | f1 | semmle.label | f1 | +| test.rs:673:30:673:40 | [post] &mut buffer [&ref] | semmle.label | [post] &mut buffer [&ref] | +| test.rs:673:35:673:40 | [post] buffer | semmle.label | [post] buffer | +| test.rs:674:14:674:20 | &buffer | semmle.label | &buffer | +| test.rs:674:15:674:20 | buffer | semmle.label | buffer | | test.rs:688:13:688:22 | mut stream | semmle.label | mut stream | | test.rs:688:26:688:53 | ...::connect | semmle.label | ...::connect | | test.rs:688:26:688:62 | ...::connect(...) [Ok] | semmle.label | ...::connect(...) [Ok] | @@ -1738,6 +1782,8 @@ testFailures | test.rs:615:14:615:15 | v4 | test.rs:581:20:581:40 | ...::open | test.rs:615:14:615:15 | v4 | $@ | test.rs:581:20:581:40 | ...::open | ...::open | | test.rs:621:14:621:20 | &buffer | test.rs:581:20:581:40 | ...::open | test.rs:621:14:621:20 | &buffer | $@ | test.rs:581:20:581:40 | ...::open | ...::open | | test.rs:630:14:630:20 | &buffer | test.rs:627:52:627:55 | open | test.rs:630:14:630:20 | &buffer | $@ | test.rs:627:52:627:55 | open | open | +| test.rs:665:14:665:20 | &buffer | test.rs:660:20:660:44 | ...::open | test.rs:665:14:665:20 | &buffer | $@ | test.rs:660:20:660:44 | ...::open | ...::open | +| test.rs:674:14:674:20 | &buffer | test.rs:671:56:671:59 | open | test.rs:674:14:674:20 | &buffer | $@ | test.rs:671:56:671:59 | open | open | | test.rs:698:14:698:20 | &buffer | test.rs:688:26:688:53 | ...::connect | test.rs:698:14:698:20 | &buffer | $@ | test.rs:688:26:688:53 | ...::connect | ...::connect | | test.rs:699:14:699:22 | buffer[0] | test.rs:688:26:688:53 | ...::connect | test.rs:699:14:699:22 | buffer[0] | $@ | test.rs:688:26:688:53 | ...::connect | ...::connect | | test.rs:725:34:725:38 | &line | test.rs:707:26:707:61 | ...::connect_timeout | test.rs:725:34:725:38 | &line | $@ | test.rs:707:26:707:61 | ...::connect_timeout | ...::connect_timeout | diff --git a/rust/ql/test/library-tests/dataflow/sources/test.rs b/rust/ql/test/library-tests/dataflow/sources/test.rs index 6e30159ea1a..895a789cfaf 100644 --- a/rust/ql/test/library-tests/dataflow/sources/test.rs +++ b/rust/ql/test/library-tests/dataflow/sources/test.rs @@ -662,7 +662,7 @@ async fn test_async_std_file() -> std::io::Result<()> { { let mut buffer = [0u8; 100]; let _bytes = file.read(&mut buffer).await?; - sink(&buffer); // $ MISSING: hasTaintFlow="file.txt" + sink(&buffer); // $ hasTaintFlow="file.txt" } // --- OpenOptions --- @@ -671,7 +671,7 @@ async fn test_async_std_file() -> std::io::Result<()> { let mut f1 = async_std::fs::OpenOptions::new().open("f1.txt").await?; // $ Alert[rust/summary/taint-sources] let mut buffer = [0u8; 1024]; let _bytes = f1.read(&mut buffer).await?; - sink(&buffer); // $ MISSING: hasTaintFlow="f1.txt" + sink(&buffer); // $ hasTaintFlow="f1.txt" } Ok(()) diff --git a/rust/ql/test/library-tests/path-resolution/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/library-tests/path-resolution/CONSISTENCY/PathResolutionConsistency.expected index d945cb4c6c2..7a3fd01dbc7 100644 --- a/rust/ql/test/library-tests/path-resolution/CONSISTENCY/PathResolutionConsistency.expected +++ b/rust/ql/test/library-tests/path-resolution/CONSISTENCY/PathResolutionConsistency.expected @@ -1,4 +1,3 @@ multipleCallTargets | main.rs:124:9:124:11 | f(...) | -| main.rs:774:5:774:7 | f(...) | | proc_macro.rs:9:5:9:10 | ...::new(...) | diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs index db8e4c0f39d..5146373b896 100644 --- a/rust/ql/test/library-tests/path-resolution/main.rs +++ b/rust/ql/test/library-tests/path-resolution/main.rs @@ -771,7 +771,7 @@ fn main() { my::nested::nested1::nested2::f(); // $ item=I4 my::f(); // $ item=I38 nested2::nested3::nested4::f(); // $ item=I12 - f(); // $ item=I12 $ SPURIOUS: item=I119 + f(); // $ item=I12 g(); // $ item=I13 crate::h(); // $ item=I25 m1::m2::g(); // $ item=I19 diff --git a/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs b/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs index e2d413841c3..b459ca05aa6 100644 --- a/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs +++ b/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs @@ -7,4 +7,4 @@ pub fn f() { use super::super::h; // $ item=I25 use super::g; // $ item=I9 -use super::nested6_f; // $ MISSING: item=I116 +use super::nested6_f; // $ item=I116 diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected index 8f12af96c02..067365a5386 100644 --- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected +++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected @@ -361,7 +361,6 @@ resolvePath | main.rs:773:5:773:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | | main.rs:773:5:773:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | | main.rs:774:5:774:5 | f | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:774:5:774:5 | f | my2/nested2.rs:23:9:25:9 | fn f | | main.rs:775:5:775:5 | g | my2/nested2.rs:7:9:9:9 | fn g | | main.rs:776:5:776:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) | | main.rs:776:5:776:12 | ...::h | main.rs:56:1:75:1 | fn h | @@ -440,6 +439,7 @@ resolvePath | my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | | my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g | | my2/my3/mod.rs:10:5:10:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | +| my2/my3/mod.rs:10:5:10:20 | ...::nested6_f | my2/nested2.rs:15:9:17:9 | fn f | | my.rs:3:5:3:10 | nested | my.rs:1:1:1:15 | mod nested | | my.rs:3:5:3:13 | ...::g | my/nested.rs:19:1:22:1 | fn g | | my.rs:11:5:11:5 | g | my/nested.rs:19:1:22:1 | fn g | From a6c1ffc45d1c6bec8f01e55f5b4ac6989fd2a236 Mon Sep 17 00:00:00 2001 From: Philip Ginsbach Date: Fri, 19 Sep 2025 10:39:36 +0100 Subject: [PATCH 038/160] sort the annotations alphabetically --- .../ql-language-reference/annotations.rst | 6 +- .../ql-language-specification.rst | 62 +++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/docs/codeql/ql-language-reference/annotations.rst b/docs/codeql/ql-language-reference/annotations.rst index 0ddb28c3a9d..00080087d36 100644 --- a/docs/codeql/ql-language-reference/annotations.rst +++ b/docs/codeql/ql-language-reference/annotations.rst @@ -16,9 +16,9 @@ For example, to declare a module ``M`` as private, you could use: } Note that some annotations act on an entity itself, whilst others act on a particular *name* for the entity: - - Act on an **entity**: ``abstract``, ``cached``, ``external``, ``transient``, ``override``, ``pragma``, ``language``, - and ``bindingset`` - - Act on a **name**: ``deprecated``, ``library``, ``private``, ``final``, and ``query`` + - Act on an **entity**: ``abstract``, ``bindingset``, ``cached``, ``external``, ``language``, + ``override``, ``pragma``, and ``transient`` + - Act on a **name**: ``deprecated``, ``final``, ``library``, ``private``, and ``query`` For example, if you annotate an entity with ``private``, then only that particular name is private. You could still access that entity under a different name (using an :ref:`alias `). diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index 9989c73e5dc..854c9f28f60 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -761,17 +761,17 @@ Various kinds of syntax can have *annotations* applied to them. Annotations are annotation ::= simpleAnnotation | argsAnnotation simpleAnnotation ::= "abstract" - | "cached" - | "external" - | "extensible" - | "final" - | "transient" - | "library" - | "private" - | "deprecated" - | "override" | "additional" + | "cached" + | "deprecated" + | "extensible" + | "external" + | "final" + | "library" + | "override" + | "private" | "query" + | "transient" argsAnnotation ::= "pragma" "[" ("inline" | "inline_late" | "noinline" | "nomagic" | "noopt" | "assume_small_delta") "]" | "language" "[" "monotonicAggregates" "]" @@ -791,28 +791,28 @@ The following table summarizes the syntactic constructs which can be marked with +================+=========+============+===================+=======================+=========+========+=========+=========+============+ | ``abstract`` | yes | | yes | | | | | | | +----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``additional`` | yes | | | yes | | | yes | yes | yes | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ | ``cached`` | yes | yes | yes | yes | | | yes | | | +----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ -| ``external`` | | | | yes | | | | | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ -| ``extensible`` | | | | yes | | | | | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ -| ``final`` | yes | | yes | | | yes | | (yes) | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ -| ``transient`` | | | | yes | | | | | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ -| ``library`` | (yes) | | | | | | | | | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ -| ``private`` | yes | | yes | yes | yes | yes | yes | yes | yes | -+----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ | ``deprecated`` | yes | | yes | yes | yes | yes | yes | yes | yes | +----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``extensible`` | | | | yes | | | | | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``external`` | | | | yes | | | | | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``final`` | yes | | yes | | | yes | | (yes) | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``library`` | (yes) | | | | | | | | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ | ``override`` | | | yes | | | yes | | | | +----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ -| ``additional`` | yes | | | yes | | | yes | yes | yes | +| ``private`` | yes | | yes | yes | yes | yes | yes | yes | yes | +----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ | ``query`` | | | | yes | | | | yes | | +----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ +| ``transient`` | | | | yes | | | | | | ++----------------+---------+------------+-------------------+-----------------------+---------+--------+---------+---------+------------+ The ``library`` annotation is only usable within a QLL file, not a QL file. The ``final`` annotation is usable on type aliases, but not on module aliases and predicate aliases. @@ -2292,17 +2292,17 @@ The complete grammar for QL is as follows: annotation ::= simpleAnnotation | argsAnnotation simpleAnnotation ::= "abstract" - | "cached" - | "external" - | "extensible" - | "final" - | "transient" - | "library" - | "private" - | "deprecated" - | "override" | "additional" + | "cached" + | "deprecated" + | "extensible" + | "external" + | "final" + | "library" + | "override" + | "private" | "query" + | "transient" argsAnnotation ::= "pragma" "[" ("inline" | "inline_late" | "noinline" | "nomagic" | "noopt" | "assume_small_delta") "]" | "language" "[" "monotonicAggregates" "]" From b27d3745781d0362ec42dfb384d1d21c296bdb05 Mon Sep 17 00:00:00 2001 From: Philip Ginsbach Date: Fri, 19 Sep 2025 10:41:52 +0100 Subject: [PATCH 039/160] mention 'additional' and 'extensible' annotations --- docs/codeql/ql-language-reference/annotations.rst | 4 ++-- .../ql-language-reference/ql-language-specification.rst | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/codeql/ql-language-reference/annotations.rst b/docs/codeql/ql-language-reference/annotations.rst index 00080087d36..cffbbf73c71 100644 --- a/docs/codeql/ql-language-reference/annotations.rst +++ b/docs/codeql/ql-language-reference/annotations.rst @@ -16,9 +16,9 @@ For example, to declare a module ``M`` as private, you could use: } Note that some annotations act on an entity itself, whilst others act on a particular *name* for the entity: - - Act on an **entity**: ``abstract``, ``bindingset``, ``cached``, ``external``, ``language``, + - Act on an **entity**: ``abstract``, ``bindingset``, ``cached``, ``extensible``, ``external``, ``language``, ``override``, ``pragma``, and ``transient`` - - Act on a **name**: ``deprecated``, ``final``, ``library``, ``private``, and ``query`` + - Act on a **name**: ``additional``, ``deprecated``, ``final``, ``library``, ``private``, and ``query`` For example, if you annotate an entity with ``private``, then only that particular name is private. You could still access that entity under a different name (using an :ref:`alias `). diff --git a/docs/codeql/ql-language-reference/ql-language-specification.rst b/docs/codeql/ql-language-reference/ql-language-specification.rst index 854c9f28f60..f834949c3cd 100644 --- a/docs/codeql/ql-language-reference/ql-language-specification.rst +++ b/docs/codeql/ql-language-reference/ql-language-specification.rst @@ -933,7 +933,8 @@ A predicate definition adds a mapping from the predicate name and arity to the p When a predicate is a top-level clause in a module, it is called a non-member predicate. See below for "`Member predicates <#member-predicates>`__." -A valid non-member predicate can be annotated with ``cached``, ``deprecated``, ``external``, ``transient``, ``private``, and ``query``. Note, the ``transient`` annotation can only be applied if the non-member predicate is also annotated with ``external``. +A valid non-member predicate can be annotated with ``additional``, ``cached``, ``deprecated``, ``extensible``, ``external``, ``transient``, ``private``, and ``query``. +Note, the ``transient`` annotation can only be applied if the non-member predicate is also annotated with ``external``. The head of the predicate gives a name, an optional *result type*, and a sequence of variables declarations that are *arguments*: @@ -979,7 +980,7 @@ A class type is said to *final inherit* from base types that are final or refere A class adds a mapping from the class name to the class declaration to the current module's declared type environment. -A valid class can be annotated with ``abstract``, ``final``, ``library``, and ``private``. Any other annotation renders the class invalid. +A valid class can be annotated with ``abstract``, ``additional``, ``final``, ``library``, and ``private``. Any other annotation renders the class invalid. A valid class may not inherit from itself, or from more than one primitive type. The set of types that a valid class inherits from must be disjoint from the set of types that it final inherits from. From c7a9cc5a424c80dc4a3c538d20f934ad4d5f44c7 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 17 Sep 2025 14:55:52 +0200 Subject: [PATCH 040/160] Rust: Use annotations also for items in macro expansions --- .../lib/utils/test/PathResolutionInlineExpectationsTest.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll b/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll index c5a95ac9038..8d2fdb2d2eb 100644 --- a/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll +++ b/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll @@ -25,9 +25,9 @@ private module ResolveTest implements TestSig { private predicate item(ItemNode i, string value) { exists(string filepath, int line, boolean inMacro | itemAt(i, filepath, line, inMacro) | - commmentAt(value, filepath, line) and inMacro = false + commmentAt(value, filepath, line) or - not (commmentAt(_, filepath, line) and inMacro = false) and + not commmentAt(_, filepath, line) and value = i.getName() ) } From 32365fd673e0520ae10cea12212adfd3e98d0b6e Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 17 Sep 2025 15:15:29 +0200 Subject: [PATCH 041/160] Rust: Account for attribute expansions in path resolution --- rust/ql/lib/codeql/rust/internal/PathResolution.qll | 11 ++++++----- rust/ql/test/library-tests/path-resolution/main.rs | 7 +++---- .../path-resolution/path-resolution.expected | 10 ++++++---- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index f819632ce10..980033811dd 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -156,6 +156,11 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki * - https://doc.rust-lang.org/reference/names/namespaces.html */ abstract class ItemNode extends Locatable { + ItemNode() { + // Exclude items that are superceded by the expansion of an attribute macro. + not this.(Item).hasAttributeMacroExpansion() + } + /** Gets the (original) name of this item. */ abstract string getName(); @@ -660,11 +665,7 @@ final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl { override Visibility getVisibility() { result = Impl.super.getVisibility() } - TypeParamItemNode getBlanketImplementationTypeParam() { - result = this.resolveSelfTy() and - // This impl block is not superseded by the expansion of an attribute macro. - not exists(super.getAttributeMacroExpansion()) - } + TypeParamItemNode getBlanketImplementationTypeParam() { result = this.resolveSelfTy() } /** * Holds if this impl block is a blanket implementation. That is, the diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs index 5146373b896..1ad55d36ad4 100644 --- a/rust/ql/test/library-tests/path-resolution/main.rs +++ b/rust/ql/test/library-tests/path-resolution/main.rs @@ -798,8 +798,7 @@ fn main() { m23::f(); // $ item=I108 m24::f(); // $ item=I121 zelf::h(); // $ item=I25 - z_changed(); // $ MISSING: item=I122 - AStruct::z_on_type(); // $ MISSING: item=I124 - AStruct {} // $ item=I123 - .z_on_instance(); // MISSING: item=I125 + z_changed(); // $ item=I122 + AStruct::z_on_type(); // $ item=I124 + AStruct {}.z_on_instance(); // $ item=I123 item=I125 } diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected index 067365a5386..7c30ebc4a1e 100644 --- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected +++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected @@ -66,7 +66,7 @@ resolvePath | main.rs:36:17:36:21 | super | main.rs:24:5:42:5 | mod m2 | | main.rs:36:17:36:24 | ...::f | main.rs:25:9:27:9 | fn f | | main.rs:39:17:39:17 | f | main.rs:25:9:27:9 | fn f | -| main.rs:46:9:46:13 | super | main.rs:1:1:805:2 | SourceFile | +| main.rs:46:9:46:13 | super | main.rs:1:1:804:2 | SourceFile | | main.rs:46:9:46:17 | ...::m1 | main.rs:19:1:43:1 | mod m1 | | main.rs:46:9:46:21 | ...::m2 | main.rs:24:5:42:5 | mod m2 | | main.rs:46:9:46:24 | ...::g | main.rs:29:9:33:9 | fn g | @@ -78,7 +78,7 @@ resolvePath | main.rs:67:17:67:19 | Foo | main.rs:65:9:65:21 | struct Foo | | main.rs:70:13:70:15 | Foo | main.rs:59:5:59:17 | struct Foo | | main.rs:72:5:72:5 | f | main.rs:61:5:68:5 | fn f | -| main.rs:74:5:74:8 | self | main.rs:1:1:805:2 | SourceFile | +| main.rs:74:5:74:8 | self | main.rs:1:1:804:2 | SourceFile | | main.rs:74:5:74:11 | ...::i | main.rs:77:1:89:1 | fn i | | main.rs:80:13:80:15 | Foo | main.rs:54:1:54:13 | struct Foo | | main.rs:84:16:84:18 | i32 | {EXTERNAL LOCATION} | struct i32 | @@ -93,7 +93,7 @@ resolvePath | main.rs:93:57:93:66 | ...::g | my2/nested2.rs:7:9:9:9 | fn g | | main.rs:93:80:93:86 | nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | | main.rs:106:5:106:22 | f_defined_in_macro | main.rs:105:18:105:42 | fn f_defined_in_macro | -| main.rs:123:13:123:17 | super | main.rs:1:1:805:2 | SourceFile | +| main.rs:123:13:123:17 | super | main.rs:1:1:804:2 | SourceFile | | main.rs:123:13:123:21 | ...::m5 | main.rs:109:1:113:1 | mod m5 | | main.rs:124:9:124:9 | f | main.rs:110:5:112:5 | fn f | | main.rs:124:9:124:9 | f | main.rs:116:5:118:5 | fn f | @@ -412,7 +412,9 @@ resolvePath | main.rs:799:5:799:10 | ...::f | main.rs:681:5:694:5 | fn f | | main.rs:800:5:800:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) | | main.rs:800:5:800:11 | ...::h | main.rs:56:1:75:1 | fn h | +| main.rs:801:5:801:13 | z_changed | main.rs:700:1:700:8 | fn z_changed | | main.rs:802:5:802:11 | AStruct | main.rs:702:1:702:17 | struct AStruct | +| main.rs:802:5:802:22 | ...::z_on_type | main.rs:706:5:706:16 | fn z_on_type | | main.rs:803:5:803:11 | AStruct | main.rs:702:1:702:17 | struct AStruct | | my2/mod.rs:5:5:5:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | | my2/mod.rs:5:5:5:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | @@ -434,7 +436,7 @@ resolvePath | my2/my3/mod.rs:3:5:3:5 | g | my2/mod.rs:3:1:6:1 | fn g | | my2/my3/mod.rs:4:5:4:5 | h | main.rs:56:1:75:1 | fn h | | my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | -| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:805:2 | SourceFile | +| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:804:2 | SourceFile | | my2/my3/mod.rs:7:5:7:19 | ...::h | main.rs:56:1:75:1 | fn h | | my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | | my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g | From 2c84b49cede939e5f935213890910c0ad87d7643 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 17 Sep 2025 15:58:54 +0200 Subject: [PATCH 042/160] Rust: Update test expecations --- .../security/CWE-696/BadCTorInitialization.expected | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected index 3ac74a3cb13..ed95a8d448a 100644 --- a/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected +++ b/rust/ql/test/query-tests/security/CWE-696/BadCTorInitialization.expected @@ -59,13 +59,11 @@ edges | test.rs:129:4:130:21 | fn bad3_1 | test.rs:130:5:130:19 | call_target3_1(...) | | test.rs:130:5:130:19 | call_target3_1(...) | test.rs:124:1:126:1 | fn call_target3_1 | | test.rs:144:1:144:7 | Attr | test.rs:145:4:147:21 | fn bad3_3 | -| test.rs:144:1:148:1 | fn bad3_3 | test.rs:146:5:146:20 | call_target3_1(...) | | test.rs:145:4:147:21 | fn bad3_3 | test.rs:146:5:146:19 | call_target3_1(...) | | test.rs:146:5:146:19 | call_target3_1(...) | test.rs:124:1:126:1 | fn call_target3_1 | -| test.rs:146:5:146:20 | call_target3_1(...) | test.rs:124:1:126:1 | fn call_target3_1 | | test.rs:150:1:150:7 | Attr | test.rs:151:4:152:13 | fn bad3_4 | | test.rs:151:4:152:13 | fn bad3_4 | test.rs:152:5:152:11 | bad3_3(...) | -| test.rs:152:5:152:11 | bad3_3(...) | test.rs:144:1:148:1 | fn bad3_3 | +| test.rs:152:5:152:11 | bad3_3(...) | test.rs:145:4:147:21 | fn bad3_3 | | test.rs:168:1:168:7 | Attr | test.rs:169:4:170:16 | fn bad4_1 | | test.rs:169:4:170:16 | fn bad4_1 | test.rs:168:1:168:7 | ... .write(...) | | test.rs:169:4:170:16 | fn bad4_1 | test.rs:168:1:168:7 | ...::stdout(...) | From a9d7662bb7a20a08bdc794bc67c1d10f60c5f3f9 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 19 Sep 2025 13:09:07 +0200 Subject: [PATCH 043/160] Rust: Add path resolution test with attribute on impl block --- .../library-tests/path-resolution/main.rs | 22 +++ .../path-resolution/path-resolution.expected | 161 ++++++++++-------- .../path-resolution/proc_macro.rs | 8 +- 3 files changed, 116 insertions(+), 75 deletions(-) diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs index 1ad55d36ad4..42107ec5fd4 100644 --- a/rust/ql/test/library-tests/path-resolution/main.rs +++ b/rust/ql/test/library-tests/path-resolution/main.rs @@ -767,6 +767,27 @@ use std::{self as ztd}; // $ item=std fn use_ztd(x: ztd::string::String) {} // $ item=String +#[rustfmt::skip] +mod impl_with_attribute_macro { + struct Foo; // IFoo + + trait ATrait { + type Foo; + } // IATrait + + #[proc_macro::identity] // $ item=identity + impl ATrait for i64 { // $ item=IATrait item=i64 + type Foo = + i64 // $ item=i64 + ; // IATrait_i64_Foo + } + + pub fn test() { + // This should resolve to the struct, not the associated type. + let _x: Foo; // $ item=IFoo SPURIOUS: item=IATrait_i64_Foo + } // impl_with_attribute_macro::test +} + fn main() { my::nested::nested1::nested2::f(); // $ item=I4 my::f(); // $ item=I38 @@ -801,4 +822,5 @@ fn main() { z_changed(); // $ item=I122 AStruct::z_on_type(); // $ item=I124 AStruct {}.z_on_instance(); // $ item=I123 item=I125 + impl_with_attribute_macro::test(); // $ item=impl_with_attribute_macro::test } diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected index 7c30ebc4a1e..e9bb668f681 100644 --- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected +++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected @@ -31,6 +31,7 @@ mod | main.rs:600:1:625:1 | mod m23 | | main.rs:627:1:695:1 | mod m24 | | main.rs:712:1:764:1 | mod associated_types | +| main.rs:770:1:789:1 | mod impl_with_attribute_macro | | my2/mod.rs:1:1:1:16 | mod nested2 | | my2/mod.rs:18:1:18:12 | mod my3 | | my2/mod.rs:20:1:21:10 | mod mymod | @@ -66,7 +67,7 @@ resolvePath | main.rs:36:17:36:21 | super | main.rs:24:5:42:5 | mod m2 | | main.rs:36:17:36:24 | ...::f | main.rs:25:9:27:9 | fn f | | main.rs:39:17:39:17 | f | main.rs:25:9:27:9 | fn f | -| main.rs:46:9:46:13 | super | main.rs:1:1:804:2 | SourceFile | +| main.rs:46:9:46:13 | super | main.rs:1:1:826:2 | SourceFile | | main.rs:46:9:46:17 | ...::m1 | main.rs:19:1:43:1 | mod m1 | | main.rs:46:9:46:21 | ...::m2 | main.rs:24:5:42:5 | mod m2 | | main.rs:46:9:46:24 | ...::g | main.rs:29:9:33:9 | fn g | @@ -78,7 +79,7 @@ resolvePath | main.rs:67:17:67:19 | Foo | main.rs:65:9:65:21 | struct Foo | | main.rs:70:13:70:15 | Foo | main.rs:59:5:59:17 | struct Foo | | main.rs:72:5:72:5 | f | main.rs:61:5:68:5 | fn f | -| main.rs:74:5:74:8 | self | main.rs:1:1:804:2 | SourceFile | +| main.rs:74:5:74:8 | self | main.rs:1:1:826:2 | SourceFile | | main.rs:74:5:74:11 | ...::i | main.rs:77:1:89:1 | fn i | | main.rs:80:13:80:15 | Foo | main.rs:54:1:54:13 | struct Foo | | main.rs:84:16:84:18 | i32 | {EXTERNAL LOCATION} | struct i32 | @@ -93,7 +94,7 @@ resolvePath | main.rs:93:57:93:66 | ...::g | my2/nested2.rs:7:9:9:9 | fn g | | main.rs:93:80:93:86 | nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | | main.rs:106:5:106:22 | f_defined_in_macro | main.rs:105:18:105:42 | fn f_defined_in_macro | -| main.rs:123:13:123:17 | super | main.rs:1:1:804:2 | SourceFile | +| main.rs:123:13:123:17 | super | main.rs:1:1:826:2 | SourceFile | | main.rs:123:13:123:21 | ...::m5 | main.rs:109:1:113:1 | mod m5 | | main.rs:124:9:124:9 | f | main.rs:110:5:112:5 | fn f | | main.rs:124:9:124:9 | f | main.rs:116:5:118:5 | fn f | @@ -303,12 +304,12 @@ resolvePath | main.rs:693:9:693:47 | ...::call_both | main.rs:659:9:662:9 | fn call_both | | main.rs:693:25:693:35 | Implementor | main.rs:665:5:665:23 | struct Implementor | | main.rs:699:3:699:12 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) | -| main.rs:699:3:699:24 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix | +| main.rs:699:3:699:24 | ...::add_suffix | proc_macro.rs:4:1:13:1 | fn add_suffix | | main.rs:703:6:703:12 | AStruct | main.rs:702:1:702:17 | struct AStruct | | main.rs:705:7:705:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) | -| main.rs:705:7:705:28 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix | +| main.rs:705:7:705:28 | ...::add_suffix | proc_macro.rs:4:1:13:1 | fn add_suffix | | main.rs:708:7:708:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) | -| main.rs:708:7:708:28 | ...::add_suffix | proc_macro.rs:4:1:12:1 | fn add_suffix | +| main.rs:708:7:708:28 | ...::add_suffix | proc_macro.rs:4:1:13:1 | fn add_suffix | | main.rs:713:9:713:11 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) | | main.rs:713:9:713:19 | ...::marker | {EXTERNAL LOCATION} | mod marker | | main.rs:713:9:713:32 | ...::PhantomData | {EXTERNAL LOCATION} | struct PhantomData | @@ -349,73 +350,82 @@ resolvePath | main.rs:768:15:768:17 | ztd | {EXTERNAL LOCATION} | Crate(std@0.0.0) | | main.rs:768:15:768:25 | ...::string | {EXTERNAL LOCATION} | mod string | | main.rs:768:15:768:33 | ...::String | {EXTERNAL LOCATION} | struct String | -| main.rs:771:5:771:6 | my | main.rs:1:1:1:7 | mod my | -| main.rs:771:5:771:14 | ...::nested | my.rs:1:1:1:15 | mod nested | -| main.rs:771:5:771:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 | -| main.rs:771:5:771:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 | -| main.rs:771:5:771:35 | ...::f | my/nested.rs:3:9:5:9 | fn f | -| main.rs:772:5:772:6 | my | main.rs:1:1:1:7 | mod my | -| main.rs:772:5:772:9 | ...::f | my.rs:5:1:7:1 | fn f | -| main.rs:773:5:773:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | -| main.rs:773:5:773:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | -| main.rs:773:5:773:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | -| main.rs:773:5:773:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:774:5:774:5 | f | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:775:5:775:5 | g | my2/nested2.rs:7:9:9:9 | fn g | -| main.rs:776:5:776:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) | -| main.rs:776:5:776:12 | ...::h | main.rs:56:1:75:1 | fn h | -| main.rs:777:5:777:6 | m1 | main.rs:19:1:43:1 | mod m1 | -| main.rs:777:5:777:10 | ...::m2 | main.rs:24:5:42:5 | mod m2 | -| main.rs:777:5:777:13 | ...::g | main.rs:29:9:33:9 | fn g | -| main.rs:778:5:778:6 | m1 | main.rs:19:1:43:1 | mod m1 | -| main.rs:778:5:778:10 | ...::m2 | main.rs:24:5:42:5 | mod m2 | -| main.rs:778:5:778:14 | ...::m3 | main.rs:35:9:41:9 | mod m3 | -| main.rs:778:5:778:17 | ...::h | main.rs:36:27:40:13 | fn h | -| main.rs:779:5:779:6 | m4 | main.rs:45:1:52:1 | mod m4 | -| main.rs:779:5:779:9 | ...::i | main.rs:48:5:51:5 | fn i | -| main.rs:780:5:780:5 | h | main.rs:56:1:75:1 | fn h | -| main.rs:781:5:781:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f | -| main.rs:782:5:782:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g | -| main.rs:783:5:783:5 | j | main.rs:103:1:107:1 | fn j | -| main.rs:784:5:784:6 | m6 | main.rs:115:1:126:1 | mod m6 | -| main.rs:784:5:784:9 | ...::g | main.rs:120:5:125:5 | fn g | -| main.rs:785:5:785:6 | m7 | main.rs:128:1:147:1 | mod m7 | -| main.rs:785:5:785:9 | ...::f | main.rs:139:5:146:5 | fn f | -| main.rs:786:5:786:6 | m8 | main.rs:149:1:203:1 | mod m8 | -| main.rs:786:5:786:9 | ...::g | main.rs:187:5:202:5 | fn g | -| main.rs:787:5:787:6 | m9 | main.rs:205:1:213:1 | mod m9 | -| main.rs:787:5:787:9 | ...::f | main.rs:208:5:212:5 | fn f | -| main.rs:788:5:788:7 | m11 | main.rs:236:1:273:1 | mod m11 | -| main.rs:788:5:788:10 | ...::f | main.rs:241:5:244:5 | fn f | -| main.rs:789:5:789:7 | m15 | main.rs:304:1:373:1 | mod m15 | -| main.rs:789:5:789:10 | ...::f | main.rs:360:5:372:5 | fn f | -| main.rs:790:5:790:7 | m16 | main.rs:375:1:467:1 | mod m16 | -| main.rs:790:5:790:10 | ...::f | main.rs:442:5:466:5 | fn f | -| main.rs:791:5:791:20 | trait_visibility | main.rs:469:1:519:1 | mod trait_visibility | -| main.rs:791:5:791:23 | ...::f | main.rs:496:5:518:5 | fn f | -| main.rs:792:5:792:7 | m17 | main.rs:521:1:551:1 | mod m17 | -| main.rs:792:5:792:10 | ...::f | main.rs:545:5:550:5 | fn f | -| main.rs:793:5:793:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 | -| main.rs:793:5:793:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f | -| main.rs:794:5:794:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 | -| main.rs:794:5:794:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f | -| main.rs:795:5:795:7 | my3 | my2/mod.rs:18:1:18:12 | mod my3 | -| main.rs:795:5:795:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f | -| main.rs:796:5:796:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f | -| main.rs:797:5:797:7 | m18 | main.rs:553:1:571:1 | mod m18 | -| main.rs:797:5:797:12 | ...::m19 | main.rs:558:5:570:5 | mod m19 | -| main.rs:797:5:797:17 | ...::m20 | main.rs:563:9:569:9 | mod m20 | -| main.rs:797:5:797:20 | ...::g | main.rs:564:13:568:13 | fn g | -| main.rs:798:5:798:7 | m23 | main.rs:600:1:625:1 | mod m23 | -| main.rs:798:5:798:10 | ...::f | main.rs:620:5:624:5 | fn f | -| main.rs:799:5:799:7 | m24 | main.rs:627:1:695:1 | mod m24 | -| main.rs:799:5:799:10 | ...::f | main.rs:681:5:694:5 | fn f | -| main.rs:800:5:800:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) | -| main.rs:800:5:800:11 | ...::h | main.rs:56:1:75:1 | fn h | -| main.rs:801:5:801:13 | z_changed | main.rs:700:1:700:8 | fn z_changed | -| main.rs:802:5:802:11 | AStruct | main.rs:702:1:702:17 | struct AStruct | -| main.rs:802:5:802:22 | ...::z_on_type | main.rs:706:5:706:16 | fn z_on_type | -| main.rs:803:5:803:11 | AStruct | main.rs:702:1:702:17 | struct AStruct | +| main.rs:778:7:778:16 | proc_macro | proc_macro.rs:0:0:0:0 | Crate(proc_macro@0.0.1) | +| main.rs:778:7:778:26 | ...::identity | proc_macro.rs:15:1:18:1 | fn identity | +| main.rs:779:10:779:15 | ATrait | main.rs:774:5:776:5 | trait ATrait | +| main.rs:779:21:779:23 | i64 | {EXTERNAL LOCATION} | struct i64 | +| main.rs:781:11:781:13 | i64 | {EXTERNAL LOCATION} | struct i64 | +| main.rs:787:17:787:19 | Foo | main.rs:772:5:772:15 | struct Foo | +| main.rs:787:17:787:19 | Foo | main.rs:779:27:782:9 | type Foo | +| main.rs:792:5:792:6 | my | main.rs:1:1:1:7 | mod my | +| main.rs:792:5:792:14 | ...::nested | my.rs:1:1:1:15 | mod nested | +| main.rs:792:5:792:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 | +| main.rs:792:5:792:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 | +| main.rs:792:5:792:35 | ...::f | my/nested.rs:3:9:5:9 | fn f | +| main.rs:793:5:793:6 | my | main.rs:1:1:1:7 | mod my | +| main.rs:793:5:793:9 | ...::f | my.rs:5:1:7:1 | fn f | +| main.rs:794:5:794:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | +| main.rs:794:5:794:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | +| main.rs:794:5:794:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | +| main.rs:794:5:794:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:795:5:795:5 | f | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:796:5:796:5 | g | my2/nested2.rs:7:9:9:9 | fn g | +| main.rs:797:5:797:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) | +| main.rs:797:5:797:12 | ...::h | main.rs:56:1:75:1 | fn h | +| main.rs:798:5:798:6 | m1 | main.rs:19:1:43:1 | mod m1 | +| main.rs:798:5:798:10 | ...::m2 | main.rs:24:5:42:5 | mod m2 | +| main.rs:798:5:798:13 | ...::g | main.rs:29:9:33:9 | fn g | +| main.rs:799:5:799:6 | m1 | main.rs:19:1:43:1 | mod m1 | +| main.rs:799:5:799:10 | ...::m2 | main.rs:24:5:42:5 | mod m2 | +| main.rs:799:5:799:14 | ...::m3 | main.rs:35:9:41:9 | mod m3 | +| main.rs:799:5:799:17 | ...::h | main.rs:36:27:40:13 | fn h | +| main.rs:800:5:800:6 | m4 | main.rs:45:1:52:1 | mod m4 | +| main.rs:800:5:800:9 | ...::i | main.rs:48:5:51:5 | fn i | +| main.rs:801:5:801:5 | h | main.rs:56:1:75:1 | fn h | +| main.rs:802:5:802:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f | +| main.rs:803:5:803:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g | +| main.rs:804:5:804:5 | j | main.rs:103:1:107:1 | fn j | +| main.rs:805:5:805:6 | m6 | main.rs:115:1:126:1 | mod m6 | +| main.rs:805:5:805:9 | ...::g | main.rs:120:5:125:5 | fn g | +| main.rs:806:5:806:6 | m7 | main.rs:128:1:147:1 | mod m7 | +| main.rs:806:5:806:9 | ...::f | main.rs:139:5:146:5 | fn f | +| main.rs:807:5:807:6 | m8 | main.rs:149:1:203:1 | mod m8 | +| main.rs:807:5:807:9 | ...::g | main.rs:187:5:202:5 | fn g | +| main.rs:808:5:808:6 | m9 | main.rs:205:1:213:1 | mod m9 | +| main.rs:808:5:808:9 | ...::f | main.rs:208:5:212:5 | fn f | +| main.rs:809:5:809:7 | m11 | main.rs:236:1:273:1 | mod m11 | +| main.rs:809:5:809:10 | ...::f | main.rs:241:5:244:5 | fn f | +| main.rs:810:5:810:7 | m15 | main.rs:304:1:373:1 | mod m15 | +| main.rs:810:5:810:10 | ...::f | main.rs:360:5:372:5 | fn f | +| main.rs:811:5:811:7 | m16 | main.rs:375:1:467:1 | mod m16 | +| main.rs:811:5:811:10 | ...::f | main.rs:442:5:466:5 | fn f | +| main.rs:812:5:812:20 | trait_visibility | main.rs:469:1:519:1 | mod trait_visibility | +| main.rs:812:5:812:23 | ...::f | main.rs:496:5:518:5 | fn f | +| main.rs:813:5:813:7 | m17 | main.rs:521:1:551:1 | mod m17 | +| main.rs:813:5:813:10 | ...::f | main.rs:545:5:550:5 | fn f | +| main.rs:814:5:814:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 | +| main.rs:814:5:814:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f | +| main.rs:815:5:815:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 | +| main.rs:815:5:815:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f | +| main.rs:816:5:816:7 | my3 | my2/mod.rs:18:1:18:12 | mod my3 | +| main.rs:816:5:816:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f | +| main.rs:817:5:817:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f | +| main.rs:818:5:818:7 | m18 | main.rs:553:1:571:1 | mod m18 | +| main.rs:818:5:818:12 | ...::m19 | main.rs:558:5:570:5 | mod m19 | +| main.rs:818:5:818:17 | ...::m20 | main.rs:563:9:569:9 | mod m20 | +| main.rs:818:5:818:20 | ...::g | main.rs:564:13:568:13 | fn g | +| main.rs:819:5:819:7 | m23 | main.rs:600:1:625:1 | mod m23 | +| main.rs:819:5:819:10 | ...::f | main.rs:620:5:624:5 | fn f | +| main.rs:820:5:820:7 | m24 | main.rs:627:1:695:1 | mod m24 | +| main.rs:820:5:820:10 | ...::f | main.rs:681:5:694:5 | fn f | +| main.rs:821:5:821:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) | +| main.rs:821:5:821:11 | ...::h | main.rs:56:1:75:1 | fn h | +| main.rs:822:5:822:13 | z_changed | main.rs:700:1:700:8 | fn z_changed | +| main.rs:823:5:823:11 | AStruct | main.rs:702:1:702:17 | struct AStruct | +| main.rs:823:5:823:22 | ...::z_on_type | main.rs:706:5:706:16 | fn z_on_type | +| main.rs:824:5:824:11 | AStruct | main.rs:702:1:702:17 | struct AStruct | +| main.rs:825:5:825:29 | impl_with_attribute_macro | main.rs:770:1:789:1 | mod impl_with_attribute_macro | +| main.rs:825:5:825:35 | ...::test | main.rs:785:5:788:5 | fn test | | my2/mod.rs:5:5:5:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 | | my2/mod.rs:5:5:5:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 | | my2/mod.rs:5:5:5:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 | @@ -436,7 +446,7 @@ resolvePath | my2/my3/mod.rs:3:5:3:5 | g | my2/mod.rs:3:1:6:1 | fn g | | my2/my3/mod.rs:4:5:4:5 | h | main.rs:56:1:75:1 | fn h | | my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | -| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:804:2 | SourceFile | +| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:826:2 | SourceFile | | my2/my3/mod.rs:7:5:7:19 | ...::h | main.rs:56:1:75:1 | fn h | | my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | | my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g | @@ -482,4 +492,7 @@ resolvePath | proc_macro.rs:8:21:8:23 | syn | {EXTERNAL LOCATION} | Crate(syn@2.0.103) | | proc_macro.rs:8:21:8:30 | ...::Ident | {EXTERNAL LOCATION} | struct Ident | | proc_macro.rs:8:21:8:35 | ...::new | {EXTERNAL LOCATION} | fn new | +| proc_macro.rs:16:24:16:34 | TokenStream | {EXTERNAL LOCATION} | struct TokenStream | +| proc_macro.rs:16:43:16:53 | TokenStream | {EXTERNAL LOCATION} | struct TokenStream | +| proc_macro.rs:16:59:16:69 | TokenStream | {EXTERNAL LOCATION} | struct TokenStream | testFailures diff --git a/rust/ql/test/library-tests/path-resolution/proc_macro.rs b/rust/ql/test/library-tests/path-resolution/proc_macro.rs index c95fc6fe640..11e3a7024ae 100644 --- a/rust/ql/test/library-tests/path-resolution/proc_macro.rs +++ b/rust/ql/test/library-tests/path-resolution/proc_macro.rs @@ -8,5 +8,11 @@ pub fn add_suffix(attr: TokenStream, item: TokenStream) -> TokenStream { ast.sig.ident = syn::Ident::new(&format!("{}_{}", ast.sig.ident, suff), ast.sig.ident.span()); quote! { #ast - }.into() + } + .into() +} + +#[proc_macro_attribute] +pub fn identity(_attr: TokenStream, item: TokenStream) -> TokenStream { + item } From d88bc8e4086b3d90e80601b8489ed521c3cacdb2 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Fri, 19 Sep 2025 14:23:40 +0200 Subject: [PATCH 044/160] JS: Add test case for `GraphQLObjectType` --- .../CWE-094/CodeInjection/graph-ql.js | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/graph-ql.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/graph-ql.js index f68f47cf3ac..c4b68e16990 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/graph-ql.js +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/graph-ql.js @@ -1,5 +1,5 @@ const express = require('express'); -const { graphql, buildSchema } = require('graphql'); +const { graphql, buildSchema, GraphQLObjectType, GraphQLString } = require('graphql'); const app = express(); app.use(express.json()); @@ -53,4 +53,30 @@ app.post('/graphql', async (req, res) => { rootValue: root1, variableValues: variables }); + + const MutationType = new GraphQLObjectType({ + name: 'Mutation', + fields: { + runEval: { + type: GraphQLString, + args: { + value: { type: GraphQLString } + }, + resolve: (_, { value }, context) => { // $ MISSING: Source[js/code-injection] + return eval(value); // $ MISSING: Alert[js/code-injection] + } + } + } + }); + + const schema = new GraphQLSchema({ + query: QueryType, + mutation: MutationType + }); + + await graphql({ + schema, + source: query, + variableValues: variables + }); }); From 60ceb89f01be59ecba08fc972d5a9bdd84e11ff2 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 19 Sep 2025 13:26:36 +0200 Subject: [PATCH 045/160] Rust: Add debug predicate for `ItemNode` --- rust/ql/lib/codeql/rust/internal/PathResolution.qll | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 980033811dd..6b7df0db58a 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -1807,6 +1807,8 @@ private module Debug { path = p.toStringDebug() } + predicate debugItemNode(ItemNode item) { item = getRelevantLocatable() } + ItemNode debugResolvePath(RelevantPath path) { path = getRelevantLocatable() and result = resolvePath(path) From 72103adacc7cf9712acd464a38adebeb240d5fb5 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 19 Sep 2025 13:27:02 +0200 Subject: [PATCH 046/160] Rust: Fix spurious path resolution The annotated impl block was filtered away, but it's children where not. This caused the associated type `Foo` to appear as if it was an item in the scope outside of the impl block. --- .../codeql/rust/internal/PathResolution.qll | 20 ++++++++++++++++++- .../library-tests/path-resolution/main.rs | 2 +- .../path-resolution/path-resolution.expected | 1 - 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 6b7df0db58a..46197b6189e 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -78,6 +78,24 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki ) } +/** + * Holds if `n` is superceded by an attribute macro expansion. That is, `n` is + * an item or a transitive child of an item with an attribute macro expansion. + */ +predicate supercededByAttributeMacroExpansion(AstNode n) { + n.(Item).hasAttributeMacroExpansion() + or + exists(AstNode parent | + n.getParentNode() = parent and + supercededByAttributeMacroExpansion(parent) and + // Don't exclude expansions themselves as they supercede other nodes. + not n = parent.(Item).getAttributeMacroExpansion() and + // Don't consider attributes themselves to be superceded. E.g., in `#[a] fn + // f() {}` the macro expansion supercedes `fn f() {}` but not `#[a]`. + not n instanceof Attr + ) +} + /** * An item that may be referred to by a path, and which is a node in * the _item graph_. @@ -158,7 +176,7 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki abstract class ItemNode extends Locatable { ItemNode() { // Exclude items that are superceded by the expansion of an attribute macro. - not this.(Item).hasAttributeMacroExpansion() + not supercededByAttributeMacroExpansion(this) } /** Gets the (original) name of this item. */ diff --git a/rust/ql/test/library-tests/path-resolution/main.rs b/rust/ql/test/library-tests/path-resolution/main.rs index 42107ec5fd4..9051f7f8412 100644 --- a/rust/ql/test/library-tests/path-resolution/main.rs +++ b/rust/ql/test/library-tests/path-resolution/main.rs @@ -784,7 +784,7 @@ mod impl_with_attribute_macro { pub fn test() { // This should resolve to the struct, not the associated type. - let _x: Foo; // $ item=IFoo SPURIOUS: item=IATrait_i64_Foo + let _x: Foo; // $ item=IFoo } // impl_with_attribute_macro::test } diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected index e9bb668f681..a908ec1e5c1 100644 --- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected +++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected @@ -356,7 +356,6 @@ resolvePath | main.rs:779:21:779:23 | i64 | {EXTERNAL LOCATION} | struct i64 | | main.rs:781:11:781:13 | i64 | {EXTERNAL LOCATION} | struct i64 | | main.rs:787:17:787:19 | Foo | main.rs:772:5:772:15 | struct Foo | -| main.rs:787:17:787:19 | Foo | main.rs:779:27:782:9 | type Foo | | main.rs:792:5:792:6 | my | main.rs:1:1:1:7 | mod my | | main.rs:792:5:792:14 | ...::nested | my.rs:1:1:1:15 | mod nested | | main.rs:792:5:792:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 | From afb6d307624ce482bf7f6f09c18b29353829bd34 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 19 Sep 2025 14:27:14 +0200 Subject: [PATCH 047/160] Rust: Fix typo in superseded --- rust/ql/lib/codeql/rust/internal/PathResolution.qll | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 46197b6189e..44e8b452255 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -79,18 +79,18 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki } /** - * Holds if `n` is superceded by an attribute macro expansion. That is, `n` is + * Holds if `n` is superseded by an attribute macro expansion. That is, `n` is * an item or a transitive child of an item with an attribute macro expansion. */ -predicate supercededByAttributeMacroExpansion(AstNode n) { +predicate supersededByAttributeMacroExpansion(AstNode n) { n.(Item).hasAttributeMacroExpansion() or exists(AstNode parent | n.getParentNode() = parent and - supercededByAttributeMacroExpansion(parent) and + supersededByAttributeMacroExpansion(parent) and // Don't exclude expansions themselves as they supercede other nodes. not n = parent.(Item).getAttributeMacroExpansion() and - // Don't consider attributes themselves to be superceded. E.g., in `#[a] fn + // Don't consider attributes themselves to be superseded. E.g., in `#[a] fn // f() {}` the macro expansion supercedes `fn f() {}` but not `#[a]`. not n instanceof Attr ) @@ -175,8 +175,8 @@ predicate supercededByAttributeMacroExpansion(AstNode n) { */ abstract class ItemNode extends Locatable { ItemNode() { - // Exclude items that are superceded by the expansion of an attribute macro. - not supercededByAttributeMacroExpansion(this) + // Exclude items that are superseded by the expansion of an attribute macro. + not supersededByAttributeMacroExpansion(this) } /** Gets the (original) name of this item. */ From 6cfc95015921ab781e16f36ac2ba5ba9a57187ae Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Fri, 19 Sep 2025 14:39:36 +0200 Subject: [PATCH 048/160] JS: Model `GraphQLObjectType` resolve params as sources --- javascript/ql/lib/ext/graph-ql.model.yml | 5 +++++ .../Security/CWE-094/CodeInjection/CodeInjection.expected | 6 ++++++ .../CodeInjection/HeuristicSourceCodeInjection.expected | 5 +++++ .../query-tests/Security/CWE-094/CodeInjection/graph-ql.js | 4 ++-- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/javascript/ql/lib/ext/graph-ql.model.yml b/javascript/ql/lib/ext/graph-ql.model.yml index 08233d1135d..2ea1c41ed9f 100644 --- a/javascript/ql/lib/ext/graph-ql.model.yml +++ b/javascript/ql/lib/ext/graph-ql.model.yml @@ -4,3 +4,8 @@ extensions: extensible: summaryModel data: - ["graphql", "Member[graphql]", "Argument[0].Member[source,variableValues]", "Argument[0].Member[rootValue].AnyMember.Parameter[0]", "taint"] + - addsTo: + pack: codeql/javascript-all + extensible: sourceModel + data: + - ["graphql", "Member[GraphQLObjectType].Argument[0].Member[fields].AnyMember.Member[resolve].Parameter[1]", "remote"] diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected index 3f5d8abed8a..fb3e4ad6e6a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/CodeInjection.expected @@ -63,6 +63,7 @@ | fastify.js:108:28:108:50 | reply.l ... tedCode | fastify.js:94:29:94:51 | request ... plyCode | fastify.js:108:28:108:50 | reply.l ... tedCode | This code execution depends on a $@. | fastify.js:94:29:94:51 | request ... plyCode | user-provided value | | graph-ql.js:20:19:20:22 | expr | graph-ql.js:28:32:28:39 | req.body | graph-ql.js:20:19:20:22 | expr | This code execution depends on a $@. | graph-ql.js:28:32:28:39 | req.body | user-provided value | | graph-ql.js:39:19:39:30 | name + title | graph-ql.js:28:32:28:39 | req.body | graph-ql.js:39:19:39:30 | name + title | This code execution depends on a $@. | graph-ql.js:28:32:28:39 | req.body | user-provided value | +| graph-ql.js:66:23:66:27 | value | graph-ql.js:65:22:65:30 | { value } | graph-ql.js:66:23:66:27 | value | This code execution depends on a $@. | graph-ql.js:65:22:65:30 | { value } | user-provided value | | module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code | module.js:9:16:9:29 | req.query.code | This code execution depends on a $@. | module.js:9:16:9:29 | req.query.code | user-provided value | | module.js:11:17:11:30 | req.query.code | module.js:11:17:11:30 | req.query.code | module.js:11:17:11:30 | req.query.code | This code execution depends on a $@. | module.js:11:17:11:30 | req.query.code | user-provided value | | react-native.js:8:32:8:38 | tainted | react-native.js:7:17:7:33 | req.param("code") | react-native.js:8:32:8:38 | tainted | This code execution depends on a $@. | react-native.js:7:17:7:33 | req.param("code") | user-provided value | @@ -173,6 +174,8 @@ edges | graph-ql.js:39:19:39:22 | name | graph-ql.js:39:19:39:30 | name + title | provenance | | | graph-ql.js:39:26:39:30 | title | graph-ql.js:39:19:39:30 | name + title | provenance | | | graph-ql.js:54:21:54:29 | variables | graph-ql.js:38:13:38:27 | { name, title } | provenance | | +| graph-ql.js:65:22:65:30 | { value } | graph-ql.js:65:24:65:28 | value | provenance | | +| graph-ql.js:65:24:65:28 | value | graph-ql.js:66:23:66:27 | value | provenance | | | react-native.js:7:7:7:13 | tainted | react-native.js:8:32:8:38 | tainted | provenance | | | react-native.js:7:7:7:13 | tainted | react-native.js:10:23:10:29 | tainted | provenance | | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:13 | tainted | provenance | | @@ -323,6 +326,9 @@ nodes | graph-ql.js:39:19:39:30 | name + title | semmle.label | name + title | | graph-ql.js:39:26:39:30 | title | semmle.label | title | | graph-ql.js:54:21:54:29 | variables | semmle.label | variables | +| graph-ql.js:65:22:65:30 | { value } | semmle.label | { value } | +| graph-ql.js:65:24:65:28 | value | semmle.label | value | +| graph-ql.js:66:23:66:27 | value | semmle.label | value | | module.js:9:16:9:29 | req.query.code | semmle.label | req.query.code | | module.js:11:17:11:30 | req.query.code | semmle.label | req.query.code | | react-native.js:7:7:7:13 | tainted | semmle.label | tainted | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected index 3d4022d8fb6..837ae37eaee 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/HeuristicSourceCodeInjection.expected @@ -72,6 +72,8 @@ edges | graph-ql.js:39:19:39:22 | name | graph-ql.js:39:19:39:30 | name + title | provenance | | | graph-ql.js:39:26:39:30 | title | graph-ql.js:39:19:39:30 | name + title | provenance | | | graph-ql.js:54:21:54:29 | variables | graph-ql.js:38:13:38:27 | { name, title } | provenance | | +| graph-ql.js:65:22:65:30 | { value } | graph-ql.js:65:24:65:28 | value | provenance | | +| graph-ql.js:65:24:65:28 | value | graph-ql.js:66:23:66:27 | value | provenance | | | react-native.js:7:7:7:13 | tainted | react-native.js:8:32:8:38 | tainted | provenance | | | react-native.js:7:7:7:13 | tainted | react-native.js:10:23:10:29 | tainted | provenance | | | react-native.js:7:17:7:33 | req.param("code") | react-native.js:7:7:7:13 | tainted | provenance | | @@ -224,6 +226,9 @@ nodes | graph-ql.js:39:19:39:30 | name + title | semmle.label | name + title | | graph-ql.js:39:26:39:30 | title | semmle.label | title | | graph-ql.js:54:21:54:29 | variables | semmle.label | variables | +| graph-ql.js:65:22:65:30 | { value } | semmle.label | { value } | +| graph-ql.js:65:24:65:28 | value | semmle.label | value | +| graph-ql.js:66:23:66:27 | value | semmle.label | value | | module.js:9:16:9:29 | req.query.code | semmle.label | req.query.code | | module.js:11:17:11:30 | req.query.code | semmle.label | req.query.code | | react-native.js:7:7:7:13 | tainted | semmle.label | tainted | diff --git a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/graph-ql.js b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/graph-ql.js index c4b68e16990..167292330d2 100644 --- a/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/graph-ql.js +++ b/javascript/ql/test/query-tests/Security/CWE-094/CodeInjection/graph-ql.js @@ -62,8 +62,8 @@ app.post('/graphql', async (req, res) => { args: { value: { type: GraphQLString } }, - resolve: (_, { value }, context) => { // $ MISSING: Source[js/code-injection] - return eval(value); // $ MISSING: Alert[js/code-injection] + resolve: (_, { value }, context) => { // $ Source[js/code-injection] + return eval(value); // $ Alert[js/code-injection] } } } From 3a6a537986133f24bfecbde3f2c770952e4d4642 Mon Sep 17 00:00:00 2001 From: Napalys Klicius Date: Fri, 19 Sep 2025 14:46:13 +0200 Subject: [PATCH 049/160] JS: Add change note --- .../ql/lib/change-notes/2025-09-19-graphql-type-object.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 javascript/ql/lib/change-notes/2025-09-19-graphql-type-object.md diff --git a/javascript/ql/lib/change-notes/2025-09-19-graphql-type-object.md b/javascript/ql/lib/change-notes/2025-09-19-graphql-type-object.md new file mode 100644 index 00000000000..6afa4ece331 --- /dev/null +++ b/javascript/ql/lib/change-notes/2025-09-19-graphql-type-object.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added modeling of `GraphQLObjectType` resolver function parameters as remote sources. From 95a84ad6559f4180039dac0dc07dcd1b4d7756ee Mon Sep 17 00:00:00 2001 From: Taus Date: Fri, 19 Sep 2025 15:06:46 +0000 Subject: [PATCH 050/160] Python: Fix false positive for unmatchable dollar/caret Our previous modelling did not account for the fact that a lookahead can potentially extend all the way to the end of the input (and similarly, that a lookbehind can extend all the way to the beginning). To fix this, I extended `firstPart` and `lastPart` to handle lookbehinds and lookaheads correctly, and added some test cases (all of which yield no new results). Fixes #20429. --- .../semmle/python/regexp/RegexTreeView.qll | 8 +-- .../python/regexp/internal/ParseRegExp.qll | 70 ++++++++++++------- ...atchable-dollar-and-caret-in-assertions.md | 5 ++ .../query-tests/Expressions/Regex/test.py | 10 ++- 4 files changed, 64 insertions(+), 29 deletions(-) create mode 100644 python/ql/src/change-notes/2025-09-19-fix-unmatchable-dollar-and-caret-in-assertions.md diff --git a/python/ql/lib/semmle/python/regexp/RegexTreeView.qll b/python/ql/lib/semmle/python/regexp/RegexTreeView.qll index a2952a5680b..897c97bb783 100644 --- a/python/ql/lib/semmle/python/regexp/RegexTreeView.qll +++ b/python/ql/lib/semmle/python/regexp/RegexTreeView.qll @@ -964,7 +964,7 @@ module Impl implements RegexTreeViewSig { * ``` */ class RegExpPositiveLookahead extends RegExpLookahead { - RegExpPositiveLookahead() { re.positiveLookaheadAssertionGroup(start, end) } + RegExpPositiveLookahead() { re.positiveLookaheadAssertionGroup(start, end, _, _) } override string getPrimaryQLClass() { result = "RegExpPositiveLookahead" } } @@ -979,7 +979,7 @@ module Impl implements RegexTreeViewSig { * ``` */ additional class RegExpNegativeLookahead extends RegExpLookahead { - RegExpNegativeLookahead() { re.negativeLookaheadAssertionGroup(start, end) } + RegExpNegativeLookahead() { re.negativeLookaheadAssertionGroup(start, end, _, _) } override string getPrimaryQLClass() { result = "RegExpNegativeLookahead" } } @@ -1006,7 +1006,7 @@ module Impl implements RegexTreeViewSig { * ``` */ class RegExpPositiveLookbehind extends RegExpLookbehind { - RegExpPositiveLookbehind() { re.positiveLookbehindAssertionGroup(start, end) } + RegExpPositiveLookbehind() { re.positiveLookbehindAssertionGroup(start, end, _, _) } override string getPrimaryQLClass() { result = "RegExpPositiveLookbehind" } } @@ -1021,7 +1021,7 @@ module Impl implements RegexTreeViewSig { * ``` */ additional class RegExpNegativeLookbehind extends RegExpLookbehind { - RegExpNegativeLookbehind() { re.negativeLookbehindAssertionGroup(start, end) } + RegExpNegativeLookbehind() { re.negativeLookbehindAssertionGroup(start, end, _, _) } override string getPrimaryQLClass() { result = "RegExpNegativeLookbehind" } } diff --git a/python/ql/lib/semmle/python/regexp/internal/ParseRegExp.qll b/python/ql/lib/semmle/python/regexp/internal/ParseRegExp.qll index 7e23554e058..d91c4bbd78c 100644 --- a/python/ql/lib/semmle/python/regexp/internal/ParseRegExp.qll +++ b/python/ql/lib/semmle/python/regexp/internal/ParseRegExp.qll @@ -554,9 +554,9 @@ class RegExp extends Expr instanceof StringLiteral { or this.negativeAssertionGroup(start, end) or - this.positiveLookaheadAssertionGroup(start, end) + this.positiveLookaheadAssertionGroup(start, end, _, _) or - this.positiveLookbehindAssertionGroup(start, end) + this.positiveLookbehindAssertionGroup(start, end, _, _) } /** Holds if an empty group is found between `start` and `end`. */ @@ -572,7 +572,7 @@ class RegExp extends Expr instanceof StringLiteral { or this.negativeAssertionGroup(start, end) or - this.positiveLookaheadAssertionGroup(start, end) + this.positiveLookaheadAssertionGroup(start, end, _, _) } private predicate emptyMatchAtEndGroup(int start, int end) { @@ -580,7 +580,7 @@ class RegExp extends Expr instanceof StringLiteral { or this.negativeAssertionGroup(start, end) or - this.positiveLookbehindAssertionGroup(start, end) + this.positiveLookbehindAssertionGroup(start, end, _, _) } private predicate negativeAssertionGroup(int start, int end) { @@ -593,32 +593,40 @@ class RegExp extends Expr instanceof StringLiteral { ) } - /** Holds if a negative lookahead is found between `start` and `end` */ - predicate negativeLookaheadAssertionGroup(int start, int end) { - exists(int in_start | this.negative_lookahead_assertion_start(start, in_start) | - this.groupContents(start, end, in_start, _) - ) + /** + * Holds if a negative lookahead is found between `start` and `end`, with contents + * between `in_start` and `in_end`. + */ + predicate negativeLookaheadAssertionGroup(int start, int end, int in_start, int in_end) { + this.negative_lookahead_assertion_start(start, in_start) and + this.groupContents(start, end, in_start, in_end) } - /** Holds if a negative lookbehind is found between `start` and `end` */ - predicate negativeLookbehindAssertionGroup(int start, int end) { - exists(int in_start | this.negative_lookbehind_assertion_start(start, in_start) | - this.groupContents(start, end, in_start, _) - ) + /** + * Holds if a negative lookbehind is found between `start` and `end`, with contents + * between `in_start` and `in_end`. + */ + predicate negativeLookbehindAssertionGroup(int start, int end, int in_start, int in_end) { + this.negative_lookbehind_assertion_start(start, in_start) and + this.groupContents(start, end, in_start, in_end) } - /** Holds if a positive lookahead is found between `start` and `end` */ - predicate positiveLookaheadAssertionGroup(int start, int end) { - exists(int in_start | this.lookahead_assertion_start(start, in_start) | - this.groupContents(start, end, in_start, _) - ) + /** + * Holds if a positive lookahead is found between `start` and `end`, with contents + * between `in_start` and `in_end`. + */ + predicate positiveLookaheadAssertionGroup(int start, int end, int in_start, int in_end) { + this.lookahead_assertion_start(start, in_start) and + this.groupContents(start, end, in_start, in_end) } - /** Holds if a positive lookbehind is found between `start` and `end` */ - predicate positiveLookbehindAssertionGroup(int start, int end) { - exists(int in_start | this.lookbehind_assertion_start(start, in_start) | - this.groupContents(start, end, in_start, _) - ) + /** + * Holds if a positive lookbehind is found between `start` and `end`, with contents + * between `in_start` and `in_end`. + */ + predicate positiveLookbehindAssertionGroup(int start, int end, int in_start, int in_end) { + this.lookbehind_assertion_start(start, in_start) and + this.groupContents(start, end, in_start, in_end) } private predicate group_start(int start, int end) { @@ -1049,6 +1057,13 @@ class RegExp extends Expr instanceof StringLiteral { or this.alternationOption(x, y, start, end) ) + or + // Lookbehind assertions can potentially match the start of the string + ( + this.positiveLookbehindAssertionGroup(_, _, start, _) or + this.negativeLookbehindAssertionGroup(_, _, start, _) + ) and + this.item(start, end) } /** A part of the regex that may match the end of the string. */ @@ -1074,6 +1089,13 @@ class RegExp extends Expr instanceof StringLiteral { or this.alternationOption(x, y, start, end) ) + or + // Lookahead assertions can potentially match the end of the string + ( + this.positiveLookaheadAssertionGroup(_, _, _, end) or + this.negativeLookaheadAssertionGroup(_, _, _, end) + ) and + this.item(start, end) } /** diff --git a/python/ql/src/change-notes/2025-09-19-fix-unmatchable-dollar-and-caret-in-assertions.md b/python/ql/src/change-notes/2025-09-19-fix-unmatchable-dollar-and-caret-in-assertions.md new file mode 100644 index 00000000000..cf63dd9ed4d --- /dev/null +++ b/python/ql/src/change-notes/2025-09-19-fix-unmatchable-dollar-and-caret-in-assertions.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- + +- The queries that check for unmatchable `$` and `^` in regular expressions did not account correctly for occurrences inside lookahead and lookbehind assertions. These occurrences are now handled correctly, eliminating this source of false positives. diff --git a/python/ql/test/query-tests/Expressions/Regex/test.py b/python/ql/test/query-tests/Expressions/Regex/test.py index 6dadbccb4b6..717663e335c 100644 --- a/python/ql/test/query-tests/Expressions/Regex/test.py +++ b/python/ql/test/query-tests/Expressions/Regex/test.py @@ -150,4 +150,12 @@ re.compile(r"[\U00010000-\U0010FFFF]") re.compile(r"[\u0000-\uFFFF]") #Allow unicode names -re.compile(r"[\N{degree sign}\N{EM DASH}]") \ No newline at end of file +re.compile(r"[\N{degree sign}\N{EM DASH}]") + +#Lookahead assertions. None of these are unmatchable dollars: +re.compile(r"^(?=a$)[ab]") +re.compile(r"^(?!a$)[ab]") + +#Lookbehind assertions. None of these are unmatchable carets: +re.compile(r"(?<=^a)a") +re.compile(r"(? Date: Fri, 19 Sep 2025 15:39:12 +0000 Subject: [PATCH 051/160] Python: Update test output --- python/ql/test/library-tests/regex/FirstLast.expected | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/ql/test/library-tests/regex/FirstLast.expected b/python/ql/test/library-tests/regex/FirstLast.expected index b187033ee22..0abf9c790c2 100644 --- a/python/ql/test/library-tests/regex/FirstLast.expected +++ b/python/ql/test/library-tests/regex/FirstLast.expected @@ -4,6 +4,7 @@ | (?!not-this)^[A-Z_]+$ | first | 12 | 13 | | (?!not-this)^[A-Z_]+$ | first | 13 | 19 | | (?!not-this)^[A-Z_]+$ | first | 13 | 20 | +| (?!not-this)^[A-Z_]+$ | last | 3 | 11 | | (?!not-this)^[A-Z_]+$ | last | 13 | 19 | | (?!not-this)^[A-Z_]+$ | last | 13 | 20 | | (?!not-this)^[A-Z_]+$ | last | 20 | 21 | @@ -101,6 +102,7 @@ | ^[A-Z_]+$(? Date: Fri, 19 Sep 2025 16:49:54 +0100 Subject: [PATCH 052/160] Apply suggestions from code review Co-authored-by: Simon Friis Vindum --- rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp b/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp index e4e0fc5eaa9..088f202965a 100644 --- a/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp +++ b/rust/ql/src/queries/security/CWE-319/UseOfHttp.qhelp @@ -4,7 +4,7 @@ -

    Constructing URLs with the HTTP protocol can lead to unsecured connections.

    +

    Constructing URLs with the HTTP protocol can lead to insecure connections.

    Furthermore, constructing URLs with the HTTP protocol can create problems if other parts of the code expect HTTPS URLs. A typical pattern is to use libraries that expect secure connections, @@ -14,7 +14,7 @@ which may fail or fall back to insecure behavior when provided with HTTP URLs in

    When you construct a URL for network requests, ensure that you use an HTTPS URL rather than an HTTP URL. -Then, any connections that are made using that URL are secure SSL/TLS connections.

    +Then, any connections that are made using that URL are secure TLS connections.

    @@ -26,7 +26,7 @@ by attackers:

    A better approach is to use HTTPS. When the request is made using an HTTPS URL, the connection -is a secure SSL/TLS connection:

    +is a secure TLS connection:

    From 89e9ee43c00159a561bbad75b43296acefd87ef7 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Fri, 19 Sep 2025 18:28:45 -0400 Subject: [PATCH 053/160] Convert from GrapeHelperMethodTaintStep extends AdditionalTaintStep to a simplified GrapeHelperMethodTarget extends AdditionalCallTarget --- .../2025-09-15-grape-framework-support.md | 2 +- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 39 +++++++------------ .../frameworks/grape/Flow.expected | 36 +++++++++++++++-- .../library-tests/frameworks/grape/app.rb | 4 +- 4 files changed, 49 insertions(+), 32 deletions(-) diff --git a/ruby/ql/lib/change-notes/2025-09-15-grape-framework-support.md b/ruby/ql/lib/change-notes/2025-09-15-grape-framework-support.md index 258da40d36c..08ceed887f2 100644 --- a/ruby/ql/lib/change-notes/2025-09-15-grape-framework-support.md +++ b/ruby/ql/lib/change-notes/2025-09-15-grape-framework-support.md @@ -1,4 +1,4 @@ --- category: feature --- -* Initial modeling for the Ruby Grape framework in `Grape.qll` have been added to detect API endpoints, parameters, and headers within Grape API classes. \ No newline at end of file +* Initial modeling for the Ruby Grape framework in `Grape.qll` has been added to detect API endpoints, parameters, and headers within Grape API classes. \ No newline at end of file diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index a1646b8654c..31632e01948 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -3,6 +3,7 @@ */ private import codeql.ruby.AST +private import codeql.ruby.CFG private import codeql.ruby.Concepts private import codeql.ruby.controlflow.CfgNodes private import codeql.ruby.DataFlow @@ -301,32 +302,20 @@ private class GrapeHelperMethod extends Method { } /** - * Additional taint step to model dataflow from method arguments to parameters - * and from return values back to call sites for Grape helper methods defined in `helpers` blocks. - * This bridges the gap where standard dataflow doesn't recognize the Grape DSL semantics. + * Additional call-target to resolve helper method calls defined in `helpers` blocks. + * + * This class is responsible for resolving calls to helper methods defined in + * `helpers` blocks, allowing the dataflow framework to accurately track + * the flow of information between these methods and their call sites. */ -private class GrapeHelperMethodTaintStep extends AdditionalTaintStep { - override predicate step(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - // Map arguments to parameters for helper method calls - exists(GrapeHelperMethod helperMethod, MethodCall call, int i | - // Find calls to helper methods from within Grape endpoints or other helper methods - call.getMethodName() = helperMethod.getName() and - exists(GrapeApiClass api | call.getParent+() = api.getADeclaration()) and - // Map argument to parameter - nodeFrom.asExpr().getExpr() = call.getArgument(i) and - nodeTo.asParameter() = helperMethod.getParameter(i) - ) - or - // Model implicit return values: the last expression in a helper method flows to the call site - exists(GrapeHelperMethod helperMethod, MethodCall helperCall, Expr lastExpr | - // Find calls to helper methods from within Grape endpoints or other helper methods - helperCall.getMethodName() = helperMethod.getName() and - exists(GrapeApiClass api | helperCall.getParent+() = api.getADeclaration()) and - // Get the last expression in the helper method (Ruby's implicit return) - lastExpr = helperMethod.getLastStmt() and - // Flow from the last expression in the helper method to the call site - nodeFrom.asExpr().getExpr() = lastExpr and - nodeTo.asExpr().getExpr() = helperCall +private class GrapeHelperMethodTarget extends AdditionalCallTarget { + override DataFlowCallable viableTarget(CfgNodes::ExprNodes::CallCfgNode call) { + // Find calls to helper methods from within Grape endpoints or other helper methods + exists(GrapeHelperMethod helperMethod, MethodCall mc | + result.asCfgScope() = helperMethod and + mc = call.getAstNode() and + mc.getMethodName() = helperMethod.getName() and + mc.getParent+() = helperMethod.getApiClass().getADeclaration() ) } } diff --git a/ruby/ql/test/library-tests/frameworks/grape/Flow.expected b/ruby/ql/test/library-tests/frameworks/grape/Flow.expected index 0fd19d4eace..c104b36afb2 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Flow.expected +++ b/ruby/ql/test/library-tests/frameworks/grape/Flow.expected @@ -1,10 +1,15 @@ models edges | app.rb:103:13:103:18 | call to params | app.rb:103:13:103:70 | call to select | provenance | | -| app.rb:103:13:103:70 | call to select | app.rb:149:21:149:31 | call to user_params | provenance | AdditionalTaintStep | -| app.rb:103:13:103:70 | call to select | app.rb:165:21:165:31 | call to user_params | provenance | AdditionalTaintStep | -| app.rb:107:13:107:32 | call to source | app.rb:143:18:143:43 | call to vulnerable_helper | provenance | AdditionalTaintStep | -| app.rb:111:13:111:33 | call to source | app.rb:150:25:150:37 | call to simple_helper | provenance | AdditionalTaintStep | +| app.rb:103:13:103:18 | call to params | app.rb:103:13:103:70 | call to select : [collection] [element] | provenance | | +| app.rb:103:13:103:70 | call to select | app.rb:149:21:149:31 | call to user_params | provenance | | +| app.rb:103:13:103:70 | call to select | app.rb:165:21:165:31 | call to user_params | provenance | | +| app.rb:103:13:103:70 | call to select : [collection] [element] | app.rb:149:21:149:31 | call to user_params : [collection] [element] | provenance | | +| app.rb:103:13:103:70 | call to select : [collection] [element] | app.rb:165:21:165:31 | call to user_params : [collection] [element] | provenance | | +| app.rb:107:13:107:32 | call to source | app.rb:143:18:143:43 | call to vulnerable_helper | provenance | | +| app.rb:107:13:107:32 | call to source | app.rb:143:18:143:43 | call to vulnerable_helper | provenance | | +| app.rb:111:13:111:33 | call to source | app.rb:150:25:150:37 | call to simple_helper | provenance | | +| app.rb:111:13:111:33 | call to source | app.rb:150:25:150:37 | call to simple_helper | provenance | | | app.rb:126:9:126:15 | user_id | app.rb:133:14:133:20 | user_id | provenance | | | app.rb:126:19:126:24 | call to params | app.rb:126:19:126:34 | ...[...] | provenance | | | app.rb:126:19:126:34 | ...[...] | app.rb:126:9:126:15 | user_id | provenance | | @@ -17,20 +22,31 @@ edges | app.rb:129:19:129:25 | call to cookies | app.rb:129:19:129:38 | ...[...] | provenance | | | app.rb:129:19:129:38 | ...[...] | app.rb:129:9:129:15 | session | provenance | | | app.rb:143:9:143:14 | result | app.rb:144:14:144:19 | result | provenance | | +| app.rb:143:9:143:14 | result | app.rb:144:14:144:19 | result | provenance | | +| app.rb:143:18:143:43 | call to vulnerable_helper | app.rb:143:9:143:14 | result | provenance | | | app.rb:143:18:143:43 | call to vulnerable_helper | app.rb:143:9:143:14 | result | provenance | | | app.rb:149:9:149:17 | user_data | app.rb:151:14:151:22 | user_data | provenance | | +| app.rb:149:9:149:17 | user_data : [collection] [element] | app.rb:151:14:151:22 | user_data | provenance | | | app.rb:149:21:149:31 | call to user_params | app.rb:149:9:149:17 | user_data | provenance | | +| app.rb:149:21:149:31 | call to user_params : [collection] [element] | app.rb:149:9:149:17 | user_data : [collection] [element] | provenance | | | app.rb:150:9:150:21 | simple_result | app.rb:152:14:152:26 | simple_result | provenance | | +| app.rb:150:9:150:21 | simple_result | app.rb:152:14:152:26 | simple_result | provenance | | +| app.rb:150:25:150:37 | call to simple_helper | app.rb:150:9:150:21 | simple_result | provenance | | | app.rb:150:25:150:37 | call to simple_helper | app.rb:150:9:150:21 | simple_result | provenance | | | app.rb:159:13:159:19 | user_id | app.rb:160:18:160:24 | user_id | provenance | | | app.rb:159:23:159:28 | call to params | app.rb:159:23:159:33 | ...[...] | provenance | | | app.rb:159:23:159:33 | ...[...] | app.rb:159:13:159:19 | user_id | provenance | | | app.rb:165:9:165:17 | user_data | app.rb:166:14:166:22 | user_data | provenance | | +| app.rb:165:9:165:17 | user_data : [collection] [element] | app.rb:166:14:166:22 | user_data | provenance | | | app.rb:165:21:165:31 | call to user_params | app.rb:165:9:165:17 | user_data | provenance | | +| app.rb:165:21:165:31 | call to user_params : [collection] [element] | app.rb:165:9:165:17 | user_data : [collection] [element] | provenance | | nodes | app.rb:103:13:103:18 | call to params | semmle.label | call to params | | app.rb:103:13:103:70 | call to select | semmle.label | call to select | +| app.rb:103:13:103:70 | call to select : [collection] [element] | semmle.label | call to select : [collection] [element] | | app.rb:107:13:107:32 | call to source | semmle.label | call to source | +| app.rb:107:13:107:32 | call to source | semmle.label | call to source | +| app.rb:111:13:111:33 | call to source | semmle.label | call to source | | app.rb:111:13:111:33 | call to source | semmle.label | call to source | | app.rb:126:9:126:15 | user_id | semmle.label | user_id | | app.rb:126:19:126:24 | call to params | semmle.label | call to params | @@ -48,20 +64,30 @@ nodes | app.rb:135:14:135:17 | auth | semmle.label | auth | | app.rb:136:14:136:20 | session | semmle.label | session | | app.rb:143:9:143:14 | result | semmle.label | result | +| app.rb:143:9:143:14 | result | semmle.label | result | +| app.rb:143:18:143:43 | call to vulnerable_helper | semmle.label | call to vulnerable_helper | | app.rb:143:18:143:43 | call to vulnerable_helper | semmle.label | call to vulnerable_helper | | app.rb:144:14:144:19 | result | semmle.label | result | +| app.rb:144:14:144:19 | result | semmle.label | result | | app.rb:149:9:149:17 | user_data | semmle.label | user_data | +| app.rb:149:9:149:17 | user_data : [collection] [element] | semmle.label | user_data : [collection] [element] | | app.rb:149:21:149:31 | call to user_params | semmle.label | call to user_params | +| app.rb:149:21:149:31 | call to user_params : [collection] [element] | semmle.label | call to user_params : [collection] [element] | +| app.rb:150:9:150:21 | simple_result | semmle.label | simple_result | | app.rb:150:9:150:21 | simple_result | semmle.label | simple_result | | app.rb:150:25:150:37 | call to simple_helper | semmle.label | call to simple_helper | +| app.rb:150:25:150:37 | call to simple_helper | semmle.label | call to simple_helper | | app.rb:151:14:151:22 | user_data | semmle.label | user_data | | app.rb:152:14:152:26 | simple_result | semmle.label | simple_result | +| app.rb:152:14:152:26 | simple_result | semmle.label | simple_result | | app.rb:159:13:159:19 | user_id | semmle.label | user_id | | app.rb:159:23:159:28 | call to params | semmle.label | call to params | | app.rb:159:23:159:33 | ...[...] | semmle.label | ...[...] | | app.rb:160:18:160:24 | user_id | semmle.label | user_id | | app.rb:165:9:165:17 | user_data | semmle.label | user_data | +| app.rb:165:9:165:17 | user_data : [collection] [element] | semmle.label | user_data : [collection] [element] | | app.rb:165:21:165:31 | call to user_params | semmle.label | call to user_params | +| app.rb:165:21:165:31 | call to user_params : [collection] [element] | semmle.label | call to user_params : [collection] [element] | | app.rb:166:14:166:22 | user_data | semmle.label | user_data | subpaths testFailures @@ -71,7 +97,9 @@ testFailures | app.rb:135:14:135:17 | auth | app.rb:128:16:128:22 | call to headers | app.rb:135:14:135:17 | auth | $@ | app.rb:128:16:128:22 | call to headers | call to headers | | app.rb:136:14:136:20 | session | app.rb:129:19:129:25 | call to cookies | app.rb:136:14:136:20 | session | $@ | app.rb:129:19:129:25 | call to cookies | call to cookies | | app.rb:144:14:144:19 | result | app.rb:107:13:107:32 | call to source | app.rb:144:14:144:19 | result | $@ | app.rb:107:13:107:32 | call to source | call to source | +| app.rb:144:14:144:19 | result | app.rb:107:13:107:32 | call to source | app.rb:144:14:144:19 | result | $@ | app.rb:107:13:107:32 | call to source | call to source | | app.rb:151:14:151:22 | user_data | app.rb:103:13:103:18 | call to params | app.rb:151:14:151:22 | user_data | $@ | app.rb:103:13:103:18 | call to params | call to params | | app.rb:152:14:152:26 | simple_result | app.rb:111:13:111:33 | call to source | app.rb:152:14:152:26 | simple_result | $@ | app.rb:111:13:111:33 | call to source | call to source | +| app.rb:152:14:152:26 | simple_result | app.rb:111:13:111:33 | call to source | app.rb:152:14:152:26 | simple_result | $@ | app.rb:111:13:111:33 | call to source | call to source | | app.rb:160:18:160:24 | user_id | app.rb:159:23:159:28 | call to params | app.rb:160:18:160:24 | user_id | $@ | app.rb:159:23:159:28 | call to params | call to params | | app.rb:166:14:166:22 | user_data | app.rb:103:13:103:18 | call to params | app.rb:166:14:166:22 | user_data | $@ | app.rb:103:13:103:18 | call to params | call to params | diff --git a/ruby/ql/test/library-tests/frameworks/grape/app.rb b/ruby/ql/test/library-tests/frameworks/grape/app.rb index 6fbb184cab9..81f46482687 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/app.rb +++ b/ruby/ql/test/library-tests/frameworks/grape/app.rb @@ -141,7 +141,7 @@ class UserAPI < Grape::API # Test helper method parameter passing dataflow user_id = params[:user_id] result = vulnerable_helper(user_id) - sink result # $ hasTaintFlow=paramHelper + sink result # $ hasValueFlow=paramHelper end post '/users' do @@ -149,7 +149,7 @@ class UserAPI < Grape::API user_data = user_params simple_result = simple_helper sink user_data # $ hasTaintFlow - sink simple_result # $ hasTaintFlow=simpleHelper + sink simple_result # $ hasValueFlow=simpleHelper end # Test route_param block pattern From f4bbbc346fe5b270f6fbfc3ed351fdfdaee3fa46 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Fri, 19 Sep 2025 19:06:50 -0400 Subject: [PATCH 054/160] Refactor Grape framework to be encapsulated properly in Module --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 550 +++++++++--------- .../library-tests/frameworks/grape/Grape.ql | 14 +- 2 files changed, 285 insertions(+), 279 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index 31632e01948..0999be94505 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -29,293 +29,299 @@ module Grape { not exists(GrapeApiClass parent | this != parent and this = parent.getADescendent()) } } -} -/** - * A class that extends `Grape::API`. - * For example, - * - * ```rb - * class FooAPI < Grape::API - * get '/users' do - * name = params[:name] - * User.where("name = #{name}") - * end - * end - * ``` - */ -class GrapeApiClass extends DataFlow::ClassNode { - GrapeApiClass() { - this = grapeApiBaseClass().getADescendentModule() and - not exists(DataFlow::ModuleNode m | m = grapeApiBaseClass().asModule() | this = m) + /** + * A class that extends `Grape::API`. + * For example, + * + * ```rb + * class FooAPI < Grape::API + * get '/users' do + * name = params[:name] + * User.where("name = #{name}") + * end + * end + * ``` + */ + class GrapeApiClass extends DataFlow::ClassNode { + GrapeApiClass() { + this = grapeApiBaseClass().getADescendentModule() and + not exists(DataFlow::ModuleNode m | m = grapeApiBaseClass().asModule() | this = m) + } + + /** + * Gets a `GrapeEndpoint` defined in this class. + */ + GrapeEndpoint getAnEndpoint() { result.getApiClass() = this } + + /** + * Gets a `self` that possibly refers to an instance of this class. + */ + DataFlow::LocalSourceNode getSelf() { + result = this.getAnInstanceSelf() + or + // Include the module-level `self` to recover some cases where a block at the module level + // is invoked with an instance as the `self`. + result = this.getModuleLevelSelf() + } + } + + private DataFlow::ConstRef grapeApiBaseClass() { + result = DataFlow::getConstant("Grape").getConstant("API") + } + + private API::Node grapeApiInstance() { result = any(GrapeApiClass cls).getSelf().track() } + + /** + * A Grape API endpoint (get, post, put, delete, etc.) call within a `Grape::API` class. + */ + class GrapeEndpoint extends DataFlow::CallNode { + private GrapeApiClass apiClass; + + GrapeEndpoint() { + this = + apiClass.getAModuleLevelCall(["get", "post", "put", "delete", "patch", "head", "options"]) + } + + /** + * Gets the HTTP method for this endpoint (e.g., "GET", "POST", etc.) + */ + string getHttpMethod() { result = this.getMethodName().toUpperCase() } + + /** + * Gets the API class containing this endpoint. + */ + GrapeApiClass getApiClass() { result = apiClass } + + /** + * Gets the block containing the endpoint logic. + */ + DataFlow::BlockNode getBody() { result = this.getBlock() } + + /** + * Gets the path pattern for this endpoint, if specified. + */ + string getPath() { result = this.getArgument(0).getConstantValue().getString() } } /** - * Gets a `GrapeEndpoint` defined in this class. + * A `RemoteFlowSource::Range` to represent accessing the + * Grape parameters available via the `params` method within an endpoint. */ - GrapeEndpoint getAnEndpoint() { result.getApiClass() = this } + class GrapeParamsSource extends Http::Server::RequestInputAccess::Range { + GrapeParamsSource() { this.asExpr().getExpr() instanceof GrapeParamsCall } - /** - * Gets a `self` that possibly refers to an instance of this class. - */ - DataFlow::LocalSourceNode getSelf() { - result = this.getAnInstanceSelf() - or - // Include the module-level `self` to recover some cases where a block at the module level - // is invoked with an instance as the `self`. - result = this.getModuleLevelSelf() - } -} + override string getSourceType() { result = "Grape::API#params" } -private DataFlow::ConstRef grapeApiBaseClass() { - result = DataFlow::getConstant("Grape").getConstant("API") -} - -private API::Node grapeApiInstance() { result = any(GrapeApiClass cls).getSelf().track() } - -/** - * A Grape API endpoint (get, post, put, delete, etc.) call within a `Grape::API` class. - */ -class GrapeEndpoint extends DataFlow::CallNode { - private GrapeApiClass apiClass; - - GrapeEndpoint() { - this = - apiClass.getAModuleLevelCall(["get", "post", "put", "delete", "patch", "head", "options"]) + override Http::Server::RequestInputKind getKind() { + result = Http::Server::parameterInputKind() + } } /** - * Gets the HTTP method for this endpoint (e.g., "GET", "POST", etc.) + * A call to `params` from within a Grape API endpoint or helper method. */ - string getHttpMethod() { result = this.getMethodName().toUpperCase() } - - /** - * Gets the API class containing this endpoint. - */ - GrapeApiClass getApiClass() { result = apiClass } - - /** - * Gets the block containing the endpoint logic. - */ - DataFlow::BlockNode getBody() { result = this.getBlock() } - - /** - * Gets the path pattern for this endpoint, if specified. - */ - string getPath() { result = this.getArgument(0).getConstantValue().getString() } -} - -/** - * A `RemoteFlowSource::Range` to represent accessing the - * Grape parameters available via the `params` method within an endpoint. - */ -class GrapeParamsSource extends Http::Server::RequestInputAccess::Range { - GrapeParamsSource() { this.asExpr().getExpr() instanceof GrapeParamsCall } - - override string getSourceType() { result = "Grape::API#params" } - - override Http::Server::RequestInputKind getKind() { result = Http::Server::parameterInputKind() } -} - -/** - * A call to `params` from within a Grape API endpoint or helper method. - */ -private class GrapeParamsCall extends ParamsCallImpl { - GrapeParamsCall() { - // Params calls within endpoint blocks - exists(GrapeApiClass api | - this.getMethodName() = "params" and - this.getParent+() = api.getADeclaration() - ) - or - // Params calls within helper methods (defined in helpers blocks) - exists(GrapeApiClass api, DataFlow::CallNode helpersCall | - helpersCall = api.getAModuleLevelCall("helpers") and - this.getMethodName() = "params" and - this.getParent+() = helpersCall.getBlock().asExpr().getExpr() - ) - } -} - -/** - * A call to `headers` from within a Grape API endpoint or headers block. - * Headers can also be a source of user input. - */ -class GrapeHeadersSource extends Http::Server::RequestInputAccess::Range { - GrapeHeadersSource() { - this.asExpr().getExpr() instanceof GrapeHeadersCall - or - this.asExpr().getExpr() instanceof GrapeHeadersBlockCall - } - - override string getSourceType() { result = "Grape::API#headers" } - - override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() } -} - -/** - * A call to `headers` from within a Grape API endpoint. - */ -private class GrapeHeadersCall extends MethodCall { - GrapeHeadersCall() { - exists(GrapeEndpoint endpoint | - this.getParent+() = endpoint.getBody().asCallableAstNode() and - this.getMethodName() = "headers" - ) - or - // Also handle cases where headers is called on an instance of a Grape API class - this = grapeApiInstance().getAMethodCall("headers").asExpr().getExpr() - } -} - -/** - * A call to `request` from within a Grape API endpoint. - * The request object can contain user input. - */ -class GrapeRequestSource extends Http::Server::RequestInputAccess::Range { - GrapeRequestSource() { this.asExpr().getExpr() instanceof GrapeRequestCall } - - override string getSourceType() { result = "Grape::API#request" } - - override Http::Server::RequestInputKind getKind() { result = Http::Server::parameterInputKind() } -} - -/** - * A call to `route_param` from within a Grape API endpoint. - * Route parameters are extracted from the URL path and can be a source of user input. - */ -class GrapeRouteParamSource extends Http::Server::RequestInputAccess::Range { - GrapeRouteParamSource() { this.asExpr().getExpr() instanceof GrapeRouteParamCall } - - override string getSourceType() { result = "Grape::API#route_param" } - - override Http::Server::RequestInputKind getKind() { result = Http::Server::parameterInputKind() } -} - -/** - * A call to `request` from within a Grape API endpoint. - */ -private class GrapeRequestCall extends MethodCall { - GrapeRequestCall() { - exists(GrapeEndpoint endpoint | - this.getParent+() = endpoint.getBody().asCallableAstNode() and - this.getMethodName() = "request" - ) - or - // Also handle cases where request is called on an instance of a Grape API class - this = grapeApiInstance().getAMethodCall("request").asExpr().getExpr() - } -} - -/** - * A call to `route_param` from within a Grape API endpoint. - */ -private class GrapeRouteParamCall extends MethodCall { - GrapeRouteParamCall() { - exists(GrapeEndpoint endpoint | - this.getParent+() = endpoint.getBody().asExpr().getExpr() and - this.getMethodName() = "route_param" - ) - or - // Also handle cases where route_param is called on an instance of a Grape API class - this = grapeApiInstance().getAMethodCall("route_param").asExpr().getExpr() - } -} - -/** - * A call to `headers` block within a Grape API class. - * This is different from the headers() method call - this is the DSL block for defining header requirements. - */ -private class GrapeHeadersBlockCall extends MethodCall { - GrapeHeadersBlockCall() { - exists(GrapeApiClass api | - this.getParent+() = api.getADeclaration() and - this.getMethodName() = "headers" and - exists(this.getBlock()) - ) - } -} - -/** - * A call to `cookies` block within a Grape API class. - * This DSL block defines cookie requirements and those cookies are user-controlled. - */ -private class GrapeCookiesBlockCall extends MethodCall { - GrapeCookiesBlockCall() { - exists(GrapeApiClass api | - this.getParent+() = api.getADeclaration() and - this.getMethodName() = "cookies" and - exists(this.getBlock()) - ) - } -} - -/** - * A call to `cookies` method from within a Grape API endpoint or cookies block. - * Similar to headers, cookies can be accessed as a method and are user-controlled input. - */ -class GrapeCookiesSource extends Http::Server::RequestInputAccess::Range { - GrapeCookiesSource() { - this.asExpr().getExpr() instanceof GrapeCookiesCall - or - this.asExpr().getExpr() instanceof GrapeCookiesBlockCall - } - - override string getSourceType() { result = "Grape::API#cookies" } - - override Http::Server::RequestInputKind getKind() { result = Http::Server::cookieInputKind() } -} - -/** - * A call to `cookies` method from within a Grape API endpoint. - */ -private class GrapeCookiesCall extends MethodCall { - GrapeCookiesCall() { - exists(GrapeEndpoint endpoint | - this.getParent+() = endpoint.getBody().asCallableAstNode() and - this.getMethodName() = "cookies" - ) - or - // Also handle cases where cookies is called on an instance of a Grape API class - this = grapeApiInstance().getAMethodCall("cookies").asExpr().getExpr() - } -} - -/** - * A method defined within a `helpers` block in a Grape API class. - * These methods become available in endpoint contexts through Grape's DSL. - */ -private class GrapeHelperMethod extends Method { - private GrapeApiClass apiClass; - - GrapeHelperMethod() { - exists(DataFlow::CallNode helpersCall | - helpersCall = apiClass.getAModuleLevelCall("helpers") and - this.getParent+() = helpersCall.getBlock().asExpr().getExpr() - ) + private class GrapeParamsCall extends ParamsCallImpl { + GrapeParamsCall() { + // Params calls within endpoint blocks + exists(GrapeApiClass api | + this.getMethodName() = "params" and + this.getParent+() = api.getADeclaration() + ) + or + // Params calls within helper methods (defined in helpers blocks) + exists(GrapeApiClass api, DataFlow::CallNode helpersCall | + helpersCall = api.getAModuleLevelCall("helpers") and + this.getMethodName() = "params" and + this.getParent+() = helpersCall.getBlock().asExpr().getExpr() + ) + } } /** - * Gets the API class that contains this helper method. + * A call to `headers` from within a Grape API endpoint or headers block. + * Headers can also be a source of user input. */ - GrapeApiClass getApiClass() { result = apiClass } -} + class GrapeHeadersSource extends Http::Server::RequestInputAccess::Range { + GrapeHeadersSource() { + this.asExpr().getExpr() instanceof GrapeHeadersCall + or + this.asExpr().getExpr() instanceof GrapeHeadersBlockCall + } -/** - * Additional call-target to resolve helper method calls defined in `helpers` blocks. - * - * This class is responsible for resolving calls to helper methods defined in - * `helpers` blocks, allowing the dataflow framework to accurately track - * the flow of information between these methods and their call sites. - */ -private class GrapeHelperMethodTarget extends AdditionalCallTarget { - override DataFlowCallable viableTarget(CfgNodes::ExprNodes::CallCfgNode call) { - // Find calls to helper methods from within Grape endpoints or other helper methods - exists(GrapeHelperMethod helperMethod, MethodCall mc | - result.asCfgScope() = helperMethod and - mc = call.getAstNode() and - mc.getMethodName() = helperMethod.getName() and - mc.getParent+() = helperMethod.getApiClass().getADeclaration() - ) + override string getSourceType() { result = "Grape::API#headers" } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::headerInputKind() } + } + + /** + * A call to `headers` from within a Grape API endpoint. + */ + private class GrapeHeadersCall extends MethodCall { + GrapeHeadersCall() { + exists(GrapeEndpoint endpoint | + this.getParent+() = endpoint.getBody().asCallableAstNode() and + this.getMethodName() = "headers" + ) + or + // Also handle cases where headers is called on an instance of a Grape API class + this = grapeApiInstance().getAMethodCall("headers").asExpr().getExpr() + } + } + + /** + * A call to `request` from within a Grape API endpoint. + * The request object can contain user input. + */ + class GrapeRequestSource extends Http::Server::RequestInputAccess::Range { + GrapeRequestSource() { this.asExpr().getExpr() instanceof GrapeRequestCall } + + override string getSourceType() { result = "Grape::API#request" } + + override Http::Server::RequestInputKind getKind() { + result = Http::Server::parameterInputKind() + } + } + + /** + * A call to `route_param` from within a Grape API endpoint. + * Route parameters are extracted from the URL path and can be a source of user input. + */ + class GrapeRouteParamSource extends Http::Server::RequestInputAccess::Range { + GrapeRouteParamSource() { this.asExpr().getExpr() instanceof GrapeRouteParamCall } + + override string getSourceType() { result = "Grape::API#route_param" } + + override Http::Server::RequestInputKind getKind() { + result = Http::Server::parameterInputKind() + } + } + + /** + * A call to `request` from within a Grape API endpoint. + */ + private class GrapeRequestCall extends MethodCall { + GrapeRequestCall() { + exists(GrapeEndpoint endpoint | + this.getParent+() = endpoint.getBody().asCallableAstNode() and + this.getMethodName() = "request" + ) + or + // Also handle cases where request is called on an instance of a Grape API class + this = grapeApiInstance().getAMethodCall("request").asExpr().getExpr() + } + } + + /** + * A call to `route_param` from within a Grape API endpoint. + */ + private class GrapeRouteParamCall extends MethodCall { + GrapeRouteParamCall() { + exists(GrapeEndpoint endpoint | + this.getParent+() = endpoint.getBody().asExpr().getExpr() and + this.getMethodName() = "route_param" + ) + or + // Also handle cases where route_param is called on an instance of a Grape API class + this = grapeApiInstance().getAMethodCall("route_param").asExpr().getExpr() + } + } + + /** + * A call to `headers` block within a Grape API class. + * This is different from the headers() method call - this is the DSL block for defining header requirements. + */ + private class GrapeHeadersBlockCall extends MethodCall { + GrapeHeadersBlockCall() { + exists(GrapeApiClass api | + this.getParent+() = api.getADeclaration() and + this.getMethodName() = "headers" and + exists(this.getBlock()) + ) + } + } + + /** + * A call to `cookies` block within a Grape API class. + * This DSL block defines cookie requirements and those cookies are user-controlled. + */ + private class GrapeCookiesBlockCall extends MethodCall { + GrapeCookiesBlockCall() { + exists(GrapeApiClass api | + this.getParent+() = api.getADeclaration() and + this.getMethodName() = "cookies" and + exists(this.getBlock()) + ) + } + } + + /** + * A call to `cookies` method from within a Grape API endpoint or cookies block. + * Similar to headers, cookies can be accessed as a method and are user-controlled input. + */ + class GrapeCookiesSource extends Http::Server::RequestInputAccess::Range { + GrapeCookiesSource() { + this.asExpr().getExpr() instanceof GrapeCookiesCall + or + this.asExpr().getExpr() instanceof GrapeCookiesBlockCall + } + + override string getSourceType() { result = "Grape::API#cookies" } + + override Http::Server::RequestInputKind getKind() { result = Http::Server::cookieInputKind() } + } + + /** + * A call to `cookies` method from within a Grape API endpoint. + */ + private class GrapeCookiesCall extends MethodCall { + GrapeCookiesCall() { + exists(GrapeEndpoint endpoint | + this.getParent+() = endpoint.getBody().asCallableAstNode() and + this.getMethodName() = "cookies" + ) + or + // Also handle cases where cookies is called on an instance of a Grape API class + this = grapeApiInstance().getAMethodCall("cookies").asExpr().getExpr() + } + } + + /** + * A method defined within a `helpers` block in a Grape API class. + * These methods become available in endpoint contexts through Grape's DSL. + */ + private class GrapeHelperMethod extends Method { + private GrapeApiClass apiClass; + + GrapeHelperMethod() { + exists(DataFlow::CallNode helpersCall | + helpersCall = apiClass.getAModuleLevelCall("helpers") and + this.getParent+() = helpersCall.getBlock().asExpr().getExpr() + ) + } + + /** + * Gets the API class that contains this helper method. + */ + GrapeApiClass getApiClass() { result = apiClass } + } + + /** + * Additional call-target to resolve helper method calls defined in `helpers` blocks. + * + * This class is responsible for resolving calls to helper methods defined in + * `helpers` blocks, allowing the dataflow framework to accurately track + * the flow of information between these methods and their call sites. + */ + private class GrapeHelperMethodTarget extends AdditionalCallTarget { + override DataFlowCallable viableTarget(CfgNodes::ExprNodes::CallCfgNode call) { + // Find calls to helper methods from within Grape endpoints or other helper methods + exists(GrapeHelperMethod helperMethod, MethodCall mc | + result.asCfgScope() = helperMethod and + mc = call.getAstNode() and + mc.getMethodName() = helperMethod.getName() and + mc.getParent+() = helperMethod.getApiClass().getADeclaration() + ) + } } } diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql index c9aa7c29082..c5f0798f7a6 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql @@ -3,20 +3,20 @@ import codeql.ruby.frameworks.Grape import codeql.ruby.Concepts import codeql.ruby.AST -query predicate grapeApiClasses(GrapeApiClass api) { any() } +query predicate grapeApiClasses(Grape::GrapeApiClass api) { any() } -query predicate grapeEndpoints(GrapeApiClass api, GrapeEndpoint endpoint, string method, string path) { +query predicate grapeEndpoints(Grape::GrapeApiClass api, Grape::GrapeEndpoint endpoint, string method, string path) { endpoint = api.getAnEndpoint() and method = endpoint.getHttpMethod() and path = endpoint.getPath() } -query predicate grapeParams(GrapeParamsSource params) { any() } +query predicate grapeParams(Grape::GrapeParamsSource params) { any() } -query predicate grapeHeaders(GrapeHeadersSource headers) { any() } +query predicate grapeHeaders(Grape::GrapeHeadersSource headers) { any() } -query predicate grapeRequest(GrapeRequestSource request) { any() } +query predicate grapeRequest(Grape::GrapeRequestSource request) { any() } -query predicate grapeRouteParam(GrapeRouteParamSource routeParam) { any() } +query predicate grapeRouteParam(Grape::GrapeRouteParamSource routeParam) { any() } -query predicate grapeCookies(GrapeCookiesSource cookies) { any() } +query predicate grapeCookies(Grape::GrapeCookiesSource cookies) { any() } From bdeeb3217ec087d58345cdfcf813d3a56a5050ad Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 19 Sep 2025 15:06:47 +0200 Subject: [PATCH 055/160] Rust: Add path resolution tests --- .../PathResolutionInlineExpectationsTest.qll | 12 +++++++---- .../library-tests/path-resolution/my2/mod.rs | 2 ++ .../path-resolution/my2/my3/mod.rs | 4 ++++ .../path-resolution/path-resolution.expected | 20 +++++++++++-------- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll b/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll index 8d2fdb2d2eb..df668194c07 100644 --- a/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll +++ b/rust/ql/lib/utils/test/PathResolutionInlineExpectationsTest.qll @@ -25,10 +25,14 @@ private module ResolveTest implements TestSig { private predicate item(ItemNode i, string value) { exists(string filepath, int line, boolean inMacro | itemAt(i, filepath, line, inMacro) | - commmentAt(value, filepath, line) - or - not commmentAt(_, filepath, line) and - value = i.getName() + if i instanceof SourceFile + then value = i.getFile().getBaseName() + else ( + commmentAt(value, filepath, line) + or + not commmentAt(_, filepath, line) and + value = i.getName() + ) ) } diff --git a/rust/ql/test/library-tests/path-resolution/my2/mod.rs b/rust/ql/test/library-tests/path-resolution/my2/mod.rs index 85edb683202..6b86c78237c 100644 --- a/rust/ql/test/library-tests/path-resolution/my2/mod.rs +++ b/rust/ql/test/library-tests/path-resolution/my2/mod.rs @@ -15,6 +15,8 @@ pub use nested2::nested7::nested8::{ // $ item=I118 use nested2::nested5::nested6::f as nested6_f; // $ item=I116 +use std::ops::Deref; // $ item=Deref + pub mod my3; #[path = "renamed.rs"] diff --git a/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs b/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs index b459ca05aa6..1a98df1b560 100644 --- a/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs +++ b/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs @@ -8,3 +8,7 @@ use super::super::h; // $ item=I25 use super::g; // $ item=I9 use super::nested6_f; // $ item=I116 + +use super::*; // $ item=mod.rs + +trait MyTrait: Deref {} // $ MISSING: item=Deref diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected index a908ec1e5c1..1a925a31cce 100644 --- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected +++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected @@ -33,8 +33,8 @@ mod | main.rs:712:1:764:1 | mod associated_types | | main.rs:770:1:789:1 | mod impl_with_attribute_macro | | my2/mod.rs:1:1:1:16 | mod nested2 | -| my2/mod.rs:18:1:18:12 | mod my3 | -| my2/mod.rs:20:1:21:10 | mod mymod | +| my2/mod.rs:20:1:20:12 | mod my3 | +| my2/mod.rs:22:1:23:10 | mod mymod | | my2/nested2.rs:1:1:11:1 | mod nested3 | | my2/nested2.rs:2:5:10:5 | mod nested4 | | my2/nested2.rs:13:1:19:1 | mod nested5 | @@ -406,7 +406,7 @@ resolvePath | main.rs:814:5:814:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f | | main.rs:815:5:815:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 | | main.rs:815:5:815:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f | -| main.rs:816:5:816:7 | my3 | my2/mod.rs:18:1:18:12 | mod my3 | +| main.rs:816:5:816:7 | my3 | my2/mod.rs:20:1:20:12 | mod my3 | | main.rs:816:5:816:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f | | main.rs:817:5:817:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f | | main.rs:818:5:818:7 | m18 | main.rs:553:1:571:1 | mod m18 | @@ -440,17 +440,21 @@ resolvePath | my2/mod.rs:16:5:16:20 | ...::nested5 | my2/nested2.rs:13:1:19:1 | mod nested5 | | my2/mod.rs:16:5:16:29 | ...::nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 | | my2/mod.rs:16:5:16:32 | ...::f | my2/nested2.rs:15:9:17:9 | fn f | -| my2/mod.rs:23:9:23:13 | mymod | my2/mod.rs:20:1:21:10 | mod mymod | -| my2/mod.rs:23:9:23:16 | ...::f | my2/renamed.rs:1:1:1:13 | fn f | +| my2/mod.rs:18:5:18:7 | std | {EXTERNAL LOCATION} | Crate(std@0.0.0) | +| my2/mod.rs:18:5:18:12 | ...::ops | {EXTERNAL LOCATION} | mod ops | +| my2/mod.rs:18:5:18:19 | ...::Deref | {EXTERNAL LOCATION} | trait Deref | +| my2/mod.rs:25:9:25:13 | mymod | my2/mod.rs:22:1:23:10 | mod mymod | +| my2/mod.rs:25:9:25:16 | ...::f | my2/renamed.rs:1:1:1:13 | fn f | | my2/my3/mod.rs:3:5:3:5 | g | my2/mod.rs:3:1:6:1 | fn g | | my2/my3/mod.rs:4:5:4:5 | h | main.rs:56:1:75:1 | fn h | -| my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | +| my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:25:34 | SourceFile | | my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:826:2 | SourceFile | | my2/my3/mod.rs:7:5:7:19 | ...::h | main.rs:56:1:75:1 | fn h | -| my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | +| my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:25:34 | SourceFile | | my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g | -| my2/my3/mod.rs:10:5:10:9 | super | my2/mod.rs:1:1:23:34 | SourceFile | +| my2/my3/mod.rs:10:5:10:9 | super | my2/mod.rs:1:1:25:34 | SourceFile | | my2/my3/mod.rs:10:5:10:20 | ...::nested6_f | my2/nested2.rs:15:9:17:9 | fn f | +| my2/my3/mod.rs:12:5:12:9 | super | my2/mod.rs:1:1:25:34 | SourceFile | | my.rs:3:5:3:10 | nested | my.rs:1:1:1:15 | mod nested | | my.rs:3:5:3:13 | ...::g | my/nested.rs:19:1:22:1 | fn g | | my.rs:11:5:11:5 | g | my/nested.rs:19:1:22:1 | fn g | From 223ab5e60cc654b3255520c581ba8cdbd9716335 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 21 Sep 2025 15:22:40 +0200 Subject: [PATCH 056/160] Rust: Add missing model --- rust/ql/lib/codeql/rust/frameworks/async-rs.model.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rust/ql/lib/codeql/rust/frameworks/async-rs.model.yml b/rust/ql/lib/codeql/rust/frameworks/async-rs.model.yml index 9e65ba1b196..706170d44b8 100644 --- a/rust/ql/lib/codeql/rust/frameworks/async-rs.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/async-rs.model.yml @@ -4,3 +4,9 @@ extensions: extensible: sourceModel data: - ["::connect", "ReturnValue.Future.Field[core::result::Result::Ok(0)]", "remote", "manual"] + - addsTo: + pack: codeql/rust-all + extensible: summaryModel + data: + - ["<_ as async_std::io::read::ReadExt>::read", "Argument[self]", "Argument[0].Reference", "taint", "manual"] + - ["<_ as async_std::io::read::ReadExt>::read", "Argument[self].Reference", "Argument[0].Reference", "taint", "manual"] \ No newline at end of file From 8d5d219c0f1d5372249c12a6f59ef3bf1046cd04 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Sun, 21 Sep 2025 15:36:22 +0200 Subject: [PATCH 057/160] Rust: Update expected test output --- .../dataflow/sources/InlineFlow.expected | 600 +++++++++--------- 1 file changed, 308 insertions(+), 292 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected index db0cb969d5a..af0e73ca2c0 100644 --- a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected @@ -33,108 +33,110 @@ models | 32 | Source: tokio::fs::read_link::read_link; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | | 33 | Source: tokio::fs::read_to_string::read_to_string; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | | 34 | Source: tokio::io::stdin::stdin; ReturnValue; stdin | -| 35 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value | -| 36 | Summary: <_ as core::iter::traits::iterator::Iterator>::collect; Argument[self].Element; ReturnValue.Element; value | -| 37 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Element; ReturnValue.Field[core::option::Option::Some(0)]; value | -| 38 | Summary: <_ as futures_io::if_std::AsyncBufRead>::poll_fill_buf; Argument[self].Reference; ReturnValue.Field[core::task::poll::Poll::Ready(0)].Field[core::result::Result::Ok(0)]; taint | -| 39 | Summary: <_ as futures_util::io::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 40 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self].Reference; Argument[0].Reference; taint | -| 41 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | -| 42 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self].Reference; Argument[1].Reference; taint | -| 43 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | -| 44 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint | -| 45 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | -| 46 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self].Reference; Argument[0].Reference; taint | -| 47 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 48 | Summary: <_ as std::io::BufRead>::lines; Argument[self]; ReturnValue; taint | -| 49 | Summary: <_ as std::io::BufRead>::read_line; Argument[self]; Argument[0].Reference; taint | -| 50 | Summary: <_ as std::io::BufRead>::read_until; Argument[self]; Argument[1].Reference; taint | -| 51 | Summary: <_ as std::io::BufRead>::split; Argument[self]; ReturnValue; taint | -| 52 | Summary: <_ as std::io::Read>::bytes; Argument[self]; ReturnValue; taint | -| 53 | Summary: <_ as std::io::Read>::chain; Argument[0]; ReturnValue; taint | -| 54 | Summary: <_ as std::io::Read>::chain; Argument[self]; ReturnValue; taint | -| 55 | Summary: <_ as std::io::Read>::read; Argument[self]; Argument[0].Reference; taint | -| 56 | Summary: <_ as std::io::Read>::read_exact; Argument[self]; Argument[0].Reference; taint | -| 57 | Summary: <_ as std::io::Read>::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 58 | Summary: <_ as std::io::Read>::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 59 | Summary: <_ as std::io::Read>::take; Argument[self]; ReturnValue; taint | -| 60 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 61 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::lines; Argument[self]; ReturnValue; taint | -| 62 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | -| 63 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | -| 64 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::split; Argument[self]; ReturnValue; taint | -| 65 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | -| 66 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_buf; Argument[self]; Argument[0].Reference; taint | -| 67 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_exact; Argument[self]; Argument[0].Reference; taint | -| 68 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_f32; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 69 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i16; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 70 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i64_le; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 71 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 72 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 73 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_u8; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 74 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | -| 75 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 76 | Summary: ::expect; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | -| 77 | Summary: ::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | -| 78 | Summary: ::new; Argument[0].Reference; ReturnValue; value | -| 79 | Summary: ::new; Argument[0]; ReturnValue.Field[core::pin::Pin::__pointer]; value | -| 80 | Summary: ::new; Argument[0]; ReturnValue; value | -| 81 | Summary: ::expect; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 82 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 83 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | -| 84 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 85 | Summary: ::parse; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 86 | Summary: ::connect; Argument[1]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 87 | Summary: ::new; Argument[0]; ReturnValue; taint | -| 88 | Summary: ::bytes; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 89 | Summary: ::chunk; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | -| 90 | Summary: ::text; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 91 | Summary: ::bytes; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 92 | Summary: ::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 93 | Summary: ::text_with_charset; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 94 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | -| 95 | Summary: ::read; Argument[self]; Argument[0]; taint | -| 96 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 97 | Summary: ::read_to_end; Argument[self]; Argument[0]; taint | -| 98 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 99 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | -| 100 | Summary: ::next; Argument[self]; ReturnValue.Field[core::option::Option::Some(0)].Field[core::result::Result::Ok(0)]; taint | -| 101 | Summary: ::fill_buf; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 102 | Summary: ::buffer; Argument[self]; ReturnValue; taint | -| 103 | Summary: ::new; Argument[0]; ReturnValue; taint | -| 104 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | -| 105 | Summary: ::read; Argument[self]; Argument[0]; taint | -| 106 | Summary: ::read_exact; Argument[self]; Argument[0].Reference; taint | -| 107 | Summary: ::read_exact; Argument[self]; Argument[0]; taint | -| 108 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 109 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 110 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | -| 111 | Summary: ::lock; Argument[self]; ReturnValue; taint | -| 112 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 113 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | -| 114 | Summary: ::as_path; Argument[self]; ReturnValue; value | -| 115 | Summary: ::buffer; Argument[self]; ReturnValue; taint | -| 116 | Summary: ::new; Argument[0]; ReturnValue; taint | -| 117 | Summary: ::next_line; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | -| 118 | Summary: ::next_segment; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | -| 119 | Summary: ::peek; Argument[self]; Argument[0].Reference; taint | -| 120 | Summary: ::try_read; Argument[self]; Argument[0].Reference; taint | -| 121 | Summary: ::try_read_buf; Argument[self]; Argument[0].Reference; taint | +| 35 | Summary: <_ as async_std::io::read::ReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint | +| 36 | Summary: <_ as async_std::io::read::ReadExt>::read; Argument[self]; Argument[0].Reference; taint | +| 37 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value | +| 38 | Summary: <_ as core::iter::traits::iterator::Iterator>::collect; Argument[self].Element; ReturnValue.Element; value | +| 39 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Element; ReturnValue.Field[core::option::Option::Some(0)]; value | +| 40 | Summary: <_ as futures_io::if_std::AsyncBufRead>::poll_fill_buf; Argument[self].Reference; ReturnValue.Field[core::task::poll::Poll::Ready(0)].Field[core::result::Result::Ok(0)]; taint | +| 41 | Summary: <_ as futures_util::io::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 42 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self].Reference; Argument[0].Reference; taint | +| 43 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | +| 44 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self].Reference; Argument[1].Reference; taint | +| 45 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | +| 46 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint | +| 47 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | +| 48 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self].Reference; Argument[0].Reference; taint | +| 49 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 50 | Summary: <_ as std::io::BufRead>::lines; Argument[self]; ReturnValue; taint | +| 51 | Summary: <_ as std::io::BufRead>::read_line; Argument[self]; Argument[0].Reference; taint | +| 52 | Summary: <_ as std::io::BufRead>::read_until; Argument[self]; Argument[1].Reference; taint | +| 53 | Summary: <_ as std::io::BufRead>::split; Argument[self]; ReturnValue; taint | +| 54 | Summary: <_ as std::io::Read>::bytes; Argument[self]; ReturnValue; taint | +| 55 | Summary: <_ as std::io::Read>::chain; Argument[0]; ReturnValue; taint | +| 56 | Summary: <_ as std::io::Read>::chain; Argument[self]; ReturnValue; taint | +| 57 | Summary: <_ as std::io::Read>::read; Argument[self]; Argument[0].Reference; taint | +| 58 | Summary: <_ as std::io::Read>::read_exact; Argument[self]; Argument[0].Reference; taint | +| 59 | Summary: <_ as std::io::Read>::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 60 | Summary: <_ as std::io::Read>::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 61 | Summary: <_ as std::io::Read>::take; Argument[self]; ReturnValue; taint | +| 62 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 63 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::lines; Argument[self]; ReturnValue; taint | +| 64 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | +| 65 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | +| 66 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::split; Argument[self]; ReturnValue; taint | +| 67 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | +| 68 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_buf; Argument[self]; Argument[0].Reference; taint | +| 69 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_exact; Argument[self]; Argument[0].Reference; taint | +| 70 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_f32; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 71 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i16; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 72 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i64_le; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 73 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 74 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 75 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_u8; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 76 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | +| 77 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 78 | Summary: ::expect; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | +| 79 | Summary: ::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | +| 80 | Summary: ::new; Argument[0].Reference; ReturnValue; value | +| 81 | Summary: ::new; Argument[0]; ReturnValue.Field[core::pin::Pin::__pointer]; value | +| 82 | Summary: ::new; Argument[0]; ReturnValue; value | +| 83 | Summary: ::expect; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | +| 84 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | +| 85 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | +| 86 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 87 | Summary: ::parse; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 88 | Summary: ::connect; Argument[1]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 89 | Summary: ::new; Argument[0]; ReturnValue; taint | +| 90 | Summary: ::bytes; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 91 | Summary: ::chunk; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | +| 92 | Summary: ::text; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 93 | Summary: ::bytes; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 94 | Summary: ::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 95 | Summary: ::text_with_charset; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 96 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | +| 97 | Summary: ::read; Argument[self]; Argument[0]; taint | +| 98 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 99 | Summary: ::read_to_end; Argument[self]; Argument[0]; taint | +| 100 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 101 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | +| 102 | Summary: ::next; Argument[self]; ReturnValue.Field[core::option::Option::Some(0)].Field[core::result::Result::Ok(0)]; taint | +| 103 | Summary: ::fill_buf; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 104 | Summary: ::buffer; Argument[self]; ReturnValue; taint | +| 105 | Summary: ::new; Argument[0]; ReturnValue; taint | +| 106 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | +| 107 | Summary: ::read; Argument[self]; Argument[0]; taint | +| 108 | Summary: ::read_exact; Argument[self]; Argument[0].Reference; taint | +| 109 | Summary: ::read_exact; Argument[self]; Argument[0]; taint | +| 110 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 111 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 112 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | +| 113 | Summary: ::lock; Argument[self]; ReturnValue; taint | +| 114 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 115 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | +| 116 | Summary: ::as_path; Argument[self]; ReturnValue; value | +| 117 | Summary: ::buffer; Argument[self]; ReturnValue; taint | +| 118 | Summary: ::new; Argument[0]; ReturnValue; taint | +| 119 | Summary: ::next_line; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | +| 120 | Summary: ::next_segment; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | +| 121 | Summary: ::peek; Argument[self]; Argument[0].Reference; taint | +| 122 | Summary: ::try_read; Argument[self]; Argument[0].Reference; taint | +| 123 | Summary: ::try_read_buf; Argument[self]; Argument[0].Reference; taint | edges | test.rs:8:10:8:22 | ...::var | test.rs:8:10:8:30 | ...::var(...) | provenance | Src:MaD:23 | | test.rs:9:10:9:25 | ...::var_os | test.rs:9:10:9:33 | ...::var_os(...) | provenance | Src:MaD:24 | | test.rs:11:9:11:12 | var1 | test.rs:14:10:14:13 | var1 | provenance | | | test.rs:11:16:11:28 | ...::var | test.rs:11:16:11:36 | ...::var(...) [Ok] | provenance | Src:MaD:23 | -| test.rs:11:16:11:36 | ...::var(...) [Ok] | test.rs:11:16:11:59 | ... .expect(...) | provenance | MaD:81 | +| test.rs:11:16:11:36 | ...::var(...) [Ok] | test.rs:11:16:11:59 | ... .expect(...) | provenance | MaD:83 | | test.rs:11:16:11:59 | ... .expect(...) | test.rs:11:9:11:12 | var1 | provenance | | | test.rs:12:9:12:12 | var2 | test.rs:15:10:15:13 | var2 | provenance | | | test.rs:12:16:12:31 | ...::var_os | test.rs:12:16:12:39 | ...::var_os(...) [Some] | provenance | Src:MaD:24 | -| test.rs:12:16:12:39 | ...::var_os(...) [Some] | test.rs:12:16:12:48 | ... .unwrap() | provenance | MaD:77 | +| test.rs:12:16:12:39 | ...::var_os(...) [Some] | test.rs:12:16:12:48 | ... .unwrap() | provenance | MaD:79 | | test.rs:12:16:12:48 | ... .unwrap() | test.rs:12:9:12:12 | var2 | provenance | | | test.rs:29:9:29:12 | args [element] | test.rs:30:20:30:23 | args [element] | provenance | | | test.rs:29:9:29:12 | args [element] | test.rs:31:17:31:20 | args [element] | provenance | | | test.rs:29:29:29:42 | ...::args | test.rs:29:29:29:44 | ...::args(...) [element] | provenance | Src:MaD:18 | -| test.rs:29:29:29:44 | ...::args(...) [element] | test.rs:29:29:29:54 | ... .collect() [element] | provenance | MaD:36 | +| test.rs:29:29:29:44 | ...::args(...) [element] | test.rs:29:29:29:54 | ... .collect() [element] | provenance | MaD:38 | | test.rs:29:29:29:54 | ... .collect() [element] | test.rs:29:9:29:12 | args [element] | provenance | | | test.rs:30:9:30:15 | my_path [&ref] | test.rs:36:10:36:16 | my_path | provenance | | | test.rs:30:19:30:26 | &... [&ref] | test.rs:30:9:30:15 | my_path [&ref] | provenance | | @@ -146,20 +148,20 @@ edges | test.rs:31:17:31:23 | args[1] | test.rs:31:16:31:23 | &... [&ref] | provenance | | | test.rs:32:9:32:12 | arg2 | test.rs:38:10:38:13 | arg2 | provenance | | | test.rs:32:16:32:29 | ...::args | test.rs:32:16:32:31 | ...::args(...) [element] | provenance | Src:MaD:18 | -| test.rs:32:16:32:31 | ...::args(...) [element] | test.rs:32:16:32:38 | ... .nth(...) [Some] | provenance | MaD:37 | -| test.rs:32:16:32:38 | ... .nth(...) [Some] | test.rs:32:16:32:47 | ... .unwrap() | provenance | MaD:77 | +| test.rs:32:16:32:31 | ...::args(...) [element] | test.rs:32:16:32:38 | ... .nth(...) [Some] | provenance | MaD:39 | +| test.rs:32:16:32:38 | ... .nth(...) [Some] | test.rs:32:16:32:47 | ... .unwrap() | provenance | MaD:79 | | test.rs:32:16:32:47 | ... .unwrap() | test.rs:32:9:32:12 | arg2 | provenance | | | test.rs:33:9:33:12 | arg3 | test.rs:39:10:39:13 | arg3 | provenance | | | test.rs:33:16:33:32 | ...::args_os | test.rs:33:16:33:34 | ...::args_os(...) [element] | provenance | Src:MaD:19 | -| test.rs:33:16:33:34 | ...::args_os(...) [element] | test.rs:33:16:33:41 | ... .nth(...) [Some] | provenance | MaD:37 | -| test.rs:33:16:33:41 | ... .nth(...) [Some] | test.rs:33:16:33:50 | ... .unwrap() | provenance | MaD:77 | +| test.rs:33:16:33:34 | ...::args_os(...) [element] | test.rs:33:16:33:41 | ... .nth(...) [Some] | provenance | MaD:39 | +| test.rs:33:16:33:41 | ... .nth(...) [Some] | test.rs:33:16:33:50 | ... .unwrap() | provenance | MaD:79 | | test.rs:33:16:33:50 | ... .unwrap() | test.rs:33:9:33:12 | arg3 | provenance | | | test.rs:34:9:34:12 | arg4 | test.rs:40:10:40:13 | arg4 | provenance | | | test.rs:34:16:34:29 | ...::args | test.rs:34:16:34:31 | ...::args(...) [element] | provenance | Src:MaD:18 | -| test.rs:34:16:34:31 | ...::args(...) [element] | test.rs:34:16:34:38 | ... .nth(...) [Some] | provenance | MaD:37 | -| test.rs:34:16:34:38 | ... .nth(...) [Some] | test.rs:34:16:34:47 | ... .unwrap() | provenance | MaD:77 | -| test.rs:34:16:34:47 | ... .unwrap() | test.rs:34:16:34:64 | ... .parse() [Ok] | provenance | MaD:85 | -| test.rs:34:16:34:64 | ... .parse() [Ok] | test.rs:34:16:34:73 | ... .unwrap() | provenance | MaD:82 | +| test.rs:34:16:34:31 | ...::args(...) [element] | test.rs:34:16:34:38 | ... .nth(...) [Some] | provenance | MaD:39 | +| test.rs:34:16:34:38 | ... .nth(...) [Some] | test.rs:34:16:34:47 | ... .unwrap() | provenance | MaD:79 | +| test.rs:34:16:34:47 | ... .unwrap() | test.rs:34:16:34:64 | ... .parse() [Ok] | provenance | MaD:87 | +| test.rs:34:16:34:64 | ... .parse() [Ok] | test.rs:34:16:34:73 | ... .unwrap() | provenance | MaD:84 | | test.rs:34:16:34:73 | ... .unwrap() | test.rs:34:9:34:12 | arg4 | provenance | | | test.rs:42:9:42:11 | arg | test.rs:43:14:43:16 | arg | provenance | | | test.rs:42:16:42:29 | ...::args | test.rs:42:16:42:31 | ...::args(...) [element] | provenance | Src:MaD:18 | @@ -169,45 +171,45 @@ edges | test.rs:46:16:46:34 | ...::args_os(...) [element] | test.rs:46:9:46:11 | arg | provenance | | | test.rs:52:9:52:11 | dir | test.rs:56:10:56:12 | dir | provenance | | | test.rs:52:15:52:35 | ...::current_dir | test.rs:52:15:52:37 | ...::current_dir(...) [Ok] | provenance | Src:MaD:20 | -| test.rs:52:15:52:37 | ...::current_dir(...) [Ok] | test.rs:52:15:52:54 | ... .expect(...) | provenance | MaD:81 | +| test.rs:52:15:52:37 | ...::current_dir(...) [Ok] | test.rs:52:15:52:54 | ... .expect(...) | provenance | MaD:83 | | test.rs:52:15:52:54 | ... .expect(...) | test.rs:52:9:52:11 | dir | provenance | | | test.rs:53:9:53:11 | exe | test.rs:57:10:57:12 | exe | provenance | | | test.rs:53:15:53:35 | ...::current_exe | test.rs:53:15:53:37 | ...::current_exe(...) [Ok] | provenance | Src:MaD:21 | -| test.rs:53:15:53:37 | ...::current_exe(...) [Ok] | test.rs:53:15:53:54 | ... .expect(...) | provenance | MaD:81 | +| test.rs:53:15:53:37 | ...::current_exe(...) [Ok] | test.rs:53:15:53:54 | ... .expect(...) | provenance | MaD:83 | | test.rs:53:15:53:54 | ... .expect(...) | test.rs:53:9:53:11 | exe | provenance | | | test.rs:54:9:54:12 | home | test.rs:58:10:58:13 | home | provenance | | | test.rs:54:16:54:33 | ...::home_dir | test.rs:54:16:54:35 | ...::home_dir(...) [Some] | provenance | Src:MaD:22 | -| test.rs:54:16:54:35 | ...::home_dir(...) [Some] | test.rs:54:16:54:52 | ... .expect(...) | provenance | MaD:76 | +| test.rs:54:16:54:35 | ...::home_dir(...) [Some] | test.rs:54:16:54:52 | ... .expect(...) | provenance | MaD:78 | | test.rs:54:16:54:52 | ... .expect(...) | test.rs:54:9:54:12 | home | provenance | | | test.rs:62:9:62:22 | remote_string1 | test.rs:63:10:63:23 | remote_string1 | provenance | | | test.rs:62:26:62:47 | ...::get | test.rs:62:26:62:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | | test.rs:62:26:62:62 | ...::get(...) [Ok] | test.rs:62:26:62:63 | TryExpr | provenance | | -| test.rs:62:26:62:63 | TryExpr | test.rs:62:26:62:70 | ... .text() [Ok] | provenance | MaD:92 | +| test.rs:62:26:62:63 | TryExpr | test.rs:62:26:62:70 | ... .text() [Ok] | provenance | MaD:94 | | test.rs:62:26:62:70 | ... .text() [Ok] | test.rs:62:26:62:71 | TryExpr | provenance | | | test.rs:62:26:62:71 | TryExpr | test.rs:62:9:62:22 | remote_string1 | provenance | | | test.rs:65:9:65:22 | remote_string2 | test.rs:66:10:66:23 | remote_string2 | provenance | | | test.rs:65:26:65:47 | ...::get | test.rs:65:26:65:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | -| test.rs:65:26:65:62 | ...::get(...) [Ok] | test.rs:65:26:65:71 | ... .unwrap() | provenance | MaD:82 | -| test.rs:65:26:65:71 | ... .unwrap() | test.rs:65:26:65:78 | ... .text() [Ok] | provenance | MaD:92 | -| test.rs:65:26:65:78 | ... .text() [Ok] | test.rs:65:26:65:87 | ... .unwrap() | provenance | MaD:82 | +| test.rs:65:26:65:62 | ...::get(...) [Ok] | test.rs:65:26:65:71 | ... .unwrap() | provenance | MaD:84 | +| test.rs:65:26:65:71 | ... .unwrap() | test.rs:65:26:65:78 | ... .text() [Ok] | provenance | MaD:94 | +| test.rs:65:26:65:78 | ... .text() [Ok] | test.rs:65:26:65:87 | ... .unwrap() | provenance | MaD:84 | | test.rs:65:26:65:87 | ... .unwrap() | test.rs:65:9:65:22 | remote_string2 | provenance | | | test.rs:68:9:68:22 | remote_string3 | test.rs:69:10:69:23 | remote_string3 | provenance | | | test.rs:68:26:68:47 | ...::get | test.rs:68:26:68:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | -| test.rs:68:26:68:62 | ...::get(...) [Ok] | test.rs:68:26:68:71 | ... .unwrap() | provenance | MaD:82 | -| test.rs:68:26:68:71 | ... .unwrap() | test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | provenance | MaD:93 | -| test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | test.rs:68:26:68:107 | ... .unwrap() | provenance | MaD:82 | +| test.rs:68:26:68:62 | ...::get(...) [Ok] | test.rs:68:26:68:71 | ... .unwrap() | provenance | MaD:84 | +| test.rs:68:26:68:71 | ... .unwrap() | test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | provenance | MaD:95 | +| test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | test.rs:68:26:68:107 | ... .unwrap() | provenance | MaD:84 | | test.rs:68:26:68:107 | ... .unwrap() | test.rs:68:9:68:22 | remote_string3 | provenance | | | test.rs:71:9:71:22 | remote_string4 | test.rs:72:10:72:23 | remote_string4 | provenance | | | test.rs:71:26:71:47 | ...::get | test.rs:71:26:71:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | -| test.rs:71:26:71:62 | ...::get(...) [Ok] | test.rs:71:26:71:71 | ... .unwrap() | provenance | MaD:82 | -| test.rs:71:26:71:71 | ... .unwrap() | test.rs:71:26:71:79 | ... .bytes() [Ok] | provenance | MaD:91 | -| test.rs:71:26:71:79 | ... .bytes() [Ok] | test.rs:71:26:71:88 | ... .unwrap() | provenance | MaD:82 | +| test.rs:71:26:71:62 | ...::get(...) [Ok] | test.rs:71:26:71:71 | ... .unwrap() | provenance | MaD:84 | +| test.rs:71:26:71:71 | ... .unwrap() | test.rs:71:26:71:79 | ... .bytes() [Ok] | provenance | MaD:93 | +| test.rs:71:26:71:79 | ... .bytes() [Ok] | test.rs:71:26:71:88 | ... .unwrap() | provenance | MaD:84 | | test.rs:71:26:71:88 | ... .unwrap() | test.rs:71:9:71:22 | remote_string4 | provenance | | | test.rs:74:9:74:22 | remote_string5 | test.rs:75:10:75:23 | remote_string5 | provenance | | | test.rs:74:26:74:37 | ...::get | test.rs:74:26:74:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:17 | | test.rs:74:26:74:52 | ...::get(...) [future, Ok] | test.rs:74:26:74:58 | await ... [Ok] | provenance | | | test.rs:74:26:74:58 | await ... [Ok] | test.rs:74:26:74:59 | TryExpr | provenance | | -| test.rs:74:26:74:59 | TryExpr | test.rs:74:26:74:66 | ... .text() [future, Ok] | provenance | MaD:90 | +| test.rs:74:26:74:59 | TryExpr | test.rs:74:26:74:66 | ... .text() [future, Ok] | provenance | MaD:92 | | test.rs:74:26:74:66 | ... .text() [future, Ok] | test.rs:74:26:74:72 | await ... [Ok] | provenance | | | test.rs:74:26:74:72 | await ... [Ok] | test.rs:74:26:74:73 | TryExpr | provenance | | | test.rs:74:26:74:73 | TryExpr | test.rs:74:9:74:22 | remote_string5 | provenance | | @@ -215,19 +217,19 @@ edges | test.rs:77:26:77:37 | ...::get | test.rs:77:26:77:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:17 | | test.rs:77:26:77:52 | ...::get(...) [future, Ok] | test.rs:77:26:77:58 | await ... [Ok] | provenance | | | test.rs:77:26:77:58 | await ... [Ok] | test.rs:77:26:77:59 | TryExpr | provenance | | -| test.rs:77:26:77:59 | TryExpr | test.rs:77:26:77:67 | ... .bytes() [future, Ok] | provenance | MaD:88 | +| test.rs:77:26:77:59 | TryExpr | test.rs:77:26:77:67 | ... .bytes() [future, Ok] | provenance | MaD:90 | | test.rs:77:26:77:67 | ... .bytes() [future, Ok] | test.rs:77:26:77:73 | await ... [Ok] | provenance | | | test.rs:77:26:77:73 | await ... [Ok] | test.rs:77:26:77:74 | TryExpr | provenance | | | test.rs:77:26:77:74 | TryExpr | test.rs:77:9:77:22 | remote_string6 | provenance | | -| test.rs:80:9:80:20 | mut request1 | test.rs:81:10:81:25 | request1.chunk() [future, Ok, Some] | provenance | MaD:89 | -| test.rs:80:9:80:20 | mut request1 | test.rs:82:29:82:44 | request1.chunk() [future, Ok, Some] | provenance | MaD:89 | +| test.rs:80:9:80:20 | mut request1 | test.rs:81:10:81:25 | request1.chunk() [future, Ok, Some] | provenance | MaD:91 | +| test.rs:80:9:80:20 | mut request1 | test.rs:82:29:82:44 | request1.chunk() [future, Ok, Some] | provenance | MaD:91 | | test.rs:80:24:80:35 | ...::get | test.rs:80:24:80:50 | ...::get(...) [future, Ok] | provenance | Src:MaD:17 | | test.rs:80:24:80:50 | ...::get(...) [future, Ok] | test.rs:80:24:80:56 | await ... [Ok] | provenance | | | test.rs:80:24:80:56 | await ... [Ok] | test.rs:80:24:80:57 | TryExpr | provenance | | | test.rs:80:24:80:57 | TryExpr | test.rs:80:9:80:20 | mut request1 | provenance | | | test.rs:81:10:81:25 | request1.chunk() [future, Ok, Some] | test.rs:81:10:81:31 | await ... [Ok, Some] | provenance | | | test.rs:81:10:81:31 | await ... [Ok, Some] | test.rs:81:10:81:32 | TryExpr [Some] | provenance | | -| test.rs:81:10:81:32 | TryExpr [Some] | test.rs:81:10:81:41 | ... .unwrap() | provenance | MaD:77 | +| test.rs:81:10:81:32 | TryExpr [Some] | test.rs:81:10:81:41 | ... .unwrap() | provenance | MaD:79 | | test.rs:82:15:82:25 | Some(...) [Some] | test.rs:82:20:82:24 | chunk | provenance | | | test.rs:82:20:82:24 | chunk | test.rs:83:14:83:18 | chunk | provenance | | | test.rs:82:29:82:44 | request1.chunk() [future, Ok, Some] | test.rs:82:29:82:50 | await ... [Ok, Some] | provenance | | @@ -247,119 +249,119 @@ edges | test.rs:121:31:121:42 | send_request | test.rs:121:24:121:51 | sender.send_request(...) [future, Ok] | provenance | Src:MaD:4 | | test.rs:122:11:122:18 | response | test.rs:122:10:122:18 | &response | provenance | | | test.rs:211:22:211:35 | ...::stdin | test.rs:211:22:211:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer | provenance | MaD:105 | -| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:55 | -| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:104 | +| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer | provenance | MaD:107 | +| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:57 | +| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:106 | | test.rs:211:44:211:54 | [post] &mut buffer | test.rs:212:15:212:20 | buffer | provenance | | | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | test.rs:211:49:211:54 | [post] buffer | provenance | | | test.rs:211:49:211:54 | [post] buffer | test.rs:212:15:212:20 | buffer | provenance | | | test.rs:212:15:212:20 | buffer | test.rs:212:14:212:20 | &buffer | provenance | | | test.rs:217:22:217:35 | ...::stdin | test.rs:217:22:217:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:57 | -| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:108 | +| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:59 | +| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:110 | | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | test.rs:217:56:217:61 | [post] buffer | provenance | | | test.rs:217:56:217:61 | [post] buffer | test.rs:218:15:218:20 | buffer | provenance | | | test.rs:218:15:218:20 | buffer | test.rs:218:14:218:20 | &buffer | provenance | | | test.rs:223:22:223:35 | ...::stdin | test.rs:223:22:223:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer | provenance | MaD:110 | -| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:58 | -| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:109 | +| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer | provenance | MaD:112 | +| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:111 | | test.rs:223:54:223:64 | [post] &mut buffer | test.rs:224:15:224:20 | buffer | provenance | | | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | test.rs:223:59:223:64 | [post] buffer | provenance | | | test.rs:223:59:223:64 | [post] buffer | test.rs:224:15:224:20 | buffer | provenance | | | test.rs:224:15:224:20 | buffer | test.rs:224:14:224:20 | &buffer | provenance | | | test.rs:229:22:229:35 | ...::stdin | test.rs:229:22:229:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:229:22:229:37 | ...::stdin(...) | test.rs:229:22:229:44 | ... .lock() | provenance | MaD:111 | -| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:58 | -| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:112 | +| test.rs:229:22:229:37 | ...::stdin(...) | test.rs:229:22:229:44 | ... .lock() | provenance | MaD:113 | +| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:114 | | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | test.rs:229:66:229:71 | [post] buffer | provenance | | | test.rs:229:66:229:71 | [post] buffer | test.rs:230:15:230:20 | buffer | provenance | | | test.rs:230:15:230:20 | buffer | test.rs:230:14:230:20 | &buffer | provenance | | | test.rs:235:9:235:22 | ...::stdin | test.rs:235:9:235:24 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer | provenance | MaD:107 | -| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:56 | -| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:106 | +| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer | provenance | MaD:109 | +| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:58 | +| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:108 | | test.rs:235:37:235:47 | [post] &mut buffer | test.rs:236:15:236:20 | buffer | provenance | | | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | test.rs:235:42:235:47 | [post] buffer | provenance | | | test.rs:235:42:235:47 | [post] buffer | test.rs:236:15:236:20 | buffer | provenance | | | test.rs:236:15:236:20 | buffer | test.rs:236:14:236:20 | &buffer | provenance | | | test.rs:239:17:239:30 | ...::stdin | test.rs:239:17:239:32 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:239:17:239:32 | ...::stdin(...) | test.rs:239:17:239:40 | ... .bytes() | provenance | MaD:52 | +| test.rs:239:17:239:32 | ...::stdin(...) | test.rs:239:17:239:40 | ... .bytes() | provenance | MaD:54 | | test.rs:239:17:239:40 | ... .bytes() | test.rs:240:14:240:17 | byte | provenance | | -| test.rs:246:13:246:22 | mut reader | test.rs:247:20:247:36 | reader.fill_buf() [Ok] | provenance | MaD:101 | +| test.rs:246:13:246:22 | mut reader | test.rs:247:20:247:36 | reader.fill_buf() [Ok] | provenance | MaD:103 | | test.rs:246:26:246:66 | ...::new(...) | test.rs:246:13:246:22 | mut reader | provenance | | | test.rs:246:50:246:63 | ...::stdin | test.rs:246:50:246:65 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:246:50:246:65 | ...::stdin(...) | test.rs:246:26:246:66 | ...::new(...) | provenance | MaD:103 | +| test.rs:246:50:246:65 | ...::stdin(...) | test.rs:246:26:246:66 | ...::new(...) | provenance | MaD:105 | | test.rs:247:13:247:16 | data | test.rs:248:15:248:18 | data | provenance | | | test.rs:247:20:247:36 | reader.fill_buf() [Ok] | test.rs:247:20:247:37 | TryExpr | provenance | | | test.rs:247:20:247:37 | TryExpr | test.rs:247:13:247:16 | data | provenance | | | test.rs:248:15:248:18 | data | test.rs:248:14:248:18 | &data | provenance | | -| test.rs:252:13:252:18 | reader | test.rs:253:20:253:34 | reader.buffer() | provenance | MaD:102 | +| test.rs:252:13:252:18 | reader | test.rs:253:20:253:34 | reader.buffer() | provenance | MaD:104 | | test.rs:252:22:252:62 | ...::new(...) | test.rs:252:13:252:18 | reader | provenance | | | test.rs:252:46:252:59 | ...::stdin | test.rs:252:46:252:61 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:252:46:252:61 | ...::stdin(...) | test.rs:252:22:252:62 | ...::new(...) | provenance | MaD:103 | +| test.rs:252:46:252:61 | ...::stdin(...) | test.rs:252:22:252:62 | ...::new(...) | provenance | MaD:105 | | test.rs:253:13:253:16 | data | test.rs:254:15:254:18 | data | provenance | | | test.rs:253:20:253:34 | reader.buffer() | test.rs:253:13:253:16 | data | provenance | | | test.rs:254:15:254:18 | data | test.rs:254:14:254:18 | &data | provenance | | -| test.rs:259:13:259:22 | mut reader | test.rs:260:26:260:36 | [post] &mut buffer [&ref] | provenance | MaD:49 | +| test.rs:259:13:259:22 | mut reader | test.rs:260:26:260:36 | [post] &mut buffer [&ref] | provenance | MaD:51 | | test.rs:259:26:259:66 | ...::new(...) | test.rs:259:13:259:22 | mut reader | provenance | | | test.rs:259:50:259:63 | ...::stdin | test.rs:259:50:259:65 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:259:50:259:65 | ...::stdin(...) | test.rs:259:26:259:66 | ...::new(...) | provenance | MaD:103 | +| test.rs:259:50:259:65 | ...::stdin(...) | test.rs:259:26:259:66 | ...::new(...) | provenance | MaD:105 | | test.rs:260:26:260:36 | [post] &mut buffer [&ref] | test.rs:260:31:260:36 | [post] buffer | provenance | | | test.rs:260:31:260:36 | [post] buffer | test.rs:261:15:261:20 | buffer | provenance | | | test.rs:261:15:261:20 | buffer | test.rs:261:14:261:20 | &buffer | provenance | | -| test.rs:266:13:266:22 | mut reader | test.rs:267:33:267:43 | [post] &mut buffer [&ref] | provenance | MaD:50 | +| test.rs:266:13:266:22 | mut reader | test.rs:267:33:267:43 | [post] &mut buffer [&ref] | provenance | MaD:52 | | test.rs:266:26:266:66 | ...::new(...) | test.rs:266:13:266:22 | mut reader | provenance | | | test.rs:266:50:266:63 | ...::stdin | test.rs:266:50:266:65 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:266:50:266:65 | ...::stdin(...) | test.rs:266:26:266:66 | ...::new(...) | provenance | MaD:103 | +| test.rs:266:50:266:65 | ...::stdin(...) | test.rs:266:26:266:66 | ...::new(...) | provenance | MaD:105 | | test.rs:267:33:267:43 | [post] &mut buffer [&ref] | test.rs:267:38:267:43 | [post] buffer | provenance | | | test.rs:267:38:267:43 | [post] buffer | test.rs:268:15:268:20 | buffer | provenance | | | test.rs:267:38:267:43 | [post] buffer | test.rs:269:14:269:22 | buffer[0] | provenance | | | test.rs:268:15:268:20 | buffer | test.rs:268:14:268:20 | &buffer | provenance | | -| test.rs:273:13:273:28 | mut reader_split | test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | provenance | MaD:100 | -| test.rs:273:13:273:28 | mut reader_split | test.rs:275:33:275:51 | reader_split.next() [Some, Ok] | provenance | MaD:100 | -| test.rs:273:32:273:72 | ...::new(...) | test.rs:273:32:273:84 | ... .split(...) | provenance | MaD:51 | +| test.rs:273:13:273:28 | mut reader_split | test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | provenance | MaD:102 | +| test.rs:273:13:273:28 | mut reader_split | test.rs:275:33:275:51 | reader_split.next() [Some, Ok] | provenance | MaD:102 | +| test.rs:273:32:273:72 | ...::new(...) | test.rs:273:32:273:84 | ... .split(...) | provenance | MaD:53 | | test.rs:273:32:273:84 | ... .split(...) | test.rs:273:13:273:28 | mut reader_split | provenance | | | test.rs:273:56:273:69 | ...::stdin | test.rs:273:56:273:71 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:273:56:273:71 | ...::stdin(...) | test.rs:273:32:273:72 | ...::new(...) | provenance | MaD:103 | -| test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | test.rs:274:14:274:41 | ... .unwrap() [Ok] | provenance | MaD:77 | -| test.rs:274:14:274:41 | ... .unwrap() [Ok] | test.rs:274:14:274:50 | ... .unwrap() | provenance | MaD:82 | +| test.rs:273:56:273:71 | ...::stdin(...) | test.rs:273:32:273:72 | ...::new(...) | provenance | MaD:105 | +| test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | test.rs:274:14:274:41 | ... .unwrap() [Ok] | provenance | MaD:79 | +| test.rs:274:14:274:41 | ... .unwrap() [Ok] | test.rs:274:14:274:50 | ... .unwrap() | provenance | MaD:84 | | test.rs:275:19:275:29 | Some(...) [Some, Ok] | test.rs:275:24:275:28 | chunk [Ok] | provenance | | -| test.rs:275:24:275:28 | chunk [Ok] | test.rs:276:18:276:31 | chunk.unwrap() | provenance | MaD:82 | +| test.rs:275:24:275:28 | chunk [Ok] | test.rs:276:18:276:31 | chunk.unwrap() | provenance | MaD:84 | | test.rs:275:33:275:51 | reader_split.next() [Some, Ok] | test.rs:275:19:275:29 | Some(...) [Some, Ok] | provenance | | -| test.rs:281:13:281:18 | reader | test.rs:282:21:282:34 | reader.lines() | provenance | MaD:48 | +| test.rs:281:13:281:18 | reader | test.rs:282:21:282:34 | reader.lines() | provenance | MaD:50 | | test.rs:281:22:281:62 | ...::new(...) | test.rs:281:13:281:18 | reader | provenance | | | test.rs:281:46:281:59 | ...::stdin | test.rs:281:46:281:61 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:281:46:281:61 | ...::stdin(...) | test.rs:281:22:281:62 | ...::new(...) | provenance | MaD:103 | +| test.rs:281:46:281:61 | ...::stdin(...) | test.rs:281:22:281:62 | ...::new(...) | provenance | MaD:105 | | test.rs:282:21:282:34 | reader.lines() | test.rs:283:18:283:21 | line | provenance | | -| test.rs:309:13:309:21 | mut stdin | test.rs:311:33:311:43 | [post] &mut buffer [&ref] | provenance | MaD:65 | +| test.rs:309:13:309:21 | mut stdin | test.rs:311:33:311:43 | [post] &mut buffer [&ref] | provenance | MaD:67 | | test.rs:309:25:309:40 | ...::stdin | test.rs:309:25:309:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:309:25:309:42 | ...::stdin(...) | test.rs:309:13:309:21 | mut stdin | provenance | | | test.rs:311:33:311:43 | [post] &mut buffer [&ref] | test.rs:311:38:311:43 | [post] buffer | provenance | | | test.rs:311:38:311:43 | [post] buffer | test.rs:312:15:312:20 | buffer | provenance | | | test.rs:312:15:312:20 | buffer | test.rs:312:14:312:20 | &buffer | provenance | | -| test.rs:316:13:316:21 | mut stdin | test.rs:318:40:318:50 | [post] &mut buffer [&ref] | provenance | MaD:71 | +| test.rs:316:13:316:21 | mut stdin | test.rs:318:40:318:50 | [post] &mut buffer [&ref] | provenance | MaD:73 | | test.rs:316:25:316:40 | ...::stdin | test.rs:316:25:316:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:316:25:316:42 | ...::stdin(...) | test.rs:316:13:316:21 | mut stdin | provenance | | | test.rs:318:40:318:50 | [post] &mut buffer [&ref] | test.rs:318:45:318:50 | [post] buffer | provenance | | | test.rs:318:45:318:50 | [post] buffer | test.rs:319:15:319:20 | buffer | provenance | | | test.rs:319:15:319:20 | buffer | test.rs:319:14:319:20 | &buffer | provenance | | -| test.rs:323:13:323:21 | mut stdin | test.rs:325:43:325:53 | [post] &mut buffer [&ref] | provenance | MaD:72 | +| test.rs:323:13:323:21 | mut stdin | test.rs:325:43:325:53 | [post] &mut buffer [&ref] | provenance | MaD:74 | | test.rs:323:25:323:40 | ...::stdin | test.rs:323:25:323:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:323:25:323:42 | ...::stdin(...) | test.rs:323:13:323:21 | mut stdin | provenance | | | test.rs:325:43:325:53 | [post] &mut buffer [&ref] | test.rs:325:48:325:53 | [post] buffer | provenance | | | test.rs:325:48:325:53 | [post] buffer | test.rs:326:15:326:20 | buffer | provenance | | | test.rs:326:15:326:20 | buffer | test.rs:326:14:326:20 | &buffer | provenance | | -| test.rs:330:13:330:21 | mut stdin | test.rs:332:26:332:36 | [post] &mut buffer [&ref] | provenance | MaD:67 | +| test.rs:330:13:330:21 | mut stdin | test.rs:332:26:332:36 | [post] &mut buffer [&ref] | provenance | MaD:69 | | test.rs:330:25:330:40 | ...::stdin | test.rs:330:25:330:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:330:25:330:42 | ...::stdin(...) | test.rs:330:13:330:21 | mut stdin | provenance | | | test.rs:332:26:332:36 | [post] &mut buffer [&ref] | test.rs:332:31:332:36 | [post] buffer | provenance | | | test.rs:332:31:332:36 | [post] buffer | test.rs:333:15:333:20 | buffer | provenance | | | test.rs:333:15:333:20 | buffer | test.rs:333:14:333:20 | &buffer | provenance | | -| test.rs:337:13:337:21 | mut stdin | test.rs:338:18:338:32 | stdin.read_u8() [future, Ok] | provenance | MaD:73 | -| test.rs:337:13:337:21 | mut stdin | test.rs:339:18:339:33 | stdin.read_i16() [future, Ok] | provenance | MaD:69 | -| test.rs:337:13:337:21 | mut stdin | test.rs:340:18:340:33 | stdin.read_f32() [future, Ok] | provenance | MaD:68 | -| test.rs:337:13:337:21 | mut stdin | test.rs:341:18:341:36 | stdin.read_i64_le() [future, Ok] | provenance | MaD:70 | +| test.rs:337:13:337:21 | mut stdin | test.rs:338:18:338:32 | stdin.read_u8() [future, Ok] | provenance | MaD:75 | +| test.rs:337:13:337:21 | mut stdin | test.rs:339:18:339:33 | stdin.read_i16() [future, Ok] | provenance | MaD:71 | +| test.rs:337:13:337:21 | mut stdin | test.rs:340:18:340:33 | stdin.read_f32() [future, Ok] | provenance | MaD:70 | +| test.rs:337:13:337:21 | mut stdin | test.rs:341:18:341:36 | stdin.read_i64_le() [future, Ok] | provenance | MaD:72 | | test.rs:337:25:337:40 | ...::stdin | test.rs:337:25:337:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:337:25:337:42 | ...::stdin(...) | test.rs:337:13:337:21 | mut stdin | provenance | | | test.rs:338:13:338:14 | v1 | test.rs:342:14:342:15 | v1 | provenance | | @@ -378,67 +380,67 @@ edges | test.rs:341:18:341:36 | stdin.read_i64_le() [future, Ok] | test.rs:341:18:341:42 | await ... [Ok] | provenance | | | test.rs:341:18:341:42 | await ... [Ok] | test.rs:341:18:341:43 | TryExpr | provenance | | | test.rs:341:18:341:43 | TryExpr | test.rs:341:13:341:14 | v4 | provenance | | -| test.rs:349:13:349:21 | mut stdin | test.rs:351:24:351:34 | [post] &mut buffer [&ref] | provenance | MaD:66 | +| test.rs:349:13:349:21 | mut stdin | test.rs:351:24:351:34 | [post] &mut buffer [&ref] | provenance | MaD:68 | | test.rs:349:25:349:40 | ...::stdin | test.rs:349:25:349:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | | test.rs:349:25:349:42 | ...::stdin(...) | test.rs:349:13:349:21 | mut stdin | provenance | | | test.rs:351:24:351:34 | [post] &mut buffer [&ref] | test.rs:351:29:351:34 | [post] buffer | provenance | | | test.rs:351:29:351:34 | [post] buffer | test.rs:352:15:352:20 | buffer | provenance | | | test.rs:352:15:352:20 | buffer | test.rs:352:14:352:20 | &buffer | provenance | | -| test.rs:358:13:358:22 | mut reader | test.rs:359:20:359:36 | reader.fill_buf() [future, Ok] | provenance | MaD:60 | +| test.rs:358:13:358:22 | mut reader | test.rs:359:20:359:36 | reader.fill_buf() [future, Ok] | provenance | MaD:62 | | test.rs:358:26:358:70 | ...::new(...) | test.rs:358:13:358:22 | mut reader | provenance | | | test.rs:358:52:358:67 | ...::stdin | test.rs:358:52:358:69 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:358:52:358:69 | ...::stdin(...) | test.rs:358:26:358:70 | ...::new(...) | provenance | MaD:116 | +| test.rs:358:52:358:69 | ...::stdin(...) | test.rs:358:26:358:70 | ...::new(...) | provenance | MaD:118 | | test.rs:359:13:359:16 | data | test.rs:360:15:360:18 | data | provenance | | | test.rs:359:20:359:36 | reader.fill_buf() [future, Ok] | test.rs:359:20:359:42 | await ... [Ok] | provenance | | | test.rs:359:20:359:42 | await ... [Ok] | test.rs:359:20:359:43 | TryExpr | provenance | | | test.rs:359:20:359:43 | TryExpr | test.rs:359:13:359:16 | data | provenance | | | test.rs:360:15:360:18 | data | test.rs:360:14:360:18 | &data | provenance | | -| test.rs:364:13:364:18 | reader | test.rs:365:20:365:34 | reader.buffer() | provenance | MaD:115 | +| test.rs:364:13:364:18 | reader | test.rs:365:20:365:34 | reader.buffer() | provenance | MaD:117 | | test.rs:364:22:364:66 | ...::new(...) | test.rs:364:13:364:18 | reader | provenance | | | test.rs:364:48:364:63 | ...::stdin | test.rs:364:48:364:65 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:364:48:364:65 | ...::stdin(...) | test.rs:364:22:364:66 | ...::new(...) | provenance | MaD:116 | +| test.rs:364:48:364:65 | ...::stdin(...) | test.rs:364:22:364:66 | ...::new(...) | provenance | MaD:118 | | test.rs:365:13:365:16 | data | test.rs:366:15:366:18 | data | provenance | | | test.rs:365:20:365:34 | reader.buffer() | test.rs:365:13:365:16 | data | provenance | | | test.rs:366:15:366:18 | data | test.rs:366:14:366:18 | &data | provenance | | -| test.rs:371:13:371:22 | mut reader | test.rs:372:26:372:36 | [post] &mut buffer [&ref] | provenance | MaD:62 | +| test.rs:371:13:371:22 | mut reader | test.rs:372:26:372:36 | [post] &mut buffer [&ref] | provenance | MaD:64 | | test.rs:371:26:371:70 | ...::new(...) | test.rs:371:13:371:22 | mut reader | provenance | | | test.rs:371:52:371:67 | ...::stdin | test.rs:371:52:371:69 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:371:52:371:69 | ...::stdin(...) | test.rs:371:26:371:70 | ...::new(...) | provenance | MaD:116 | +| test.rs:371:52:371:69 | ...::stdin(...) | test.rs:371:26:371:70 | ...::new(...) | provenance | MaD:118 | | test.rs:372:26:372:36 | [post] &mut buffer [&ref] | test.rs:372:31:372:36 | [post] buffer | provenance | | | test.rs:372:31:372:36 | [post] buffer | test.rs:373:15:373:20 | buffer | provenance | | | test.rs:373:15:373:20 | buffer | test.rs:373:14:373:20 | &buffer | provenance | | -| test.rs:378:13:378:22 | mut reader | test.rs:379:33:379:43 | [post] &mut buffer [&ref] | provenance | MaD:63 | +| test.rs:378:13:378:22 | mut reader | test.rs:379:33:379:43 | [post] &mut buffer [&ref] | provenance | MaD:65 | | test.rs:378:26:378:70 | ...::new(...) | test.rs:378:13:378:22 | mut reader | provenance | | | test.rs:378:52:378:67 | ...::stdin | test.rs:378:52:378:69 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:378:52:378:69 | ...::stdin(...) | test.rs:378:26:378:70 | ...::new(...) | provenance | MaD:116 | +| test.rs:378:52:378:69 | ...::stdin(...) | test.rs:378:26:378:70 | ...::new(...) | provenance | MaD:118 | | test.rs:379:33:379:43 | [post] &mut buffer [&ref] | test.rs:379:38:379:43 | [post] buffer | provenance | | | test.rs:379:38:379:43 | [post] buffer | test.rs:380:15:380:20 | buffer | provenance | | | test.rs:379:38:379:43 | [post] buffer | test.rs:381:14:381:22 | buffer[0] | provenance | | | test.rs:380:15:380:20 | buffer | test.rs:380:14:380:20 | &buffer | provenance | | -| test.rs:385:13:385:28 | mut reader_split | test.rs:386:14:386:40 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:118 | -| test.rs:385:13:385:28 | mut reader_split | test.rs:387:33:387:59 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:118 | -| test.rs:385:32:385:76 | ...::new(...) | test.rs:385:32:385:88 | ... .split(...) | provenance | MaD:64 | +| test.rs:385:13:385:28 | mut reader_split | test.rs:386:14:386:40 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:120 | +| test.rs:385:13:385:28 | mut reader_split | test.rs:387:33:387:59 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:120 | +| test.rs:385:32:385:76 | ...::new(...) | test.rs:385:32:385:88 | ... .split(...) | provenance | MaD:66 | | test.rs:385:32:385:88 | ... .split(...) | test.rs:385:13:385:28 | mut reader_split | provenance | | | test.rs:385:58:385:73 | ...::stdin | test.rs:385:58:385:75 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:385:58:385:75 | ...::stdin(...) | test.rs:385:32:385:76 | ...::new(...) | provenance | MaD:116 | +| test.rs:385:58:385:75 | ...::stdin(...) | test.rs:385:32:385:76 | ...::new(...) | provenance | MaD:118 | | test.rs:386:14:386:40 | reader_split.next_segment() [future, Ok, Some] | test.rs:386:14:386:46 | await ... [Ok, Some] | provenance | | | test.rs:386:14:386:46 | await ... [Ok, Some] | test.rs:386:14:386:47 | TryExpr [Some] | provenance | | -| test.rs:386:14:386:47 | TryExpr [Some] | test.rs:386:14:386:56 | ... .unwrap() | provenance | MaD:77 | +| test.rs:386:14:386:47 | TryExpr [Some] | test.rs:386:14:386:56 | ... .unwrap() | provenance | MaD:79 | | test.rs:387:19:387:29 | Some(...) [Some] | test.rs:387:24:387:28 | chunk | provenance | | | test.rs:387:24:387:28 | chunk | test.rs:388:18:388:22 | chunk | provenance | | | test.rs:387:33:387:59 | reader_split.next_segment() [future, Ok, Some] | test.rs:387:33:387:65 | await ... [Ok, Some] | provenance | | | test.rs:387:33:387:65 | await ... [Ok, Some] | test.rs:387:33:387:66 | TryExpr [Some] | provenance | | | test.rs:387:33:387:66 | TryExpr [Some] | test.rs:387:19:387:29 | Some(...) [Some] | provenance | | -| test.rs:393:13:393:18 | reader | test.rs:394:25:394:38 | reader.lines() | provenance | MaD:61 | +| test.rs:393:13:393:18 | reader | test.rs:394:25:394:38 | reader.lines() | provenance | MaD:63 | | test.rs:393:22:393:66 | ...::new(...) | test.rs:393:13:393:18 | reader | provenance | | | test.rs:393:48:393:63 | ...::stdin | test.rs:393:48:393:65 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:393:48:393:65 | ...::stdin(...) | test.rs:393:22:393:66 | ...::new(...) | provenance | MaD:116 | -| test.rs:394:13:394:21 | mut lines | test.rs:395:14:395:30 | lines.next_line() [future, Ok, Some] | provenance | MaD:117 | -| test.rs:394:13:394:21 | mut lines | test.rs:396:32:396:48 | lines.next_line() [future, Ok, Some] | provenance | MaD:117 | +| test.rs:393:48:393:65 | ...::stdin(...) | test.rs:393:22:393:66 | ...::new(...) | provenance | MaD:118 | +| test.rs:394:13:394:21 | mut lines | test.rs:395:14:395:30 | lines.next_line() [future, Ok, Some] | provenance | MaD:119 | +| test.rs:394:13:394:21 | mut lines | test.rs:396:32:396:48 | lines.next_line() [future, Ok, Some] | provenance | MaD:119 | | test.rs:394:25:394:38 | reader.lines() | test.rs:394:13:394:21 | mut lines | provenance | | | test.rs:395:14:395:30 | lines.next_line() [future, Ok, Some] | test.rs:395:14:395:36 | await ... [Ok, Some] | provenance | | | test.rs:395:14:395:36 | await ... [Ok, Some] | test.rs:395:14:395:37 | TryExpr [Some] | provenance | | -| test.rs:395:14:395:37 | TryExpr [Some] | test.rs:395:14:395:46 | ... .unwrap() | provenance | MaD:77 | +| test.rs:395:14:395:37 | TryExpr [Some] | test.rs:395:14:395:46 | ... .unwrap() | provenance | MaD:79 | | test.rs:396:19:396:28 | Some(...) [Some] | test.rs:396:24:396:27 | line | provenance | | | test.rs:396:24:396:27 | line | test.rs:397:18:397:21 | line | provenance | | | test.rs:396:32:396:48 | lines.next_line() [future, Ok, Some] | test.rs:396:32:396:54 | await ... [Ok, Some] | provenance | | @@ -463,21 +465,21 @@ edges | test.rs:418:22:418:51 | ...::read_to_string(...) [Ok] | test.rs:418:22:418:52 | TryExpr | provenance | | | test.rs:418:22:418:52 | TryExpr | test.rs:418:13:418:18 | buffer | provenance | | | test.rs:425:13:425:16 | path | test.rs:426:14:426:17 | path | provenance | | -| test.rs:425:13:425:16 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:35 | +| test.rs:425:13:425:16 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:37 | | test.rs:425:13:425:16 | path | test.rs:427:14:427:17 | path | provenance | | -| test.rs:425:13:425:16 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:35 | +| test.rs:425:13:425:16 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:37 | | test.rs:425:13:425:16 | path | test.rs:437:14:437:17 | path | provenance | | | test.rs:425:20:425:27 | e.path() | test.rs:425:13:425:16 | path | provenance | | | test.rs:425:22:425:25 | path | test.rs:425:20:425:27 | e.path() | provenance | Src:MaD:6 MaD:6 | -| test.rs:426:14:426:17 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:35 | -| test.rs:427:14:427:17 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:35 | -| test.rs:427:14:427:25 | path.clone() | test.rs:427:14:427:35 | ... .as_path() | provenance | MaD:114 | +| test.rs:426:14:426:17 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:37 | +| test.rs:427:14:427:17 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:37 | +| test.rs:427:14:427:25 | path.clone() | test.rs:427:14:427:35 | ... .as_path() | provenance | MaD:116 | | test.rs:439:13:439:21 | file_name | test.rs:440:14:440:22 | file_name | provenance | | -| test.rs:439:13:439:21 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:35 | +| test.rs:439:13:439:21 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:37 | | test.rs:439:13:439:21 | file_name | test.rs:445:14:445:22 | file_name | provenance | | | test.rs:439:25:439:37 | e.file_name() | test.rs:439:13:439:21 | file_name | provenance | | | test.rs:439:27:439:35 | file_name | test.rs:439:25:439:37 | e.file_name() | provenance | Src:MaD:5 MaD:5 | -| test.rs:440:14:440:22 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:35 | +| test.rs:440:14:440:22 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:37 | | test.rs:461:13:461:18 | target | test.rs:462:14:462:19 | target | provenance | | | test.rs:461:22:461:34 | ...::read_link | test.rs:461:22:461:49 | ...::read_link(...) [Ok] | provenance | Src:MaD:27 | | test.rs:461:22:461:49 | ...::read_link(...) [Ok] | test.rs:461:22:461:50 | TryExpr | provenance | | @@ -510,17 +512,17 @@ edges | test.rs:493:22:493:56 | ...::read_link(...) [future, Ok] | test.rs:493:22:493:62 | await ... [Ok] | provenance | | | test.rs:493:22:493:62 | await ... [Ok] | test.rs:493:22:493:63 | TryExpr | provenance | | | test.rs:493:22:493:63 | TryExpr | test.rs:493:13:493:18 | target | provenance | | -| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer | provenance | MaD:95 | -| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:55 | -| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:94 | -| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer | provenance | MaD:97 | -| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:57 | -| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:96 | -| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer | provenance | MaD:99 | -| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:58 | -| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:98 | -| test.rs:503:9:503:16 | mut file | test.rs:525:25:525:35 | [post] &mut buffer [&ref] | provenance | MaD:56 | -| test.rs:503:9:503:16 | mut file | test.rs:529:17:529:28 | file.bytes() | provenance | MaD:52 | +| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer | provenance | MaD:97 | +| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:57 | +| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:96 | +| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer | provenance | MaD:99 | +| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:59 | +| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:98 | +| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer | provenance | MaD:101 | +| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:100 | +| test.rs:503:9:503:16 | mut file | test.rs:525:25:525:35 | [post] &mut buffer [&ref] | provenance | MaD:58 | +| test.rs:503:9:503:16 | mut file | test.rs:529:17:529:28 | file.bytes() | provenance | MaD:54 | | test.rs:503:20:503:38 | ...::open | test.rs:503:20:503:50 | ...::open(...) [Ok] | provenance | Src:MaD:7 | | test.rs:503:20:503:50 | ...::open(...) [Ok] | test.rs:503:20:503:51 | TryExpr | provenance | | | test.rs:503:20:503:51 | TryExpr | test.rs:503:9:503:16 | mut file | provenance | | @@ -540,37 +542,37 @@ edges | test.rs:525:30:525:35 | [post] buffer | test.rs:526:15:526:20 | buffer | provenance | | | test.rs:526:15:526:20 | buffer | test.rs:526:14:526:20 | &buffer | provenance | | | test.rs:529:17:529:28 | file.bytes() | test.rs:530:14:530:17 | byte | provenance | | -| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer | provenance | MaD:95 | -| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:55 | -| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:94 | -| test.rs:536:22:536:63 | ... .open(...) [Ok] | test.rs:536:22:536:72 | ... .unwrap() | provenance | MaD:82 | +| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer | provenance | MaD:97 | +| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:57 | +| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:96 | +| test.rs:536:22:536:63 | ... .open(...) [Ok] | test.rs:536:22:536:72 | ... .unwrap() | provenance | MaD:84 | | test.rs:536:22:536:72 | ... .unwrap() | test.rs:536:13:536:18 | mut f1 | provenance | | | test.rs:536:50:536:53 | open | test.rs:536:22:536:63 | ... .open(...) [Ok] | provenance | Src:MaD:8 | | test.rs:538:30:538:40 | [post] &mut buffer | test.rs:539:15:539:20 | buffer | provenance | | | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | test.rs:538:35:538:40 | [post] buffer | provenance | | | test.rs:538:35:538:40 | [post] buffer | test.rs:539:15:539:20 | buffer | provenance | | | test.rs:539:15:539:20 | buffer | test.rs:539:14:539:20 | &buffer | provenance | | -| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer | provenance | MaD:95 | -| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:55 | -| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:94 | -| test.rs:543:22:543:80 | ... .open(...) [Ok] | test.rs:543:22:543:89 | ... .unwrap() | provenance | MaD:82 | +| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer | provenance | MaD:97 | +| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:57 | +| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:96 | +| test.rs:543:22:543:80 | ... .open(...) [Ok] | test.rs:543:22:543:89 | ... .unwrap() | provenance | MaD:84 | | test.rs:543:22:543:89 | ... .unwrap() | test.rs:543:13:543:18 | mut f2 | provenance | | | test.rs:543:67:543:70 | open | test.rs:543:22:543:80 | ... .open(...) [Ok] | provenance | Src:MaD:8 | | test.rs:545:30:545:40 | [post] &mut buffer | test.rs:546:15:546:20 | buffer | provenance | | | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | test.rs:545:35:545:40 | [post] buffer | provenance | | | test.rs:545:35:545:40 | [post] buffer | test.rs:546:15:546:20 | buffer | provenance | | | test.rs:546:15:546:20 | buffer | test.rs:546:14:546:20 | &buffer | provenance | | -| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer | provenance | MaD:95 | -| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:55 | -| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:94 | -| test.rs:550:22:550:114 | ... .open(...) [Ok] | test.rs:550:22:550:123 | ... .unwrap() | provenance | MaD:82 | +| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer | provenance | MaD:97 | +| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:57 | +| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:96 | +| test.rs:550:22:550:114 | ... .open(...) [Ok] | test.rs:550:22:550:123 | ... .unwrap() | provenance | MaD:84 | | test.rs:550:22:550:123 | ... .unwrap() | test.rs:550:13:550:18 | mut f3 | provenance | | | test.rs:550:101:550:104 | open | test.rs:550:22:550:114 | ... .open(...) [Ok] | provenance | Src:MaD:8 | | test.rs:552:30:552:40 | [post] &mut buffer | test.rs:553:15:553:20 | buffer | provenance | | | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | test.rs:552:35:552:40 | [post] buffer | provenance | | | test.rs:552:35:552:40 | [post] buffer | test.rs:553:15:553:20 | buffer | provenance | | | test.rs:553:15:553:20 | buffer | test.rs:553:14:553:20 | &buffer | provenance | | -| test.rs:560:13:560:17 | file1 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:54 | +| test.rs:560:13:560:17 | file1 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:56 | | test.rs:560:21:560:39 | ...::open | test.rs:560:21:560:51 | ...::open(...) [Ok] | provenance | Src:MaD:7 | | test.rs:560:21:560:51 | ...::open(...) [Ok] | test.rs:560:21:560:52 | TryExpr | provenance | | | test.rs:560:21:560:52 | TryExpr | test.rs:560:13:560:17 | file1 | provenance | | @@ -578,30 +580,30 @@ edges | test.rs:561:21:561:39 | ...::open | test.rs:561:21:561:59 | ...::open(...) [Ok] | provenance | Src:MaD:7 | | test.rs:561:21:561:59 | ...::open(...) [Ok] | test.rs:561:21:561:60 | TryExpr | provenance | | | test.rs:561:21:561:60 | TryExpr | test.rs:561:13:561:17 | file2 | provenance | | -| test.rs:562:13:562:22 | mut reader | test.rs:563:31:563:41 | [post] &mut buffer [&ref] | provenance | MaD:58 | +| test.rs:562:13:562:22 | mut reader | test.rs:563:31:563:41 | [post] &mut buffer [&ref] | provenance | MaD:60 | | test.rs:562:26:562:43 | file1.chain(...) | test.rs:562:13:562:22 | mut reader | provenance | | -| test.rs:562:38:562:42 | file2 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:53 | +| test.rs:562:38:562:42 | file2 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:55 | | test.rs:563:31:563:41 | [post] &mut buffer [&ref] | test.rs:563:36:563:41 | [post] buffer | provenance | | | test.rs:563:36:563:41 | [post] buffer | test.rs:564:15:564:20 | buffer | provenance | | | test.rs:564:15:564:20 | buffer | test.rs:564:14:564:20 | &buffer | provenance | | -| test.rs:569:13:569:17 | file1 | test.rs:570:26:570:40 | file1.take(...) | provenance | MaD:59 | +| test.rs:569:13:569:17 | file1 | test.rs:570:26:570:40 | file1.take(...) | provenance | MaD:61 | | test.rs:569:21:569:39 | ...::open | test.rs:569:21:569:51 | ...::open(...) [Ok] | provenance | Src:MaD:7 | | test.rs:569:21:569:51 | ...::open(...) [Ok] | test.rs:569:21:569:52 | TryExpr | provenance | | | test.rs:569:21:569:52 | TryExpr | test.rs:569:13:569:17 | file1 | provenance | | -| test.rs:570:13:570:22 | mut reader | test.rs:571:31:571:41 | [post] &mut buffer [&ref] | provenance | MaD:58 | +| test.rs:570:13:570:22 | mut reader | test.rs:571:31:571:41 | [post] &mut buffer [&ref] | provenance | MaD:60 | | test.rs:570:26:570:40 | file1.take(...) | test.rs:570:13:570:22 | mut reader | provenance | | | test.rs:571:31:571:41 | [post] &mut buffer [&ref] | test.rs:571:36:571:41 | [post] buffer | provenance | | | test.rs:571:36:571:41 | [post] buffer | test.rs:572:15:572:20 | buffer | provenance | | | test.rs:572:15:572:20 | buffer | test.rs:572:14:572:20 | &buffer | provenance | | -| test.rs:581:9:581:16 | mut file | test.rs:585:32:585:42 | [post] &mut buffer [&ref] | provenance | MaD:65 | -| test.rs:581:9:581:16 | mut file | test.rs:591:39:591:49 | [post] &mut buffer [&ref] | provenance | MaD:71 | -| test.rs:581:9:581:16 | mut file | test.rs:597:42:597:52 | [post] &mut buffer [&ref] | provenance | MaD:72 | -| test.rs:581:9:581:16 | mut file | test.rs:603:25:603:35 | [post] &mut buffer [&ref] | provenance | MaD:67 | -| test.rs:581:9:581:16 | mut file | test.rs:608:18:608:31 | file.read_u8() [future, Ok] | provenance | MaD:73 | -| test.rs:581:9:581:16 | mut file | test.rs:609:18:609:32 | file.read_i16() [future, Ok] | provenance | MaD:69 | -| test.rs:581:9:581:16 | mut file | test.rs:610:18:610:32 | file.read_f32() [future, Ok] | provenance | MaD:68 | -| test.rs:581:9:581:16 | mut file | test.rs:611:18:611:35 | file.read_i64_le() [future, Ok] | provenance | MaD:70 | -| test.rs:581:9:581:16 | mut file | test.rs:620:23:620:33 | [post] &mut buffer [&ref] | provenance | MaD:66 | +| test.rs:581:9:581:16 | mut file | test.rs:585:32:585:42 | [post] &mut buffer [&ref] | provenance | MaD:67 | +| test.rs:581:9:581:16 | mut file | test.rs:591:39:591:49 | [post] &mut buffer [&ref] | provenance | MaD:73 | +| test.rs:581:9:581:16 | mut file | test.rs:597:42:597:52 | [post] &mut buffer [&ref] | provenance | MaD:74 | +| test.rs:581:9:581:16 | mut file | test.rs:603:25:603:35 | [post] &mut buffer [&ref] | provenance | MaD:69 | +| test.rs:581:9:581:16 | mut file | test.rs:608:18:608:31 | file.read_u8() [future, Ok] | provenance | MaD:75 | +| test.rs:581:9:581:16 | mut file | test.rs:609:18:609:32 | file.read_i16() [future, Ok] | provenance | MaD:71 | +| test.rs:581:9:581:16 | mut file | test.rs:610:18:610:32 | file.read_f32() [future, Ok] | provenance | MaD:70 | +| test.rs:581:9:581:16 | mut file | test.rs:611:18:611:35 | file.read_i64_le() [future, Ok] | provenance | MaD:72 | +| test.rs:581:9:581:16 | mut file | test.rs:620:23:620:33 | [post] &mut buffer [&ref] | provenance | MaD:68 | | test.rs:581:20:581:40 | ...::open | test.rs:581:20:581:52 | ...::open(...) [future, Ok] | provenance | Src:MaD:11 | | test.rs:581:20:581:52 | ...::open(...) [future, Ok] | test.rs:581:20:581:58 | await ... [Ok] | provenance | | | test.rs:581:20:581:58 | await ... [Ok] | test.rs:581:20:581:59 | TryExpr | provenance | | @@ -637,7 +639,7 @@ edges | test.rs:620:23:620:33 | [post] &mut buffer [&ref] | test.rs:620:28:620:33 | [post] buffer | provenance | | | test.rs:620:28:620:33 | [post] buffer | test.rs:621:15:621:20 | buffer | provenance | | | test.rs:621:15:621:20 | buffer | test.rs:621:14:621:20 | &buffer | provenance | | -| test.rs:627:13:627:18 | mut f1 | test.rs:629:30:629:40 | [post] &mut buffer [&ref] | provenance | MaD:65 | +| test.rs:627:13:627:18 | mut f1 | test.rs:629:30:629:40 | [post] &mut buffer [&ref] | provenance | MaD:67 | | test.rs:627:22:627:65 | ... .open(...) [future, Ok] | test.rs:627:22:627:71 | await ... [Ok] | provenance | | | test.rs:627:22:627:71 | await ... [Ok] | test.rs:627:22:627:72 | TryExpr | provenance | | | test.rs:627:22:627:72 | TryExpr | test.rs:627:13:627:18 | mut f1 | provenance | | @@ -646,29 +648,35 @@ edges | test.rs:629:35:629:40 | [post] buffer | test.rs:630:15:630:20 | buffer | provenance | | | test.rs:630:15:630:20 | buffer | test.rs:630:14:630:20 | &buffer | provenance | | | test.rs:660:9:660:16 | mut file | test.rs:664:22:664:25 | file | provenance | | -| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:44 | -| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:45 | +| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:35 | +| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:36 | +| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:46 | +| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:47 | | test.rs:660:20:660:44 | ...::open | test.rs:660:20:660:56 | ...::open(...) [future, Ok] | provenance | Src:MaD:1 | | test.rs:660:20:660:56 | ...::open(...) [future, Ok] | test.rs:660:20:660:62 | await ... [Ok] | provenance | | | test.rs:660:20:660:62 | await ... [Ok] | test.rs:660:20:660:63 | TryExpr | provenance | | | test.rs:660:20:660:63 | TryExpr | test.rs:660:9:660:16 | mut file | provenance | | -| test.rs:664:22:664:25 | file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:44 | +| test.rs:664:22:664:25 | file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:35 | +| test.rs:664:22:664:25 | file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:46 | | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | test.rs:664:37:664:42 | [post] buffer | provenance | | | test.rs:664:37:664:42 | [post] buffer | test.rs:665:15:665:20 | buffer | provenance | | | test.rs:665:15:665:20 | buffer | test.rs:665:14:665:20 | &buffer | provenance | | | test.rs:671:13:671:18 | mut f1 | test.rs:673:22:673:23 | f1 | provenance | | -| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:44 | -| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:45 | +| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:35 | +| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:36 | +| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:46 | +| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:47 | | test.rs:671:22:671:69 | ... .open(...) [future, Ok] | test.rs:671:22:671:75 | await ... [Ok] | provenance | | | test.rs:671:22:671:75 | await ... [Ok] | test.rs:671:22:671:76 | TryExpr | provenance | | | test.rs:671:22:671:76 | TryExpr | test.rs:671:13:671:18 | mut f1 | provenance | | | test.rs:671:56:671:59 | open | test.rs:671:22:671:69 | ... .open(...) [future, Ok] | provenance | Src:MaD:2 | -| test.rs:673:22:673:23 | f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:44 | +| test.rs:673:22:673:23 | f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:35 | +| test.rs:673:22:673:23 | f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:46 | | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | test.rs:673:35:673:40 | [post] buffer | provenance | | | test.rs:673:35:673:40 | [post] buffer | test.rs:674:15:674:20 | buffer | provenance | | | test.rs:674:15:674:20 | buffer | test.rs:674:14:674:20 | &buffer | provenance | | -| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:55 | -| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:113 | +| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:57 | +| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:115 | | test.rs:688:26:688:53 | ...::connect | test.rs:688:26:688:62 | ...::connect(...) [Ok] | provenance | Src:MaD:9 | | test.rs:688:26:688:62 | ...::connect(...) [Ok] | test.rs:688:26:688:63 | TryExpr | provenance | | | test.rs:688:26:688:63 | TryExpr | test.rs:688:13:688:22 | mut stream | provenance | | @@ -680,17 +688,17 @@ edges | test.rs:707:26:707:61 | ...::connect_timeout | test.rs:707:26:707:105 | ...::connect_timeout(...) [Ok] | provenance | Src:MaD:10 | | test.rs:707:26:707:105 | ...::connect_timeout(...) [Ok] | test.rs:707:26:707:106 | TryExpr | provenance | | | test.rs:707:26:707:106 | TryExpr | test.rs:707:13:707:22 | mut stream | provenance | | -| test.rs:715:21:715:30 | mut reader | test.rs:718:44:718:52 | [post] &mut line [&ref] | provenance | MaD:49 | -| test.rs:715:34:715:64 | ...::new(...) | test.rs:715:34:715:74 | ... .take(...) | provenance | MaD:59 | +| test.rs:715:21:715:30 | mut reader | test.rs:718:44:718:52 | [post] &mut line [&ref] | provenance | MaD:51 | +| test.rs:715:34:715:64 | ...::new(...) | test.rs:715:34:715:74 | ... .take(...) | provenance | MaD:61 | | test.rs:715:34:715:74 | ... .take(...) | test.rs:715:21:715:30 | mut reader | provenance | | -| test.rs:715:58:715:63 | stream | test.rs:715:34:715:64 | ...::new(...) | provenance | MaD:103 | +| test.rs:715:58:715:63 | stream | test.rs:715:34:715:64 | ...::new(...) | provenance | MaD:105 | | test.rs:718:44:718:52 | [post] &mut line [&ref] | test.rs:718:49:718:52 | [post] line | provenance | | | test.rs:718:49:718:52 | [post] line | test.rs:725:35:725:38 | line | provenance | | | test.rs:725:35:725:38 | line | test.rs:725:34:725:38 | &line | provenance | | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:767:35:767:46 | [post] &mut buffer1 [&ref] | provenance | MaD:119 | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:771:36:771:47 | [post] &mut buffer2 [&ref] | provenance | MaD:65 | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:787:41:787:51 | [post] &mut buffer [&ref] | provenance | MaD:120 | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:810:45:810:55 | [post] &mut buffer [&ref] | provenance | MaD:121 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:767:35:767:46 | [post] &mut buffer1 [&ref] | provenance | MaD:121 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:771:36:771:47 | [post] &mut buffer2 [&ref] | provenance | MaD:67 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:787:41:787:51 | [post] &mut buffer [&ref] | provenance | MaD:122 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:810:45:810:55 | [post] &mut buffer [&ref] | provenance | MaD:123 | | test.rs:759:28:759:57 | ...::connect | test.rs:759:28:759:66 | ...::connect(...) [future, Ok] | provenance | Src:MaD:15 | | test.rs:759:28:759:66 | ...::connect(...) [future, Ok] | test.rs:759:28:759:72 | await ... [Ok] | provenance | | | test.rs:759:28:759:72 | await ... [Ok] | test.rs:759:28:759:73 | TryExpr | provenance | | @@ -720,13 +728,15 @@ edges | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:32:40:32:45 | reader | provenance | | | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:45:64:45:69 | reader | provenance | | | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:27:49:32 | reader | provenance | | -| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:44 | -| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:45 | +| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:35 | +| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:36 | +| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:46 | +| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:47 | | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:54:51:54:56 | reader | provenance | | | test_futures_io.rs:26:22:26:56 | connector.connect(...) [future, Ok] | test_futures_io.rs:26:22:26:62 | await ... [Ok] | provenance | | | test_futures_io.rs:26:22:26:62 | await ... [Ok] | test_futures_io.rs:26:22:26:63 | TryExpr | provenance | | | test_futures_io.rs:26:22:26:63 | TryExpr | test_futures_io.rs:26:9:26:18 | mut reader | provenance | | -| test_futures_io.rs:26:53:26:55 | tcp | test_futures_io.rs:26:22:26:56 | connector.connect(...) [future, Ok] | provenance | MaD:86 | +| test_futures_io.rs:26:53:26:55 | tcp | test_futures_io.rs:26:22:26:56 | connector.connect(...) [future, Ok] | provenance | MaD:88 | | test_futures_io.rs:27:11:27:16 | reader | test_futures_io.rs:27:10:27:16 | &reader | provenance | | | test_futures_io.rs:32:13:32:22 | mut pinned | test_futures_io.rs:33:15:33:20 | pinned | provenance | | | test_futures_io.rs:32:13:32:22 | mut pinned [&ref] | test_futures_io.rs:33:15:33:20 | pinned [&ref] | provenance | | @@ -734,56 +744,60 @@ edges | test_futures_io.rs:32:26:32:46 | ...::new(...) | test_futures_io.rs:32:13:32:22 | mut pinned | provenance | | | test_futures_io.rs:32:26:32:46 | ...::new(...) [&ref] | test_futures_io.rs:32:13:32:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:32:26:32:46 | ...::new(...) [Pin, &ref] | test_futures_io.rs:32:13:32:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) | provenance | MaD:78 | -| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [&ref] | provenance | MaD:80 | -| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [Pin, &ref] | provenance | MaD:79 | +| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) | provenance | MaD:80 | +| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [&ref] | provenance | MaD:82 | +| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [Pin, &ref] | provenance | MaD:81 | | test_futures_io.rs:32:40:32:45 | reader | test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | provenance | | | test_futures_io.rs:33:15:33:20 | pinned | test_futures_io.rs:33:14:33:20 | &pinned | provenance | | | test_futures_io.rs:33:15:33:20 | pinned [&ref] | test_futures_io.rs:33:14:33:20 | &pinned | provenance | | | test_futures_io.rs:33:15:33:20 | pinned [Pin, &ref] | test_futures_io.rs:33:14:33:20 | &pinned | provenance | | -| test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | provenance | MaD:44 | +| test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | provenance | MaD:35 | +| test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | provenance | MaD:46 | | test_futures_io.rs:45:64:45:69 | reader | test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | provenance | | | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | test_futures_io.rs:45:77:45:83 | [post] buffer1 | provenance | | | test_futures_io.rs:45:77:45:83 | [post] buffer1 | test_futures_io.rs:46:15:46:36 | buffer1[...] | provenance | | | test_futures_io.rs:46:15:46:36 | buffer1[...] | test_futures_io.rs:46:14:46:36 | &... | provenance | | -| test_futures_io.rs:49:27:49:32 | reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:44 | +| test_futures_io.rs:49:27:49:32 | reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:35 | +| test_futures_io.rs:49:27:49:32 | reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:46 | | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | test_futures_io.rs:49:44:49:50 | [post] buffer2 | provenance | | | test_futures_io.rs:49:44:49:50 | [post] buffer2 | test_futures_io.rs:51:15:51:36 | buffer2[...] | provenance | | | test_futures_io.rs:51:15:51:36 | buffer2[...] | test_futures_io.rs:51:14:51:36 | &... | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:55:11:55:17 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:59:40:59:46 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:69:37:69:43 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:83:22:83:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:39 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:83:22:83:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:41 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:90:40:90:46 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:103:64:103:70 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:27:107:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:44 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:45 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:35 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:36 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:46 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:47 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:113:40:113:46 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:125:22:125:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:39 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:125:22:125:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:41 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:27:132:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:42 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:43 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:44 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:45 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:27:139:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:40 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:41 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:42 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:43 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:27:146:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:46 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:47 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:48 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:49 | | test_futures_io.rs:54:23:54:57 | ...::new(...) | test_futures_io.rs:54:9:54:19 | mut reader2 | provenance | | -| test_futures_io.rs:54:51:54:56 | reader | test_futures_io.rs:54:23:54:57 | ...::new(...) | provenance | MaD:87 | +| test_futures_io.rs:54:51:54:56 | reader | test_futures_io.rs:54:23:54:57 | ...::new(...) | provenance | MaD:89 | | test_futures_io.rs:55:11:55:17 | reader2 | test_futures_io.rs:55:10:55:17 | &reader2 | provenance | | | test_futures_io.rs:59:13:59:22 | mut pinned | test_futures_io.rs:60:15:60:20 | pinned | provenance | | -| test_futures_io.rs:59:13:59:22 | mut pinned | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | +| test_futures_io.rs:59:13:59:22 | mut pinned | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | | test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | test_futures_io.rs:60:15:60:20 | pinned [&ref] | provenance | | -| test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | +| test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | | test_futures_io.rs:59:13:59:22 | mut pinned [Pin, &ref] | test_futures_io.rs:60:15:60:20 | pinned [Pin, &ref] | provenance | | | test_futures_io.rs:59:26:59:47 | ...::new(...) | test_futures_io.rs:59:13:59:22 | mut pinned | provenance | | | test_futures_io.rs:59:26:59:47 | ...::new(...) [&ref] | test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:59:26:59:47 | ...::new(...) [Pin, &ref] | test_futures_io.rs:59:13:59:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) | provenance | MaD:78 | -| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [&ref] | provenance | MaD:80 | -| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [Pin, &ref] | provenance | MaD:79 | +| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) | provenance | MaD:80 | +| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [&ref] | provenance | MaD:82 | +| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [Pin, &ref] | provenance | MaD:81 | | test_futures_io.rs:59:40:59:46 | reader2 | test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:60:15:60:20 | pinned | test_futures_io.rs:60:14:60:20 | &pinned | provenance | | | test_futures_io.rs:60:15:60:20 | pinned [&ref] | test_futures_io.rs:60:14:60:20 | &pinned | provenance | | @@ -796,11 +810,11 @@ edges | test_futures_io.rs:63:31:63:33 | buf | test_futures_io.rs:65:18:65:20 | buf | provenance | | | test_futures_io.rs:64:19:64:24 | buffer [Ready, Ok] | test_futures_io.rs:64:18:64:24 | &buffer | provenance | | | test_futures_io.rs:69:13:69:19 | buffer2 [Ready, Ok] | test_futures_io.rs:70:16:70:22 | buffer2 [Ready, Ok] | provenance | | -| test_futures_io.rs:69:23:69:44 | ...::new(...) | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | -| test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | +| test_futures_io.rs:69:23:69:44 | ...::new(...) | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | +| test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | test_futures_io.rs:69:13:69:19 | buffer2 [Ready, Ok] | provenance | | -| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) | provenance | MaD:78 | -| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | provenance | MaD:80 | +| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) | provenance | MaD:80 | +| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | provenance | MaD:82 | | test_futures_io.rs:69:37:69:43 | reader2 | test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:70:16:70:22 | buffer2 [Ready, Ok] | test_futures_io.rs:71:13:71:32 | ...::Ready(...) [Ready, Ok] | provenance | | | test_futures_io.rs:70:16:70:22 | buffer2 [Ready, Ok] | test_futures_io.rs:72:23:72:29 | buffer2 [Ready, Ok] | provenance | | @@ -818,33 +832,35 @@ edges | test_futures_io.rs:90:26:90:47 | ...::new(...) | test_futures_io.rs:90:13:90:22 | mut pinned | provenance | | | test_futures_io.rs:90:26:90:47 | ...::new(...) [&ref] | test_futures_io.rs:90:13:90:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:90:26:90:47 | ...::new(...) [Pin, &ref] | test_futures_io.rs:90:13:90:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) | provenance | MaD:78 | -| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [&ref] | provenance | MaD:80 | -| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [Pin, &ref] | provenance | MaD:79 | +| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) | provenance | MaD:80 | +| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [&ref] | provenance | MaD:82 | +| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [Pin, &ref] | provenance | MaD:81 | | test_futures_io.rs:90:40:90:46 | reader2 | test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:91:15:91:20 | pinned | test_futures_io.rs:91:14:91:20 | &pinned | provenance | | | test_futures_io.rs:91:15:91:20 | pinned [&ref] | test_futures_io.rs:91:14:91:20 | &pinned | provenance | | | test_futures_io.rs:91:15:91:20 | pinned [Pin, &ref] | test_futures_io.rs:91:14:91:20 | &pinned | provenance | | -| test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | provenance | MaD:44 | +| test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | provenance | MaD:35 | +| test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | provenance | MaD:46 | | test_futures_io.rs:103:64:103:70 | reader2 | test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | test_futures_io.rs:103:78:103:84 | [post] buffer1 | provenance | | | test_futures_io.rs:103:78:103:84 | [post] buffer1 | test_futures_io.rs:104:15:104:36 | buffer1[...] | provenance | | | test_futures_io.rs:104:15:104:36 | buffer1[...] | test_futures_io.rs:104:14:104:36 | &... | provenance | | -| test_futures_io.rs:107:27:107:33 | reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:44 | +| test_futures_io.rs:107:27:107:33 | reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:35 | +| test_futures_io.rs:107:27:107:33 | reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:46 | | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | test_futures_io.rs:107:45:107:51 | [post] buffer2 | provenance | | | test_futures_io.rs:107:45:107:51 | [post] buffer2 | test_futures_io.rs:108:15:108:36 | buffer2[...] | provenance | | | test_futures_io.rs:108:15:108:36 | buffer2[...] | test_futures_io.rs:108:14:108:36 | &... | provenance | | | test_futures_io.rs:113:13:113:22 | mut pinned | test_futures_io.rs:114:15:114:20 | pinned | provenance | | -| test_futures_io.rs:113:13:113:22 | mut pinned | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | +| test_futures_io.rs:113:13:113:22 | mut pinned | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | | test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | test_futures_io.rs:114:15:114:20 | pinned [&ref] | provenance | | -| test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:38 | +| test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | | test_futures_io.rs:113:13:113:22 | mut pinned [Pin, &ref] | test_futures_io.rs:114:15:114:20 | pinned [Pin, &ref] | provenance | | | test_futures_io.rs:113:26:113:47 | ...::new(...) | test_futures_io.rs:113:13:113:22 | mut pinned | provenance | | | test_futures_io.rs:113:26:113:47 | ...::new(...) [&ref] | test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:113:26:113:47 | ...::new(...) [Pin, &ref] | test_futures_io.rs:113:13:113:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) | provenance | MaD:78 | -| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [&ref] | provenance | MaD:80 | -| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [Pin, &ref] | provenance | MaD:79 | +| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) | provenance | MaD:80 | +| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [&ref] | provenance | MaD:82 | +| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [Pin, &ref] | provenance | MaD:81 | | test_futures_io.rs:113:40:113:46 | reader2 | test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:114:15:114:20 | pinned | test_futures_io.rs:114:14:114:20 | &pinned | provenance | | | test_futures_io.rs:114:15:114:20 | pinned [&ref] | test_futures_io.rs:114:14:114:20 | &pinned | provenance | | @@ -860,40 +876,40 @@ edges | test_futures_io.rs:125:22:125:39 | reader2.fill_buf() [future, Ok] | test_futures_io.rs:125:22:125:45 | await ... [Ok] | provenance | | | test_futures_io.rs:125:22:125:45 | await ... [Ok] | test_futures_io.rs:125:22:125:46 | TryExpr | provenance | | | test_futures_io.rs:125:22:125:46 | TryExpr | test_futures_io.rs:125:13:125:18 | buffer | provenance | | -| test_futures_io.rs:132:27:132:33 | reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:42 | +| test_futures_io.rs:132:27:132:33 | reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:44 | | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | test_futures_io.rs:132:58:132:61 | [post] line | provenance | | | test_futures_io.rs:132:58:132:61 | [post] line | test_futures_io.rs:133:15:133:18 | line | provenance | | | test_futures_io.rs:133:15:133:18 | line | test_futures_io.rs:133:14:133:18 | &line | provenance | | -| test_futures_io.rs:139:27:139:33 | reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:40 | +| test_futures_io.rs:139:27:139:33 | reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:42 | | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | test_futures_io.rs:139:50:139:53 | [post] line | provenance | | | test_futures_io.rs:139:50:139:53 | [post] line | test_futures_io.rs:140:15:140:18 | line | provenance | | | test_futures_io.rs:140:15:140:18 | line | test_futures_io.rs:140:14:140:18 | &line | provenance | | -| test_futures_io.rs:146:27:146:33 | reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:46 | +| test_futures_io.rs:146:27:146:33 | reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:48 | | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | test_futures_io.rs:146:52:146:57 | [post] buffer | provenance | | | test_futures_io.rs:146:52:146:57 | [post] buffer | test_futures_io.rs:147:15:147:20 | buffer | provenance | | | test_futures_io.rs:147:15:147:20 | buffer | test_futures_io.rs:147:14:147:20 | &buffer | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:14 | a | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:14 | a | provenance | | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:75 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:84 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:75 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:84 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:77 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:86 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:77 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:86 | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:14 | a | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:14 | a | provenance | | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:74 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:83 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:74 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:83 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:76 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:85 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:76 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:85 | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:15:14:15:14 | a | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:15:14:15:14 | a | provenance | | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:75 | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:84 | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:75 | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:84 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:74 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:83 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:74 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:83 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:77 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:86 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:77 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:86 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:76 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:85 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:76 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:85 | | web_frameworks.rs:68:15:68:15 | a | web_frameworks.rs:70:14:70:14 | a | provenance | | | web_frameworks.rs:68:15:68:15 | a | web_frameworks.rs:70:14:70:14 | a | provenance | | nodes From 50bf9ae7563e671814820819269200980cb5a5b3 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Sun, 21 Sep 2025 20:44:46 -0400 Subject: [PATCH 058/160] Refactor RootApi class to use getAnImmediateDescendent for clarity --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index 0999be94505..ce0b47502f9 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -26,7 +26,7 @@ module Grape { */ class RootApi extends GrapeApiClass { RootApi() { - not exists(GrapeApiClass parent | this != parent and this = parent.getADescendent()) + not this = any(GrapeApiClass parent).getAnImmediateDescendent() } } From 1bf6101967e860043695e2d93e10c34373ea8b39 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Sun, 21 Sep 2025 20:52:28 -0400 Subject: [PATCH 059/160] Remove redundant exclusion of base Grape::API module from GrapeApiClass - should not impact extracted application code --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index ce0b47502f9..4e178792572 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -45,8 +45,7 @@ module Grape { */ class GrapeApiClass extends DataFlow::ClassNode { GrapeApiClass() { - this = grapeApiBaseClass().getADescendentModule() and - not exists(DataFlow::ModuleNode m | m = grapeApiBaseClass().asModule() | this = m) + this = grapeApiBaseClass().getADescendentModule() } /** From b2cc01c490115f1c1078318e45d328a1ddbedc7c Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 22 Sep 2025 09:38:30 +0200 Subject: [PATCH 060/160] Rust: Visibility check for qualified path resolution --- .../lib/codeql/rust/internal/CachedStages.qll | 2 +- .../codeql/rust/internal/PathResolution.qll | 209 +++++++++++------- .../path-resolution/my2/my3/mod.rs | 2 +- .../path-resolution/path-resolution.expected | 1 + 4 files changed, 136 insertions(+), 78 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/CachedStages.qll b/rust/ql/lib/codeql/rust/internal/CachedStages.qll index cfd3d690522..132b9ec8f7e 100644 --- a/rust/ql/lib/codeql/rust/internal/CachedStages.qll +++ b/rust/ql/lib/codeql/rust/internal/CachedStages.qll @@ -117,7 +117,7 @@ module Stages { or exists(resolvePath(_)) or - exists(any(ItemNode i).getASuccessor(_, _)) + exists(any(ItemNode i).getASuccessor(_, _, _)) or exists(any(ImplOrTraitItemNode i).getASelfPath()) or diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 44e8b452255..785dc2e4319 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -6,6 +6,7 @@ private import rust private import codeql.rust.elements.internal.generated.ParentChild private import codeql.rust.internal.CachedStages private import codeql.rust.frameworks.stdlib.Builtins as Builtins +private import codeql.util.Option private newtype TNamespace = TTypeNamespace() or @@ -78,6 +79,10 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki ) } +private module UseOption = Option; + +private class UseOption = UseOption::Option; + /** * Holds if `n` is superseded by an attribute macro expansion. That is, `n` is * an item or a transitive child of an item with an attribute macro expansion. @@ -229,40 +234,51 @@ abstract class ItemNode extends Locatable { result = this.(SourceFileItemNode).getSuper() } - /** Gets a successor named `name` of the given `kind`, if any. */ + /** + * Gets a successor named `name` of the given `kind`, if any. + * + * `useOpt` represents the `use` statement that brought the item into scope, + * if any. + */ cached - ItemNode getASuccessor(string name, SuccessorKind kind) { + ItemNode getASuccessor(string name, SuccessorKind kind, UseOption useOpt) { Stages::PathResolutionStage::ref() and sourceFileEdge(this, name, result) and - kind.isBoth() + kind.isBoth() and + useOpt.isNone() or - result = getAChildSuccessor(this, name, kind) + result = getAChildSuccessor(this, name, kind) and + useOpt.isNone() or - fileImportEdge(this, name, result, kind) + fileImportEdge(this, name, result, kind, useOpt) or - useImportEdge(this, name, result, kind) + useImportEdge(this, name, result, kind) and + useOpt.isNone() or - crateDefEdge(this, name, result, kind) + crateDefEdge(this, name, result, kind, useOpt) or crateDependencyEdge(this, name, result) and - kind.isInternal() + kind.isInternal() and + useOpt.isNone() or externCrateEdge(this, name, result) and - kind.isInternal() + kind.isInternal() and + useOpt.isNone() or // items made available through `use` are available to nodes that contain the `use` - exists(UseItemNode use | - use = this.getASuccessor(_, _) and - result = use.getASuccessor(name, kind) - ) + useOpt.asSome() = + any(UseItemNode use_ | + use_ = this.getASuccessor(_, _, _) and + result = use_.getASuccessor(name, kind, _) + ) or - exists(ExternCrateItemNode ec | result = ec.(ItemNode).getASuccessor(name, kind) | - ec = this.getASuccessor(_, _) + exists(ExternCrateItemNode ec | result = ec.(ItemNode).getASuccessor(name, kind, useOpt) | + ec = this.getASuccessor(_, _, _) or // if the extern crate appears in the crate root, then the crate name is also added // to the 'extern prelude', see https://doc.rust-lang.org/reference/items/extern-crates.html exists(Crate c | - ec = c.getSourceFile().(ItemNode).getASuccessor(_, _) and + ec = c.getSourceFile().(ItemNode).getASuccessor(_, _, _) and this = c.getASourceFile() ) ) @@ -270,20 +286,20 @@ abstract class ItemNode extends Locatable { // a trait has access to the associated items of its supertraits this = any(TraitItemNodeImpl trait | - result = trait.resolveABoundCand().getASuccessor(name, kind) and + result = trait.resolveABoundCand().getASuccessor(name, kind, useOpt) and kind.isExternalOrBoth() and result instanceof AssocItemNode and not trait.hasAssocItem(name) ) or // items made available by an implementation where `this` is the implementing type - typeImplEdge(this, _, name, kind, result) + typeImplEdge(this, _, name, kind, result, useOpt) or // trait items with default implementations made available in an implementation exists(ImplItemNodeImpl impl, ItemNode trait | this = impl and trait = impl.resolveTraitTyCand() and - result = trait.getASuccessor(name, kind) and + result = trait.getASuccessor(name, kind, useOpt) and result.(AssocItemNode).hasImplementation() and kind.isExternalOrBoth() and not impl.hasAssocItem(name) @@ -291,42 +307,52 @@ abstract class ItemNode extends Locatable { or // type parameters have access to the associated items of its bounds result = - this.(TypeParamItemNodeImpl).resolveABoundCand().getASuccessor(name, kind).(AssocItemNode) and + this.(TypeParamItemNodeImpl) + .resolveABoundCand() + .getASuccessor(name, kind, useOpt) + .(AssocItemNode) and kind.isExternalOrBoth() or result = this.(ImplTraitTypeReprItemNodeImpl) .resolveABoundCand() - .getASuccessor(name, kind) + .getASuccessor(name, kind, useOpt) .(AssocItemNode) and kind.isExternalOrBoth() or - result = this.(TypeAliasItemNodeImpl).resolveAliasCand().getASuccessor(name, kind) and + result = this.(TypeAliasItemNodeImpl).resolveAliasCand().getASuccessor(name, kind, useOpt) and kind.isExternalOrBoth() or name = "super" and - if this instanceof Module or this instanceof SourceFile - then ( - kind.isBoth() and result = this.getImmediateParentModule() - ) else ( - kind.isInternal() and result = this.getImmediateParentModule().getImmediateParentModule() + useOpt.isNone() and + ( + if this instanceof Module or this instanceof SourceFile + then ( + kind.isBoth() and result = this.getImmediateParentModule() + ) else ( + kind.isInternal() and result = this.getImmediateParentModule().getImmediateParentModule() + ) ) or name = "self" and - if - this instanceof Module or - this instanceof Enum or - this instanceof Struct or - this instanceof Crate - then ( - kind.isBoth() and - result = this - ) else ( - kind.isInternal() and - result = this.getImmediateParentModule() + useOpt.isNone() and + ( + if + this instanceof Module or + this instanceof Enum or + this instanceof Struct or + this instanceof Crate + then ( + kind.isBoth() and + result = this + ) else ( + kind.isInternal() and + result = this.getImmediateParentModule() + ) ) or kind.isInternal() and + useOpt.isNone() and ( preludeEdge(this, name, result) or @@ -350,7 +376,7 @@ abstract class ItemNode extends Locatable { pragma[nomagic] ItemNode getASuccessor(string name) { exists(SuccessorKind kind | - result = this.getASuccessor(name, kind) and + result = this.getASuccessor(name, kind, _) and kind.isExternalOrBoth() ) } @@ -1266,10 +1292,12 @@ predicate fileImport(Module m, SourceFile f) { * in scope under the name `name`. */ pragma[nomagic] -private predicate fileImportEdge(Module mod, string name, ItemNode item, SuccessorKind kind) { +private predicate fileImportEdge( + Module mod, string name, ItemNode item, SuccessorKind kind, UseOption useOpt +) { exists(SourceFileItemNode f | fileImport(mod, f) and - item = f.getASuccessor(name, kind) + item = f.getASuccessor(name, kind, useOpt) ) } @@ -1277,8 +1305,10 @@ private predicate fileImportEdge(Module mod, string name, ItemNode item, Success * Holds if crate `c` defines the item `i` named `name`. */ pragma[nomagic] -private predicate crateDefEdge(CrateItemNode c, string name, ItemNode i, SuccessorKind kind) { - i = c.getSourceFile().getASuccessor(name, kind) and +private predicate crateDefEdge( + CrateItemNode c, string name, ItemNode i, SuccessorKind kind, UseOption useOpt +) { + i = c.getSourceFile().getASuccessor(name, kind, useOpt) and kind.isExternalOrBoth() } @@ -1421,8 +1451,10 @@ private predicate unqualifiedPathLookup(ItemNode encl, string name, Namespace ns } pragma[nomagic] -private ItemNode getASuccessor(ItemNode pred, string name, Namespace ns, SuccessorKind kind) { - result = pred.getASuccessor(name, kind) and +private ItemNode getASuccessor( + ItemNode pred, string name, Namespace ns, SuccessorKind kind, UseOption useOpt +) { + result = pred.getASuccessor(name, kind, useOpt) and ns = result.getNamespace() } @@ -1457,7 +1489,7 @@ private predicate keywordLookup(ItemNode encl, string name, RelevantPath p) { pragma[nomagic] private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKind kind) { exists(ItemNode encl, string name | - result = getASuccessor(encl, name, ns, kind) and + result = getASuccessor(encl, name, ns, kind, _) and kind.isInternalOrBoth() | unqualifiedPathLookup(encl, name, ns, p) @@ -1486,7 +1518,7 @@ module TraitIsVisible { // lookup in an outer scope, but only if the trait is not declared in inner scope exists(ItemNode mid | traitLookup(mid, element, trait) and - not trait = mid.getASuccessor(_, _) and + not trait = mid.getASuccessor(_, _, _) and encl = getOuterScope(mid) ) } @@ -1494,7 +1526,9 @@ module TraitIsVisible { /** Holds if the trait `trait` is visible at `element`. */ pragma[nomagic] predicate traitIsVisible(Element element, Trait trait) { - exists(ItemNode encl | traitLookup(encl, element, trait) and trait = encl.getASuccessor(_, _)) + exists(ItemNode encl | + traitLookup(encl, element, trait) and trait = encl.getASuccessor(_, _, _) + ) } } @@ -1523,12 +1557,42 @@ private ItemNode resolvePathCandQualifier(RelevantPath qualifier, RelevantPath p name = path.getText() } -pragma[nomagic] -private Crate getCrate0(Locatable l) { result.getASourceFile().getFile() = l.getFile() } - bindingset[l] pragma[inline_late] -private Crate getCrate(Locatable l) { result = getCrate0(l) } +private ModuleLikeNode getAnAncestorModule(Locatable l) { + exists(ItemNode encl | + encl.getADescendant() = l and + result = encl.getImmediateParentModule*() + ) +} + +bindingset[i] +pragma[inline_late] +private ModuleLikeNode getParent(ItemNode i) { result = i.getImmediateParent() } + +/** + * Holds if resolving a qualified path at `l` to the item `i` with successor kind + * `kind` respects visibility. + * + * This is the case when either `i` is externally visible (e.g. a `pub` function), + * or when `i` (or the `use` statement, `useOpt`, that brought `i` into scope) is + * in an ancestor module of `l`. + */ +bindingset[l, i, kind, useOpt] +pragma[inline_late] +private predicate checkQualifiedVisibility( + Locatable l, ItemNode i, SuccessorKind kind, UseOption useOpt +) { + kind.isExternalOrBoth() + or + exists(AstNode n | getAnAncestorModule(l) = getParent(n) | + n = useOpt.asSome() + or + useOpt.isNone() and + n = i + ) and + not i instanceof TypeParam +} /** * Gets the item that `path` resolves to in `ns` when `qualifier` is the @@ -1538,19 +1602,10 @@ pragma[nomagic] private ItemNode resolvePathCandQualified( RelevantPath qualifier, ItemNode q, RelevantPath path, Namespace ns ) { - exists(string name, SuccessorKind kind | + exists(string name, SuccessorKind kind, UseOption useOpt | q = resolvePathCandQualifier(qualifier, path, name) and - result = getASuccessor(q, name, ns, kind) - | - kind.isExternalOrBoth() - or - // Non-public items are visible to paths in descendant modules of the declaring - // module; the declaration may happen via a `use` statement, where the item - // being used is _not_ itself in an ancestor module, and we currently don't track - // that information in `getASuccessor`. So, for simplicity, we allow for non-public - // items when the path and the item are in the same crate. - getCrate(path) = getCrate(result) and - not result instanceof TypeParam + result = getASuccessor(q, name, ns, kind, useOpt) and + checkQualifiedVisibility(path, result, kind, useOpt) ) } @@ -1561,6 +1616,8 @@ private predicate pathUsesNamespace(Path p, Namespace n) { p = any(PathExpr pe).getPath() or p = any(TupleStructPat tsp).getPath() + or + p = any(Meta m).getPath() ) or n.isType() and @@ -1621,7 +1678,7 @@ private ItemNode resolvePathCand(RelevantPath path) { private Trait getResolvePathTraitUsed(RelevantPath path, AssocItemNode node) { exists(TypeItemNode type, ImplItemNodeImpl impl | node = resolvePathCandQualified(_, type, path, _) and - typeImplEdge(type, impl, _, _, node) and + typeImplEdge(type, impl, _, _, node, _) and result = impl.resolveTraitTyCand() ) } @@ -1668,18 +1725,17 @@ private predicate isUseTreeSubPathUnqualified(UseTree tree, RelevantPath path, s pragma[nomagic] private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path, SuccessorKind kind) { - kind.isExternalOrBoth() and - ( + exists(UseOption useOpt | checkQualifiedVisibility(use, result, kind, useOpt) | exists(UseTree midTree, ItemNode mid, string name | mid = resolveUseTreeListItem(use, midTree) and tree = midTree.getUseTreeList().getAUseTree() and isUseTreeSubPathUnqualified(tree, path, pragma[only_bind_into](name)) and - result = mid.getASuccessor(pragma[only_bind_into](name), kind) + result = mid.getASuccessor(pragma[only_bind_into](name), kind, useOpt) ) or exists(ItemNode q, string name | q = resolveUseTreeListItemQualifier(use, tree, path, name) and - result = q.getASuccessor(name, kind) + result = q.getASuccessor(name, kind, useOpt) ) ) } @@ -1711,10 +1767,10 @@ private predicate useImportEdge(Use use, string name, ItemNode item, SuccessorKi not tree.hasUseTreeList() and if tree.isGlob() then - exists(ItemNode encl, Namespace ns, SuccessorKind kind1 | + exists(ItemNode encl, Namespace ns, SuccessorKind kind1, UseOption useOpt | encl.getADescendant() = use and - item = getASuccessor(used, name, ns, kind1) and - kind1.isExternalOrBoth() and + item = getASuccessor(used, name, ns, kind1, useOpt) and + checkQualifiedVisibility(use, item, kind1, useOpt) and // glob imports can be shadowed not declares(encl, ns, name) and not name = ["super", "self"] @@ -1764,10 +1820,11 @@ private predicate externCrateEdge(ExternCrateItemNode ec, string name, CrateItem * makes `assoc` available as `name` at `kind`. */ private predicate typeImplEdge( - TypeItemNode typeItem, ImplItemNodeImpl impl, string name, SuccessorKind kind, AssocItemNode assoc + TypeItemNode typeItem, ImplItemNodeImpl impl, string name, SuccessorKind kind, + AssocItemNode assoc, UseOption useOpt ) { typeItem = impl.resolveSelfTyCand() and - assoc = impl.getASuccessor(name, kind) and + assoc = impl.getASuccessor(name, kind, useOpt) and kind.isExternalOrBoth() } @@ -1839,12 +1896,12 @@ private module Debug { ItemNode debugGetASuccessor(ItemNode i, string name, SuccessorKind kind) { i = getRelevantLocatable() and - result = i.getASuccessor(name, kind) + result = i.getASuccessor(name, kind, _) } predicate debugFileImportEdge(Module mod, string name, ItemNode item, SuccessorKind kind) { mod = getRelevantLocatable() and - fileImportEdge(mod, name, item, kind) + fileImportEdge(mod, name, item, kind, _) } predicate debugFileImport(Module m, SourceFile f) { diff --git a/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs b/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs index 1a98df1b560..169aeed6b28 100644 --- a/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs +++ b/rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs @@ -11,4 +11,4 @@ use super::nested6_f; // $ item=I116 use super::*; // $ item=mod.rs -trait MyTrait: Deref {} // $ MISSING: item=Deref +trait MyTrait: Deref {} // $ item=Deref diff --git a/rust/ql/test/library-tests/path-resolution/path-resolution.expected b/rust/ql/test/library-tests/path-resolution/path-resolution.expected index 1a925a31cce..9315016fe6a 100644 --- a/rust/ql/test/library-tests/path-resolution/path-resolution.expected +++ b/rust/ql/test/library-tests/path-resolution/path-resolution.expected @@ -455,6 +455,7 @@ resolvePath | my2/my3/mod.rs:10:5:10:9 | super | my2/mod.rs:1:1:25:34 | SourceFile | | my2/my3/mod.rs:10:5:10:20 | ...::nested6_f | my2/nested2.rs:15:9:17:9 | fn f | | my2/my3/mod.rs:12:5:12:9 | super | my2/mod.rs:1:1:25:34 | SourceFile | +| my2/my3/mod.rs:14:16:14:20 | Deref | {EXTERNAL LOCATION} | trait Deref | | my.rs:3:5:3:10 | nested | my.rs:1:1:1:15 | mod nested | | my.rs:3:5:3:13 | ...::g | my/nested.rs:19:1:22:1 | fn g | | my.rs:11:5:11:5 | g | my/nested.rs:19:1:22:1 | fn g | From b5b6f0600565148c64d278c2bec48ddd03926916 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 22 Sep 2025 09:38:43 +0200 Subject: [PATCH 061/160] Rust: Fix bad join ``` Evaluated relational algebra for predicate _PathResolution::CrateItemNode.getName/0#dispred#91b4dd6b_PathResolution::SourceFileItemNode#bd8f490__#antijoin_rhs@e84aee8k with tuple counts: 35406180 ~0% {3} r1 = JOIN PathResolution::SourceFileItemNode#bd8f4905 WITH `PathResolution::CrateItemNode.getName/0#dispred#91b4dd6b` CARTESIAN PRODUCT OUTPUT Lhs.0, Rhs.1, Rhs.0 8455 ~2% {4} | JOIN WITH `PathResolution::declaresDirectly/3#7d0350fb_021#join_rhs` ON FIRST 2 OUTPUT Rhs.2, Lhs.0, Lhs.2, Lhs.1 3259 ~0% {3} | JOIN WITH num#PathResolution::TTypeNamespace#4897e416 ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Lhs.3 return r1 ``` --- rust/ql/lib/codeql/rust/internal/PathResolution.qll | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 785dc2e4319..a4b1e9bce98 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -1321,6 +1321,12 @@ private predicate crateDependency(SourceFileItemNode file, string name, CrateIte exists(CrateItemNode c | dep = c.(Crate).getDependency(name) | file = c.getASourceFile()) } +pragma[nomagic] +private predicate hasDeclOrDep(SourceFileItemNode file, string name) { + declaresDirectly(file, TTypeNamespace(), name) or + crateDependency(file, name, _) +} + /** * Holds if `file` depends on crate `dep` named `name`. */ @@ -1334,8 +1340,7 @@ private predicate crateDependencyEdge(SourceFileItemNode file, string name, Crat // a given file to its crate (for example, if the file is `mod` imported inside a macro that the // extractor is unable to expand). name = dep.getName() and - not declaresDirectly(file, TTypeNamespace(), name) and - not crateDependency(file, name, _) + not hasDeclOrDep(file, name) } private predicate useTreeDeclares(UseTree tree, string name) { From 78641b4dde6d2fc3c1c8cd23bce229f73da3cd0e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 22 Sep 2025 09:37:03 +0200 Subject: [PATCH 062/160] Rust: Reduce size of `unqualifiedPathLookup` --- .../codeql/rust/internal/PathResolution.qll | 58 ++++++++++++------- 1 file changed, 36 insertions(+), 22 deletions(-) diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index a4b1e9bce98..efd614db63a 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -1401,11 +1401,20 @@ class RelevantPath extends Path { name = this.getText() } + /** + * Holds if this is an unqualified path with the textual value `name` and + * enclosing item `encl`. + */ + pragma[nomagic] + predicate isUnqualified(string name, ItemNode encl) { + this.isUnqualified(name) and + encl.getADescendant() = this + } + pragma[nomagic] predicate isCratePath(string name, ItemNode encl) { name = ["crate", "$crate"] and - this.isUnqualified(name) and - encl.getADescendant() = this + this.isUnqualified(name, encl) } pragma[nomagic] @@ -1432,26 +1441,26 @@ private ItemNode getOuterScope(ItemNode i) { } /** - * Holds if the unqualified path `p` references an item named `name`, and `name` - * may be looked up in the `ns` namespace inside enclosing item `encl`. + * Holds if _some_ unqualified path in `encl` references an item named `name`, + * and `name` may be looked up in the `ns` namespace inside `ancestor`. */ pragma[nomagic] -private predicate unqualifiedPathLookup(ItemNode encl, string name, Namespace ns, RelevantPath p) { +private predicate unqualifiedPathLookup(ItemNode ancestor, string name, Namespace ns, ItemNode encl) { // lookup in the immediately enclosing item - p.isUnqualified(name) and - encl.getADescendant() = p and + any(RelevantPath p).isUnqualified(name, encl) and + ancestor = encl and exists(ns) and not name = ["crate", "$crate", "super", "self"] or // lookup in an outer scope, but only if the item is not declared in inner scope exists(ItemNode mid | - unqualifiedPathLookup(mid, name, ns, p) and + unqualifiedPathLookup(mid, name, ns, encl) and not declares(mid, ns, name) and not ( name = "Self" and mid = any(ImplOrTraitItemNode i).getAnItemInSelfScope() ) and - encl = getOuterScope(mid) + ancestor = getOuterScope(mid) ) } @@ -1474,32 +1483,34 @@ private predicate sourceFileHasCratePathTc(ItemNode i1, ItemNode i2) = /** * Holds if the unqualified path `p` references a keyword item named `name`, and - * `name` may be looked up inside enclosing item `encl`. + * `name` may be looked up inside `ancestor`. */ pragma[nomagic] -private predicate keywordLookup(ItemNode encl, string name, RelevantPath p) { +private predicate keywordLookup(ItemNode ancestor, string name, RelevantPath p) { // For `($)crate`, jump directly to the root module exists(ItemNode i | p.isCratePath(name, i) | - encl instanceof SourceFile and - encl = i + ancestor instanceof SourceFile and + ancestor = i or - sourceFileHasCratePathTc(encl, i) + sourceFileHasCratePathTc(ancestor, i) ) or name = ["super", "self"] and - p.isUnqualified(name) and - encl.getADescendant() = p + p.isUnqualified(name, ancestor) } pragma[nomagic] private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKind kind) { - exists(ItemNode encl, string name | - result = getASuccessor(encl, name, ns, kind, _) and + exists(ItemNode ancestor, string name | + result = getASuccessor(ancestor, pragma[only_bind_into](name), ns, kind, _) and kind.isInternalOrBoth() | - unqualifiedPathLookup(encl, name, ns, p) + exists(ItemNode encl | + unqualifiedPathLookup(ancestor, name, ns, encl) and + p.isUnqualified(pragma[only_bind_into](name), encl) + ) or - keywordLookup(encl, name, p) and exists(ns) + keywordLookup(ancestor, name, p) and exists(ns) ) } @@ -1880,10 +1891,13 @@ private module Debug { } predicate debugUnqualifiedPathLookup( - RelevantPath p, string name, Namespace ns, ItemNode encl, string path + RelevantPath p, string name, Namespace ns, ItemNode ancestor, string path ) { p = getRelevantLocatable() and - unqualifiedPathLookup(encl, name, ns, p) and + exists(ItemNode encl | + unqualifiedPathLookup(encl, name, ns, ancestor) and + p.isUnqualified(name, encl) + ) and path = p.toStringDebug() } From cd807533f26b24f841124b6a4f6632149abcd5f7 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 17 Sep 2025 10:55:47 +0200 Subject: [PATCH 063/160] Rust: Add tests for parameter in source model --- .../library-tests/dataflow/models/main.rs | 27 ++ .../dataflow/models/models.expected | 328 +++++++++--------- .../dataflow/models/models.ext.yml | 1 + 3 files changed, 192 insertions(+), 164 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/models/main.rs b/rust/ql/test/library-tests/dataflow/models/main.rs index 0430b6f8dff..98a45655035 100644 --- a/rust/ql/test/library-tests/dataflow/models/main.rs +++ b/rust/ql/test/library-tests/dataflow/models/main.rs @@ -249,6 +249,33 @@ fn test_enum_method_source() { } } +mod source_into_function { + use super::sink; + + // has a source model + fn pass_source(_i: i64, f: impl FnOnce(i64) -> A) -> A { + f(42) + } + + fn test_source_into_function() { + let a = |a| sink(a); // $ MISSING: hasValueFlow=1 + pass_source(1, a); + + pass_source(2, |a| { + sink(a); // $ MISSING: hasValueFlow=2 + }); + + fn f(a: i64) { + sink(a) // $ MISSING: hasValueFlow=3 + } + pass_source(3, f); + + pass_source(4, async move |a| { + sink(a); // $ MISSING: hasValueFlow=4 + }); + } +} + // has a sink model fn enum_sink(e: MyFieldEnum) {} diff --git a/rust/ql/test/library-tests/dataflow/models/models.expected b/rust/ql/test/library-tests/dataflow/models/models.expected index db7489809b8..c04b66068db 100644 --- a/rust/ql/test/library-tests/dataflow/models/models.expected +++ b/rust/ql/test/library-tests/dataflow/models/models.expected @@ -230,70 +230,70 @@ edges | main.rs:247:9:247:37 | ...::C {...} [C] | main.rs:247:35:247:35 | i | provenance | | | main.rs:247:35:247:35 | i | main.rs:247:47:247:47 | i | provenance | | | main.rs:247:35:247:35 | i | main.rs:247:47:247:47 | i | provenance | | -| main.rs:256:9:256:9 | s | main.rs:257:41:257:41 | s | provenance | | -| main.rs:256:9:256:9 | s | main.rs:257:41:257:41 | s | provenance | | -| main.rs:256:13:256:22 | source(...) | main.rs:256:9:256:9 | s | provenance | | -| main.rs:256:13:256:22 | source(...) | main.rs:256:9:256:9 | s | provenance | | -| main.rs:257:15:257:43 | ...::C {...} [C] | main.rs:257:5:257:13 | enum_sink | provenance | MaD:2 Sink:MaD:2 | -| main.rs:257:15:257:43 | ...::C {...} [C] | main.rs:257:5:257:13 | enum_sink | provenance | MaD:2 Sink:MaD:2 | -| main.rs:257:41:257:41 | s | main.rs:257:15:257:43 | ...::C {...} [C] | provenance | | -| main.rs:257:41:257:41 | s | main.rs:257:15:257:43 | ...::C {...} [C] | provenance | | -| main.rs:262:9:262:9 | s | main.rs:263:39:263:39 | s | provenance | | -| main.rs:262:9:262:9 | s | main.rs:263:39:263:39 | s | provenance | | -| main.rs:262:13:262:22 | source(...) | main.rs:262:9:262:9 | s | provenance | | -| main.rs:262:13:262:22 | source(...) | main.rs:262:9:262:9 | s | provenance | | -| main.rs:263:9:263:9 | e [D] | main.rs:264:5:264:5 | e [D] | provenance | | -| main.rs:263:9:263:9 | e [D] | main.rs:264:5:264:5 | e [D] | provenance | | -| main.rs:263:13:263:41 | ...::D {...} [D] | main.rs:263:9:263:9 | e [D] | provenance | | -| main.rs:263:13:263:41 | ...::D {...} [D] | main.rs:263:9:263:9 | e [D] | provenance | | -| main.rs:263:39:263:39 | s | main.rs:263:13:263:41 | ...::D {...} [D] | provenance | | -| main.rs:263:39:263:39 | s | main.rs:263:13:263:41 | ...::D {...} [D] | provenance | | -| main.rs:264:5:264:5 | e [D] | main.rs:264:7:264:10 | sink | provenance | MaD:1 Sink:MaD:1 | -| main.rs:264:5:264:5 | e [D] | main.rs:264:7:264:10 | sink | provenance | MaD:1 Sink:MaD:1 | -| main.rs:273:9:273:9 | s | main.rs:274:10:274:10 | s | provenance | | -| main.rs:273:9:273:9 | s | main.rs:274:10:274:10 | s | provenance | | -| main.rs:273:13:273:25 | simple_source | main.rs:273:13:273:29 | simple_source(...) | provenance | Src:MaD:7 MaD:7 | -| main.rs:273:13:273:25 | simple_source | main.rs:273:13:273:29 | simple_source(...) | provenance | Src:MaD:7 MaD:7 | -| main.rs:273:13:273:29 | simple_source(...) | main.rs:273:9:273:9 | s | provenance | | -| main.rs:273:13:273:29 | simple_source(...) | main.rs:273:9:273:9 | s | provenance | | -| main.rs:281:9:281:9 | s | main.rs:282:17:282:17 | s | provenance | | -| main.rs:281:9:281:9 | s | main.rs:282:17:282:17 | s | provenance | | -| main.rs:281:13:281:22 | source(...) | main.rs:281:9:281:9 | s | provenance | | -| main.rs:281:13:281:22 | source(...) | main.rs:281:9:281:9 | s | provenance | | -| main.rs:282:17:282:17 | s | main.rs:282:5:282:15 | simple_sink | provenance | MaD:3 Sink:MaD:3 | -| main.rs:282:17:282:17 | s | main.rs:282:5:282:15 | simple_sink | provenance | MaD:3 Sink:MaD:3 | -| main.rs:290:5:290:14 | arg_source | main.rs:290:16:290:16 | [post] i | provenance | Src:MaD:5 MaD:5 | -| main.rs:290:5:290:14 | arg_source | main.rs:290:16:290:16 | [post] i | provenance | Src:MaD:5 MaD:5 | -| main.rs:290:16:290:16 | [post] i | main.rs:291:10:291:10 | i | provenance | | -| main.rs:290:16:290:16 | [post] i | main.rs:291:10:291:10 | i | provenance | | -| main.rs:343:9:343:10 | x1 | main.rs:344:10:344:11 | x1 | provenance | | -| main.rs:343:9:343:10 | x1 | main.rs:344:10:344:11 | x1 | provenance | | -| main.rs:343:14:343:23 | source(...) | main.rs:343:14:343:30 | ... .max(...) | provenance | MaD:8 | -| main.rs:343:14:343:23 | source(...) | main.rs:343:14:343:30 | ... .max(...) | provenance | MaD:8 | -| main.rs:343:14:343:30 | ... .max(...) | main.rs:343:9:343:10 | x1 | provenance | | -| main.rs:343:14:343:30 | ... .max(...) | main.rs:343:9:343:10 | x1 | provenance | | -| main.rs:346:9:346:10 | x2 [MyStruct.field1] | main.rs:354:10:354:11 | x2 [MyStruct.field1] | provenance | | -| main.rs:346:9:346:10 | x2 [MyStruct.field1] | main.rs:354:10:354:11 | x2 [MyStruct.field1] | provenance | | -| main.rs:346:14:353:6 | ... .max(...) [MyStruct.field1] | main.rs:346:9:346:10 | x2 [MyStruct.field1] | provenance | | -| main.rs:346:14:353:6 | ... .max(...) [MyStruct.field1] | main.rs:346:9:346:10 | x2 [MyStruct.field1] | provenance | | -| main.rs:346:15:349:5 | MyStruct {...} [MyStruct.field1] | main.rs:346:14:353:6 | ... .max(...) [MyStruct.field1] | provenance | MaD:8 | -| main.rs:346:15:349:5 | MyStruct {...} [MyStruct.field1] | main.rs:346:14:353:6 | ... .max(...) [MyStruct.field1] | provenance | MaD:8 | -| main.rs:347:17:347:26 | source(...) | main.rs:346:15:349:5 | MyStruct {...} [MyStruct.field1] | provenance | | -| main.rs:347:17:347:26 | source(...) | main.rs:346:15:349:5 | MyStruct {...} [MyStruct.field1] | provenance | | -| main.rs:354:10:354:11 | x2 [MyStruct.field1] | main.rs:354:10:354:18 | x2.field1 | provenance | | -| main.rs:354:10:354:11 | x2 [MyStruct.field1] | main.rs:354:10:354:18 | x2.field1 | provenance | | -| main.rs:359:9:359:10 | x4 | main.rs:360:10:360:11 | x4 | provenance | | -| main.rs:359:9:359:10 | x4 | main.rs:360:10:360:11 | x4 | provenance | | -| main.rs:359:14:359:23 | source(...) | main.rs:359:14:359:30 | ... .max(...) | provenance | MaD:8 | -| main.rs:359:14:359:23 | source(...) | main.rs:359:14:359:30 | ... .max(...) | provenance | MaD:8 | -| main.rs:359:14:359:30 | ... .max(...) | main.rs:359:9:359:10 | x4 | provenance | | -| main.rs:359:14:359:30 | ... .max(...) | main.rs:359:9:359:10 | x4 | provenance | | -| main.rs:362:9:362:10 | x5 | main.rs:363:10:363:11 | x5 | provenance | | -| main.rs:362:14:362:23 | source(...) | main.rs:362:14:362:30 | ... .lt(...) | provenance | MaD:9 | -| main.rs:362:14:362:30 | ... .lt(...) | main.rs:362:9:362:10 | x5 | provenance | | -| main.rs:365:9:365:10 | x6 | main.rs:366:10:366:11 | x6 | provenance | | -| main.rs:365:14:365:23 | source(...) | main.rs:365:14:365:27 | ... < ... | provenance | MaD:9 | -| main.rs:365:14:365:27 | ... < ... | main.rs:365:9:365:10 | x6 | provenance | | +| main.rs:283:9:283:9 | s | main.rs:284:41:284:41 | s | provenance | | +| main.rs:283:9:283:9 | s | main.rs:284:41:284:41 | s | provenance | | +| main.rs:283:13:283:22 | source(...) | main.rs:283:9:283:9 | s | provenance | | +| main.rs:283:13:283:22 | source(...) | main.rs:283:9:283:9 | s | provenance | | +| main.rs:284:15:284:43 | ...::C {...} [C] | main.rs:284:5:284:13 | enum_sink | provenance | MaD:2 Sink:MaD:2 | +| main.rs:284:15:284:43 | ...::C {...} [C] | main.rs:284:5:284:13 | enum_sink | provenance | MaD:2 Sink:MaD:2 | +| main.rs:284:41:284:41 | s | main.rs:284:15:284:43 | ...::C {...} [C] | provenance | | +| main.rs:284:41:284:41 | s | main.rs:284:15:284:43 | ...::C {...} [C] | provenance | | +| main.rs:289:9:289:9 | s | main.rs:290:39:290:39 | s | provenance | | +| main.rs:289:9:289:9 | s | main.rs:290:39:290:39 | s | provenance | | +| main.rs:289:13:289:22 | source(...) | main.rs:289:9:289:9 | s | provenance | | +| main.rs:289:13:289:22 | source(...) | main.rs:289:9:289:9 | s | provenance | | +| main.rs:290:9:290:9 | e [D] | main.rs:291:5:291:5 | e [D] | provenance | | +| main.rs:290:9:290:9 | e [D] | main.rs:291:5:291:5 | e [D] | provenance | | +| main.rs:290:13:290:41 | ...::D {...} [D] | main.rs:290:9:290:9 | e [D] | provenance | | +| main.rs:290:13:290:41 | ...::D {...} [D] | main.rs:290:9:290:9 | e [D] | provenance | | +| main.rs:290:39:290:39 | s | main.rs:290:13:290:41 | ...::D {...} [D] | provenance | | +| main.rs:290:39:290:39 | s | main.rs:290:13:290:41 | ...::D {...} [D] | provenance | | +| main.rs:291:5:291:5 | e [D] | main.rs:291:7:291:10 | sink | provenance | MaD:1 Sink:MaD:1 | +| main.rs:291:5:291:5 | e [D] | main.rs:291:7:291:10 | sink | provenance | MaD:1 Sink:MaD:1 | +| main.rs:300:9:300:9 | s | main.rs:301:10:301:10 | s | provenance | | +| main.rs:300:9:300:9 | s | main.rs:301:10:301:10 | s | provenance | | +| main.rs:300:13:300:25 | simple_source | main.rs:300:13:300:29 | simple_source(...) | provenance | Src:MaD:7 MaD:7 | +| main.rs:300:13:300:25 | simple_source | main.rs:300:13:300:29 | simple_source(...) | provenance | Src:MaD:7 MaD:7 | +| main.rs:300:13:300:29 | simple_source(...) | main.rs:300:9:300:9 | s | provenance | | +| main.rs:300:13:300:29 | simple_source(...) | main.rs:300:9:300:9 | s | provenance | | +| main.rs:308:9:308:9 | s | main.rs:309:17:309:17 | s | provenance | | +| main.rs:308:9:308:9 | s | main.rs:309:17:309:17 | s | provenance | | +| main.rs:308:13:308:22 | source(...) | main.rs:308:9:308:9 | s | provenance | | +| main.rs:308:13:308:22 | source(...) | main.rs:308:9:308:9 | s | provenance | | +| main.rs:309:17:309:17 | s | main.rs:309:5:309:15 | simple_sink | provenance | MaD:3 Sink:MaD:3 | +| main.rs:309:17:309:17 | s | main.rs:309:5:309:15 | simple_sink | provenance | MaD:3 Sink:MaD:3 | +| main.rs:317:5:317:14 | arg_source | main.rs:317:16:317:16 | [post] i | provenance | Src:MaD:5 MaD:5 | +| main.rs:317:5:317:14 | arg_source | main.rs:317:16:317:16 | [post] i | provenance | Src:MaD:5 MaD:5 | +| main.rs:317:16:317:16 | [post] i | main.rs:318:10:318:10 | i | provenance | | +| main.rs:317:16:317:16 | [post] i | main.rs:318:10:318:10 | i | provenance | | +| main.rs:370:9:370:10 | x1 | main.rs:371:10:371:11 | x1 | provenance | | +| main.rs:370:9:370:10 | x1 | main.rs:371:10:371:11 | x1 | provenance | | +| main.rs:370:14:370:23 | source(...) | main.rs:370:14:370:30 | ... .max(...) | provenance | MaD:8 | +| main.rs:370:14:370:23 | source(...) | main.rs:370:14:370:30 | ... .max(...) | provenance | MaD:8 | +| main.rs:370:14:370:30 | ... .max(...) | main.rs:370:9:370:10 | x1 | provenance | | +| main.rs:370:14:370:30 | ... .max(...) | main.rs:370:9:370:10 | x1 | provenance | | +| main.rs:373:9:373:10 | x2 [MyStruct.field1] | main.rs:381:10:381:11 | x2 [MyStruct.field1] | provenance | | +| main.rs:373:9:373:10 | x2 [MyStruct.field1] | main.rs:381:10:381:11 | x2 [MyStruct.field1] | provenance | | +| main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | main.rs:373:9:373:10 | x2 [MyStruct.field1] | provenance | | +| main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | main.rs:373:9:373:10 | x2 [MyStruct.field1] | provenance | | +| main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | provenance | MaD:8 | +| main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | provenance | MaD:8 | +| main.rs:374:17:374:26 | source(...) | main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | provenance | | +| main.rs:374:17:374:26 | source(...) | main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | provenance | | +| main.rs:381:10:381:11 | x2 [MyStruct.field1] | main.rs:381:10:381:18 | x2.field1 | provenance | | +| main.rs:381:10:381:11 | x2 [MyStruct.field1] | main.rs:381:10:381:18 | x2.field1 | provenance | | +| main.rs:386:9:386:10 | x4 | main.rs:387:10:387:11 | x4 | provenance | | +| main.rs:386:9:386:10 | x4 | main.rs:387:10:387:11 | x4 | provenance | | +| main.rs:386:14:386:23 | source(...) | main.rs:386:14:386:30 | ... .max(...) | provenance | MaD:8 | +| main.rs:386:14:386:23 | source(...) | main.rs:386:14:386:30 | ... .max(...) | provenance | MaD:8 | +| main.rs:386:14:386:30 | ... .max(...) | main.rs:386:9:386:10 | x4 | provenance | | +| main.rs:386:14:386:30 | ... .max(...) | main.rs:386:9:386:10 | x4 | provenance | | +| main.rs:389:9:389:10 | x5 | main.rs:390:10:390:11 | x5 | provenance | | +| main.rs:389:14:389:23 | source(...) | main.rs:389:14:389:30 | ... .lt(...) | provenance | MaD:9 | +| main.rs:389:14:389:30 | ... .lt(...) | main.rs:389:9:389:10 | x5 | provenance | | +| main.rs:392:9:392:10 | x6 | main.rs:393:10:393:11 | x6 | provenance | | +| main.rs:392:14:392:23 | source(...) | main.rs:392:14:392:27 | ... < ... | provenance | MaD:9 | +| main.rs:392:14:392:27 | ... < ... | main.rs:392:9:392:10 | x6 | provenance | | nodes | main.rs:15:9:15:9 | s | semmle.label | s | | main.rs:15:9:15:9 | s | semmle.label | s | @@ -533,88 +533,88 @@ nodes | main.rs:247:35:247:35 | i | semmle.label | i | | main.rs:247:47:247:47 | i | semmle.label | i | | main.rs:247:47:247:47 | i | semmle.label | i | -| main.rs:256:9:256:9 | s | semmle.label | s | -| main.rs:256:9:256:9 | s | semmle.label | s | -| main.rs:256:13:256:22 | source(...) | semmle.label | source(...) | -| main.rs:256:13:256:22 | source(...) | semmle.label | source(...) | -| main.rs:257:5:257:13 | enum_sink | semmle.label | enum_sink | -| main.rs:257:5:257:13 | enum_sink | semmle.label | enum_sink | -| main.rs:257:15:257:43 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:257:15:257:43 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | -| main.rs:257:41:257:41 | s | semmle.label | s | -| main.rs:257:41:257:41 | s | semmle.label | s | -| main.rs:262:9:262:9 | s | semmle.label | s | -| main.rs:262:9:262:9 | s | semmle.label | s | -| main.rs:262:13:262:22 | source(...) | semmle.label | source(...) | -| main.rs:262:13:262:22 | source(...) | semmle.label | source(...) | -| main.rs:263:9:263:9 | e [D] | semmle.label | e [D] | -| main.rs:263:9:263:9 | e [D] | semmle.label | e [D] | -| main.rs:263:13:263:41 | ...::D {...} [D] | semmle.label | ...::D {...} [D] | -| main.rs:263:13:263:41 | ...::D {...} [D] | semmle.label | ...::D {...} [D] | -| main.rs:263:39:263:39 | s | semmle.label | s | -| main.rs:263:39:263:39 | s | semmle.label | s | -| main.rs:264:5:264:5 | e [D] | semmle.label | e [D] | -| main.rs:264:5:264:5 | e [D] | semmle.label | e [D] | -| main.rs:264:7:264:10 | sink | semmle.label | sink | -| main.rs:264:7:264:10 | sink | semmle.label | sink | -| main.rs:273:9:273:9 | s | semmle.label | s | -| main.rs:273:9:273:9 | s | semmle.label | s | -| main.rs:273:13:273:25 | simple_source | semmle.label | simple_source | -| main.rs:273:13:273:25 | simple_source | semmle.label | simple_source | -| main.rs:273:13:273:29 | simple_source(...) | semmle.label | simple_source(...) | -| main.rs:273:13:273:29 | simple_source(...) | semmle.label | simple_source(...) | -| main.rs:274:10:274:10 | s | semmle.label | s | -| main.rs:274:10:274:10 | s | semmle.label | s | -| main.rs:281:9:281:9 | s | semmle.label | s | -| main.rs:281:9:281:9 | s | semmle.label | s | -| main.rs:281:13:281:22 | source(...) | semmle.label | source(...) | -| main.rs:281:13:281:22 | source(...) | semmle.label | source(...) | -| main.rs:282:5:282:15 | simple_sink | semmle.label | simple_sink | -| main.rs:282:5:282:15 | simple_sink | semmle.label | simple_sink | -| main.rs:282:17:282:17 | s | semmle.label | s | -| main.rs:282:17:282:17 | s | semmle.label | s | -| main.rs:290:5:290:14 | arg_source | semmle.label | arg_source | -| main.rs:290:5:290:14 | arg_source | semmle.label | arg_source | -| main.rs:290:16:290:16 | [post] i | semmle.label | [post] i | -| main.rs:290:16:290:16 | [post] i | semmle.label | [post] i | -| main.rs:291:10:291:10 | i | semmle.label | i | -| main.rs:291:10:291:10 | i | semmle.label | i | -| main.rs:343:9:343:10 | x1 | semmle.label | x1 | -| main.rs:343:9:343:10 | x1 | semmle.label | x1 | -| main.rs:343:14:343:23 | source(...) | semmle.label | source(...) | -| main.rs:343:14:343:23 | source(...) | semmle.label | source(...) | -| main.rs:343:14:343:30 | ... .max(...) | semmle.label | ... .max(...) | -| main.rs:343:14:343:30 | ... .max(...) | semmle.label | ... .max(...) | -| main.rs:344:10:344:11 | x1 | semmle.label | x1 | -| main.rs:344:10:344:11 | x1 | semmle.label | x1 | -| main.rs:346:9:346:10 | x2 [MyStruct.field1] | semmle.label | x2 [MyStruct.field1] | -| main.rs:346:9:346:10 | x2 [MyStruct.field1] | semmle.label | x2 [MyStruct.field1] | -| main.rs:346:14:353:6 | ... .max(...) [MyStruct.field1] | semmle.label | ... .max(...) [MyStruct.field1] | -| main.rs:346:14:353:6 | ... .max(...) [MyStruct.field1] | semmle.label | ... .max(...) [MyStruct.field1] | -| main.rs:346:15:349:5 | MyStruct {...} [MyStruct.field1] | semmle.label | MyStruct {...} [MyStruct.field1] | -| main.rs:346:15:349:5 | MyStruct {...} [MyStruct.field1] | semmle.label | MyStruct {...} [MyStruct.field1] | -| main.rs:347:17:347:26 | source(...) | semmle.label | source(...) | -| main.rs:347:17:347:26 | source(...) | semmle.label | source(...) | -| main.rs:354:10:354:11 | x2 [MyStruct.field1] | semmle.label | x2 [MyStruct.field1] | -| main.rs:354:10:354:11 | x2 [MyStruct.field1] | semmle.label | x2 [MyStruct.field1] | -| main.rs:354:10:354:18 | x2.field1 | semmle.label | x2.field1 | -| main.rs:354:10:354:18 | x2.field1 | semmle.label | x2.field1 | -| main.rs:359:9:359:10 | x4 | semmle.label | x4 | -| main.rs:359:9:359:10 | x4 | semmle.label | x4 | -| main.rs:359:14:359:23 | source(...) | semmle.label | source(...) | -| main.rs:359:14:359:23 | source(...) | semmle.label | source(...) | -| main.rs:359:14:359:30 | ... .max(...) | semmle.label | ... .max(...) | -| main.rs:359:14:359:30 | ... .max(...) | semmle.label | ... .max(...) | -| main.rs:360:10:360:11 | x4 | semmle.label | x4 | -| main.rs:360:10:360:11 | x4 | semmle.label | x4 | -| main.rs:362:9:362:10 | x5 | semmle.label | x5 | -| main.rs:362:14:362:23 | source(...) | semmle.label | source(...) | -| main.rs:362:14:362:30 | ... .lt(...) | semmle.label | ... .lt(...) | -| main.rs:363:10:363:11 | x5 | semmle.label | x5 | -| main.rs:365:9:365:10 | x6 | semmle.label | x6 | -| main.rs:365:14:365:23 | source(...) | semmle.label | source(...) | -| main.rs:365:14:365:27 | ... < ... | semmle.label | ... < ... | -| main.rs:366:10:366:11 | x6 | semmle.label | x6 | +| main.rs:283:9:283:9 | s | semmle.label | s | +| main.rs:283:9:283:9 | s | semmle.label | s | +| main.rs:283:13:283:22 | source(...) | semmle.label | source(...) | +| main.rs:283:13:283:22 | source(...) | semmle.label | source(...) | +| main.rs:284:5:284:13 | enum_sink | semmle.label | enum_sink | +| main.rs:284:5:284:13 | enum_sink | semmle.label | enum_sink | +| main.rs:284:15:284:43 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:284:15:284:43 | ...::C {...} [C] | semmle.label | ...::C {...} [C] | +| main.rs:284:41:284:41 | s | semmle.label | s | +| main.rs:284:41:284:41 | s | semmle.label | s | +| main.rs:289:9:289:9 | s | semmle.label | s | +| main.rs:289:9:289:9 | s | semmle.label | s | +| main.rs:289:13:289:22 | source(...) | semmle.label | source(...) | +| main.rs:289:13:289:22 | source(...) | semmle.label | source(...) | +| main.rs:290:9:290:9 | e [D] | semmle.label | e [D] | +| main.rs:290:9:290:9 | e [D] | semmle.label | e [D] | +| main.rs:290:13:290:41 | ...::D {...} [D] | semmle.label | ...::D {...} [D] | +| main.rs:290:13:290:41 | ...::D {...} [D] | semmle.label | ...::D {...} [D] | +| main.rs:290:39:290:39 | s | semmle.label | s | +| main.rs:290:39:290:39 | s | semmle.label | s | +| main.rs:291:5:291:5 | e [D] | semmle.label | e [D] | +| main.rs:291:5:291:5 | e [D] | semmle.label | e [D] | +| main.rs:291:7:291:10 | sink | semmle.label | sink | +| main.rs:291:7:291:10 | sink | semmle.label | sink | +| main.rs:300:9:300:9 | s | semmle.label | s | +| main.rs:300:9:300:9 | s | semmle.label | s | +| main.rs:300:13:300:25 | simple_source | semmle.label | simple_source | +| main.rs:300:13:300:25 | simple_source | semmle.label | simple_source | +| main.rs:300:13:300:29 | simple_source(...) | semmle.label | simple_source(...) | +| main.rs:300:13:300:29 | simple_source(...) | semmle.label | simple_source(...) | +| main.rs:301:10:301:10 | s | semmle.label | s | +| main.rs:301:10:301:10 | s | semmle.label | s | +| main.rs:308:9:308:9 | s | semmle.label | s | +| main.rs:308:9:308:9 | s | semmle.label | s | +| main.rs:308:13:308:22 | source(...) | semmle.label | source(...) | +| main.rs:308:13:308:22 | source(...) | semmle.label | source(...) | +| main.rs:309:5:309:15 | simple_sink | semmle.label | simple_sink | +| main.rs:309:5:309:15 | simple_sink | semmle.label | simple_sink | +| main.rs:309:17:309:17 | s | semmle.label | s | +| main.rs:309:17:309:17 | s | semmle.label | s | +| main.rs:317:5:317:14 | arg_source | semmle.label | arg_source | +| main.rs:317:5:317:14 | arg_source | semmle.label | arg_source | +| main.rs:317:16:317:16 | [post] i | semmle.label | [post] i | +| main.rs:317:16:317:16 | [post] i | semmle.label | [post] i | +| main.rs:318:10:318:10 | i | semmle.label | i | +| main.rs:318:10:318:10 | i | semmle.label | i | +| main.rs:370:9:370:10 | x1 | semmle.label | x1 | +| main.rs:370:9:370:10 | x1 | semmle.label | x1 | +| main.rs:370:14:370:23 | source(...) | semmle.label | source(...) | +| main.rs:370:14:370:23 | source(...) | semmle.label | source(...) | +| main.rs:370:14:370:30 | ... .max(...) | semmle.label | ... .max(...) | +| main.rs:370:14:370:30 | ... .max(...) | semmle.label | ... .max(...) | +| main.rs:371:10:371:11 | x1 | semmle.label | x1 | +| main.rs:371:10:371:11 | x1 | semmle.label | x1 | +| main.rs:373:9:373:10 | x2 [MyStruct.field1] | semmle.label | x2 [MyStruct.field1] | +| main.rs:373:9:373:10 | x2 [MyStruct.field1] | semmle.label | x2 [MyStruct.field1] | +| main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | semmle.label | ... .max(...) [MyStruct.field1] | +| main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | semmle.label | ... .max(...) [MyStruct.field1] | +| main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | semmle.label | MyStruct {...} [MyStruct.field1] | +| main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | semmle.label | MyStruct {...} [MyStruct.field1] | +| main.rs:374:17:374:26 | source(...) | semmle.label | source(...) | +| main.rs:374:17:374:26 | source(...) | semmle.label | source(...) | +| main.rs:381:10:381:11 | x2 [MyStruct.field1] | semmle.label | x2 [MyStruct.field1] | +| main.rs:381:10:381:11 | x2 [MyStruct.field1] | semmle.label | x2 [MyStruct.field1] | +| main.rs:381:10:381:18 | x2.field1 | semmle.label | x2.field1 | +| main.rs:381:10:381:18 | x2.field1 | semmle.label | x2.field1 | +| main.rs:386:9:386:10 | x4 | semmle.label | x4 | +| main.rs:386:9:386:10 | x4 | semmle.label | x4 | +| main.rs:386:14:386:23 | source(...) | semmle.label | source(...) | +| main.rs:386:14:386:23 | source(...) | semmle.label | source(...) | +| main.rs:386:14:386:30 | ... .max(...) | semmle.label | ... .max(...) | +| main.rs:386:14:386:30 | ... .max(...) | semmle.label | ... .max(...) | +| main.rs:387:10:387:11 | x4 | semmle.label | x4 | +| main.rs:387:10:387:11 | x4 | semmle.label | x4 | +| main.rs:389:9:389:10 | x5 | semmle.label | x5 | +| main.rs:389:14:389:23 | source(...) | semmle.label | source(...) | +| main.rs:389:14:389:30 | ... .lt(...) | semmle.label | ... .lt(...) | +| main.rs:390:10:390:11 | x5 | semmle.label | x5 | +| main.rs:392:9:392:10 | x6 | semmle.label | x6 | +| main.rs:392:14:392:23 | source(...) | semmle.label | source(...) | +| main.rs:392:14:392:27 | ... < ... | semmle.label | ... < ... | +| main.rs:393:10:393:11 | x6 | semmle.label | x6 | subpaths | main.rs:198:23:198:23 | f [captured s] | main.rs:197:40:197:40 | s | main.rs:197:17:197:42 | if ... {...} else {...} | main.rs:198:13:198:24 | apply(...) | | main.rs:198:23:198:23 | f [captured s] | main.rs:197:40:197:40 | s | main.rs:197:17:197:42 | if ... {...} else {...} | main.rs:198:13:198:24 | apply(...) | @@ -658,21 +658,21 @@ invalidSpecComponent | main.rs:239:47:239:47 | i | main.rs:236:13:236:23 | enum_source | main.rs:239:47:239:47 | i | $@ | main.rs:236:13:236:23 | enum_source | enum_source | | main.rs:247:47:247:47 | i | main.rs:245:15:245:20 | source | main.rs:247:47:247:47 | i | $@ | main.rs:245:15:245:20 | source | source | | main.rs:247:47:247:47 | i | main.rs:245:15:245:20 | source | main.rs:247:47:247:47 | i | $@ | main.rs:245:15:245:20 | source | source | -| main.rs:257:5:257:13 | enum_sink | main.rs:256:13:256:22 | source(...) | main.rs:257:5:257:13 | enum_sink | $@ | main.rs:256:13:256:22 | source(...) | source(...) | -| main.rs:257:5:257:13 | enum_sink | main.rs:256:13:256:22 | source(...) | main.rs:257:5:257:13 | enum_sink | $@ | main.rs:256:13:256:22 | source(...) | source(...) | -| main.rs:264:7:264:10 | sink | main.rs:262:13:262:22 | source(...) | main.rs:264:7:264:10 | sink | $@ | main.rs:262:13:262:22 | source(...) | source(...) | -| main.rs:264:7:264:10 | sink | main.rs:262:13:262:22 | source(...) | main.rs:264:7:264:10 | sink | $@ | main.rs:262:13:262:22 | source(...) | source(...) | -| main.rs:274:10:274:10 | s | main.rs:273:13:273:25 | simple_source | main.rs:274:10:274:10 | s | $@ | main.rs:273:13:273:25 | simple_source | simple_source | -| main.rs:274:10:274:10 | s | main.rs:273:13:273:25 | simple_source | main.rs:274:10:274:10 | s | $@ | main.rs:273:13:273:25 | simple_source | simple_source | -| main.rs:282:5:282:15 | simple_sink | main.rs:281:13:281:22 | source(...) | main.rs:282:5:282:15 | simple_sink | $@ | main.rs:281:13:281:22 | source(...) | source(...) | -| main.rs:282:5:282:15 | simple_sink | main.rs:281:13:281:22 | source(...) | main.rs:282:5:282:15 | simple_sink | $@ | main.rs:281:13:281:22 | source(...) | source(...) | -| main.rs:291:10:291:10 | i | main.rs:290:5:290:14 | arg_source | main.rs:291:10:291:10 | i | $@ | main.rs:290:5:290:14 | arg_source | arg_source | -| main.rs:291:10:291:10 | i | main.rs:290:5:290:14 | arg_source | main.rs:291:10:291:10 | i | $@ | main.rs:290:5:290:14 | arg_source | arg_source | -| main.rs:344:10:344:11 | x1 | main.rs:343:14:343:23 | source(...) | main.rs:344:10:344:11 | x1 | $@ | main.rs:343:14:343:23 | source(...) | source(...) | -| main.rs:344:10:344:11 | x1 | main.rs:343:14:343:23 | source(...) | main.rs:344:10:344:11 | x1 | $@ | main.rs:343:14:343:23 | source(...) | source(...) | -| main.rs:354:10:354:18 | x2.field1 | main.rs:347:17:347:26 | source(...) | main.rs:354:10:354:18 | x2.field1 | $@ | main.rs:347:17:347:26 | source(...) | source(...) | -| main.rs:354:10:354:18 | x2.field1 | main.rs:347:17:347:26 | source(...) | main.rs:354:10:354:18 | x2.field1 | $@ | main.rs:347:17:347:26 | source(...) | source(...) | -| main.rs:360:10:360:11 | x4 | main.rs:359:14:359:23 | source(...) | main.rs:360:10:360:11 | x4 | $@ | main.rs:359:14:359:23 | source(...) | source(...) | -| main.rs:360:10:360:11 | x4 | main.rs:359:14:359:23 | source(...) | main.rs:360:10:360:11 | x4 | $@ | main.rs:359:14:359:23 | source(...) | source(...) | -| main.rs:363:10:363:11 | x5 | main.rs:362:14:362:23 | source(...) | main.rs:363:10:363:11 | x5 | $@ | main.rs:362:14:362:23 | source(...) | source(...) | -| main.rs:366:10:366:11 | x6 | main.rs:365:14:365:23 | source(...) | main.rs:366:10:366:11 | x6 | $@ | main.rs:365:14:365:23 | source(...) | source(...) | +| main.rs:284:5:284:13 | enum_sink | main.rs:283:13:283:22 | source(...) | main.rs:284:5:284:13 | enum_sink | $@ | main.rs:283:13:283:22 | source(...) | source(...) | +| main.rs:284:5:284:13 | enum_sink | main.rs:283:13:283:22 | source(...) | main.rs:284:5:284:13 | enum_sink | $@ | main.rs:283:13:283:22 | source(...) | source(...) | +| main.rs:291:7:291:10 | sink | main.rs:289:13:289:22 | source(...) | main.rs:291:7:291:10 | sink | $@ | main.rs:289:13:289:22 | source(...) | source(...) | +| main.rs:291:7:291:10 | sink | main.rs:289:13:289:22 | source(...) | main.rs:291:7:291:10 | sink | $@ | main.rs:289:13:289:22 | source(...) | source(...) | +| main.rs:301:10:301:10 | s | main.rs:300:13:300:25 | simple_source | main.rs:301:10:301:10 | s | $@ | main.rs:300:13:300:25 | simple_source | simple_source | +| main.rs:301:10:301:10 | s | main.rs:300:13:300:25 | simple_source | main.rs:301:10:301:10 | s | $@ | main.rs:300:13:300:25 | simple_source | simple_source | +| main.rs:309:5:309:15 | simple_sink | main.rs:308:13:308:22 | source(...) | main.rs:309:5:309:15 | simple_sink | $@ | main.rs:308:13:308:22 | source(...) | source(...) | +| main.rs:309:5:309:15 | simple_sink | main.rs:308:13:308:22 | source(...) | main.rs:309:5:309:15 | simple_sink | $@ | main.rs:308:13:308:22 | source(...) | source(...) | +| main.rs:318:10:318:10 | i | main.rs:317:5:317:14 | arg_source | main.rs:318:10:318:10 | i | $@ | main.rs:317:5:317:14 | arg_source | arg_source | +| main.rs:318:10:318:10 | i | main.rs:317:5:317:14 | arg_source | main.rs:318:10:318:10 | i | $@ | main.rs:317:5:317:14 | arg_source | arg_source | +| main.rs:371:10:371:11 | x1 | main.rs:370:14:370:23 | source(...) | main.rs:371:10:371:11 | x1 | $@ | main.rs:370:14:370:23 | source(...) | source(...) | +| main.rs:371:10:371:11 | x1 | main.rs:370:14:370:23 | source(...) | main.rs:371:10:371:11 | x1 | $@ | main.rs:370:14:370:23 | source(...) | source(...) | +| main.rs:381:10:381:18 | x2.field1 | main.rs:374:17:374:26 | source(...) | main.rs:381:10:381:18 | x2.field1 | $@ | main.rs:374:17:374:26 | source(...) | source(...) | +| main.rs:381:10:381:18 | x2.field1 | main.rs:374:17:374:26 | source(...) | main.rs:381:10:381:18 | x2.field1 | $@ | main.rs:374:17:374:26 | source(...) | source(...) | +| main.rs:387:10:387:11 | x4 | main.rs:386:14:386:23 | source(...) | main.rs:387:10:387:11 | x4 | $@ | main.rs:386:14:386:23 | source(...) | source(...) | +| main.rs:387:10:387:11 | x4 | main.rs:386:14:386:23 | source(...) | main.rs:387:10:387:11 | x4 | $@ | main.rs:386:14:386:23 | source(...) | source(...) | +| main.rs:390:10:390:11 | x5 | main.rs:389:14:389:23 | source(...) | main.rs:390:10:390:11 | x5 | $@ | main.rs:389:14:389:23 | source(...) | source(...) | +| main.rs:393:10:393:11 | x6 | main.rs:392:14:392:23 | source(...) | main.rs:393:10:393:11 | x6 | $@ | main.rs:392:14:392:23 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/models/models.ext.yml b/rust/ql/test/library-tests/dataflow/models/models.ext.yml index eb51ac64f50..52342e88022 100644 --- a/rust/ql/test/library-tests/dataflow/models/models.ext.yml +++ b/rust/ql/test/library-tests/dataflow/models/models.ext.yml @@ -7,6 +7,7 @@ extensions: - ["main::enum_source", "ReturnValue.Field[main::MyFieldEnum::D::field_d]", "test-source", "manual"] - ["::source", "ReturnValue.Field[main::MyFieldEnum::C::field_c]", "test-source", "manual"] - ["main::arg_source", "Argument[0]", "test-source", "manual"] + - ["main::source_into_function::pass_source", "Argument[1].Parameter[0]", "test-source", "manual"] - addsTo: pack: codeql/rust-all extensible: sinkModel From 05a58323c1eca9a8c929209a17965ecbb6a88b43 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 18 Sep 2025 10:02:25 +0200 Subject: [PATCH 064/160] Rust: Add Warp test to request forgery query tests --- .../query-tests/security/CWE-918/Cargo.lock | 73 +++++++++++++++++++ .../query-tests/security/CWE-918/options.yml | 1 + .../security/CWE-918/request_forgery_tests.rs | 20 +++++ 3 files changed, 94 insertions(+) diff --git a/rust/ql/test/query-tests/security/CWE-918/Cargo.lock b/rust/ql/test/query-tests/security/CWE-918/Cargo.lock index 83c077741bc..d00e99a2909 100644 --- a/rust/ql/test/query-tests/security/CWE-918/Cargo.lock +++ b/rust/ql/test/query-tests/security/CWE-918/Cargo.lock @@ -714,6 +714,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -851,6 +861,26 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -1132,6 +1162,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -1337,6 +1373,7 @@ dependencies = [ "poem", "reqwest", "tokio", + "warp", ] [[package]] @@ -1501,6 +1538,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -1547,6 +1585,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + [[package]] name = "unicode-ident" version = "1.0.18" @@ -1598,6 +1642,35 @@ dependencies = [ "try-lock", ] +[[package]] +name = "warp" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d06d9202adc1f15d709c4f4a2069be5428aa912cc025d6f268ac441ab066b0" +dependencies = [ + "bytes", + "futures-util", + "headers", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "log", + "mime", + "mime_guess", + "percent-encoding", + "pin-project", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-util", + "tower-service", + "tracing", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" diff --git a/rust/ql/test/query-tests/security/CWE-918/options.yml b/rust/ql/test/query-tests/security/CWE-918/options.yml index 078784053e1..6c6a1517497 100644 --- a/rust/ql/test/query-tests/security/CWE-918/options.yml +++ b/rust/ql/test/query-tests/security/CWE-918/options.yml @@ -3,3 +3,4 @@ qltest_dependencies: - reqwest = { version = "0.12.23", features = ["blocking", "json"] } - tokio = { version = "1.0", features = ["full"] } - poem = { version = "3.1.12", features = ["server"] } + - warp = { version = "0.4.2", features = ["server"] } diff --git a/rust/ql/test/query-tests/security/CWE-918/request_forgery_tests.rs b/rust/ql/test/query-tests/security/CWE-918/request_forgery_tests.rs index d9f2e1ae5c4..ab99d73db43 100644 --- a/rust/ql/test/query-tests/security/CWE-918/request_forgery_tests.rs +++ b/rust/ql/test/query-tests/security/CWE-918/request_forgery_tests.rs @@ -54,6 +54,26 @@ mod poem_server { } } +mod warp_test { + use warp::Filter; + + #[tokio::main] + #[rustfmt::skip] + async fn test_warp() { + // A route with parameter and `and_then` + let map_route = + warp::path::param().and_then(async |a: String| // $ MISSING: Source=a + { + + let response = reqwest::get(&a).await; // $ MISSING: Alert[rust/request-forgery]=a + match response { + Ok(resp) => Ok(resp.text().await.unwrap_or_default()), + Err(_err) => Err(warp::reject::not_found()), + } + }); + } +} + /// Start the Poem web application pub fn start() { tokio::runtime::Runtime::new() From 014c27ee8a501f31dadb133f1df0ef80f3141b97 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 17 Sep 2025 11:13:16 +0200 Subject: [PATCH 065/160] Rust: Discard sources with spaces in inline flow tests --- rust/ql/lib/utils/test/InlineFlowTest.qll | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/rust/ql/lib/utils/test/InlineFlowTest.qll b/rust/ql/lib/utils/test/InlineFlowTest.qll index 80abf21e1f5..9ba92f7757b 100644 --- a/rust/ql/lib/utils/test/InlineFlowTest.qll +++ b/rust/ql/lib/utils/test/InlineFlowTest.qll @@ -34,10 +34,9 @@ private module FlowTestImpl implements InputSig { result = src.asExpr().(CallExprCfgNode).getArgument(0).toString() or sourceNode(src, _) and - exists(CallExprBase call | - call = src.(Node::FlowSummaryNode).getSourceElement().getCall() and - result = call.getArgList().getArg(0).toString() - ) + result = src.(Node::FlowSummaryNode).getSourceElement().getCall().getArg(0).toString() and + // Don't use the result if it contains spaces + not result.matches("% %") } bindingset[src, sink] From 265e8b3623d3554777821cc068f17db4626bb015 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 17 Sep 2025 13:56:48 +0200 Subject: [PATCH 066/160] Shared: Pass SummaryComponentStack to isSource and getSourceType --- .../rust/dataflow/internal/DataFlowImpl.qll | 3 +- .../dataflow/internal/FlowSummaryImpl.qll | 45 +- .../library-tests/dataflow/models/main.rs | 8 +- .../dataflow/models/models.expected | 163 ++-- .../dataflow/sources/InlineFlow.expected | 897 +++++++++--------- .../dataflow/sources/web_frameworks.rs | 8 +- .../security/CWE-918/RequestForgery.expected | 37 +- .../security/CWE-918/request_forgery_tests.rs | 4 +- .../dataflow/internal/FlowSummaryImpl.qll | 40 +- 9 files changed, 686 insertions(+), 519 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll index 1d7a3d49cf4..4c252dfcd0f 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll @@ -508,7 +508,8 @@ module RustDataFlow implements InputSig { */ predicate jumpStep(Node node1, Node node2) { FlowSummaryImpl::Private::Steps::summaryJumpStep(node1.(FlowSummaryNode).getSummaryNode(), - node2.(FlowSummaryNode).getSummaryNode()) + node2.(FlowSummaryNode).getSummaryNode()) or + FlowSummaryImpl::Private::Steps::sourceJumpStep(node1.(FlowSummaryNode).getSummaryNode(), node2) } pragma[nomagic] diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll index 997f27e51e1..129bd468e01 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll @@ -6,7 +6,10 @@ private import rust private import codeql.dataflow.internal.FlowSummaryImpl private import codeql.dataflow.internal.AccessPathSyntax as AccessPath private import codeql.rust.dataflow.internal.DataFlowImpl +private import codeql.rust.internal.PathResolution private import codeql.rust.dataflow.FlowSummary +private import codeql.rust.dataflow.Ssa +private import codeql.rust.controlflow.CfgNodes private import Content module Input implements InputSig { @@ -133,16 +136,44 @@ private module StepsInput implements Impl::Private::StepsInputSig { result.asCallCfgNode().getCall().getStaticTarget() = sc } - RustDataFlow::Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { - sc = Impl::Private::SummaryComponent::return(_) and + /** Gets the argument of `source` described by `sc`, if any. */ + private Expr getSourceNodeArgument(Input::SourceBase source, Impl::Private::SummaryComponent sc) { + exists(ArgumentPosition pos | + sc = Impl::Private::SummaryComponent::argument(pos) and + result = pos.getArgument(source.getCall()) + ) + } + + /** Get the callable that `expr` refers to. */ + private Callable getCallable(Expr expr) { + result = resolvePath(expr.(PathExpr).getPath()).(Function) + or + result = expr.(ClosureExpr) + or + // The expression is an SSA read of an assignment of a closure + exists(Ssa::Definition def, ExprCfgNode value | + def.getARead().getAstNode() = expr and + def.getAnUltimateDefinition().(Ssa::WriteDefinition).assigns(value) and + result = value.getExpr().(ClosureExpr) + ) + } + + RustDataFlow::DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { + result.asCfgScope() = source.getEnclosingCfgScope() + } + + RustDataFlow::Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { + s.head() = Impl::Private::SummaryComponent::return(_) and result.asExpr().getExpr() = source.getCall() or - exists(CallExprBase call, Expr arg, ArgumentPosition pos | - result.(RustDataFlow::PostUpdateNode).getPreUpdateNode().asExpr().getExpr() = arg and - sc = Impl::Private::SummaryComponent::argument(pos) and - call = source.getCall() and - arg = pos.getArgument(call) + exists(ArgumentPosition pos, Expr arg | + s.head() = Impl::Private::SummaryComponent::parameter(pos) and + arg = getSourceNodeArgument(source, s.tail().head()) and + result.asParameter() = getCallable(arg).getParam(pos.getPosition()) ) + or + result.(RustDataFlow::PostUpdateNode).getPreUpdateNode().asExpr().getExpr() = + getSourceNodeArgument(source, s.head()) } RustDataFlow::Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { diff --git a/rust/ql/test/library-tests/dataflow/models/main.rs b/rust/ql/test/library-tests/dataflow/models/main.rs index 98a45655035..7daa883996f 100644 --- a/rust/ql/test/library-tests/dataflow/models/main.rs +++ b/rust/ql/test/library-tests/dataflow/models/main.rs @@ -258,20 +258,20 @@ mod source_into_function { } fn test_source_into_function() { - let a = |a| sink(a); // $ MISSING: hasValueFlow=1 + let a = |a| sink(a); // $ hasValueFlow=1 pass_source(1, a); pass_source(2, |a| { - sink(a); // $ MISSING: hasValueFlow=2 + sink(a); // $ hasValueFlow=2 }); fn f(a: i64) { - sink(a) // $ MISSING: hasValueFlow=3 + sink(a) // $ hasValueFlow=3 } pass_source(3, f); pass_source(4, async move |a| { - sink(a); // $ MISSING: hasValueFlow=4 + sink(a); // $ hasValueFlow=4 }); } } diff --git a/rust/ql/test/library-tests/dataflow/models/models.expected b/rust/ql/test/library-tests/dataflow/models/models.expected index c04b66068db..2918e5c3c39 100644 --- a/rust/ql/test/library-tests/dataflow/models/models.expected +++ b/rust/ql/test/library-tests/dataflow/models/models.expected @@ -6,22 +6,23 @@ models | 5 | Source: main::arg_source; Argument[0]; test-source | | 6 | Source: main::enum_source; ReturnValue.Field[main::MyFieldEnum::D::field_d]; test-source | | 7 | Source: main::simple_source; ReturnValue; test-source | -| 8 | Summary: <_ as core::cmp::Ord>::max; Argument[self]; ReturnValue; value | -| 9 | Summary: <_ as core::cmp::PartialOrd>::lt; Argument[self].Reference; ReturnValue; taint | -| 10 | Summary: main::apply; Argument[0]; Argument[1].Parameter[0]; value | -| 11 | Summary: main::apply; Argument[1].ReturnValue; ReturnValue; value | -| 12 | Summary: main::coerce; Argument[0]; ReturnValue; taint | -| 13 | Summary: main::get_array_element; Argument[0].Element; ReturnValue; value | -| 14 | Summary: main::get_async_number; Argument[0]; ReturnValue.Future; value | -| 15 | Summary: main::get_struct_field; Argument[0].Field[main::MyStruct::field1]; ReturnValue; value | -| 16 | Summary: main::get_tuple_element; Argument[0].Field[0]; ReturnValue; value | -| 17 | Summary: main::get_var_field; Argument[0].Field[main::MyFieldEnum::C::field_c]; ReturnValue; value | -| 18 | Summary: main::get_var_pos; Argument[0].Field[main::MyPosEnum::A(0)]; ReturnValue; value | -| 19 | Summary: main::set_array_element; Argument[0]; ReturnValue.Element; value | -| 20 | Summary: main::set_struct_field; Argument[0]; ReturnValue.Field[main::MyStruct::field2]; value | -| 21 | Summary: main::set_tuple_element; Argument[0]; ReturnValue.Field[1]; value | -| 22 | Summary: main::set_var_field; Argument[0]; ReturnValue.Field[main::MyFieldEnum::D::field_d]; value | -| 23 | Summary: main::set_var_pos; Argument[0]; ReturnValue.Field[main::MyPosEnum::B(0)]; value | +| 8 | Source: main::source_into_function::pass_source; Argument[1].Parameter[0]; test-source | +| 9 | Summary: <_ as core::cmp::Ord>::max; Argument[self]; ReturnValue; value | +| 10 | Summary: <_ as core::cmp::PartialOrd>::lt; Argument[self].Reference; ReturnValue; taint | +| 11 | Summary: main::apply; Argument[0]; Argument[1].Parameter[0]; value | +| 12 | Summary: main::apply; Argument[1].ReturnValue; ReturnValue; value | +| 13 | Summary: main::coerce; Argument[0]; ReturnValue; taint | +| 14 | Summary: main::get_array_element; Argument[0].Element; ReturnValue; value | +| 15 | Summary: main::get_async_number; Argument[0]; ReturnValue.Future; value | +| 16 | Summary: main::get_struct_field; Argument[0].Field[main::MyStruct::field1]; ReturnValue; value | +| 17 | Summary: main::get_tuple_element; Argument[0].Field[0]; ReturnValue; value | +| 18 | Summary: main::get_var_field; Argument[0].Field[main::MyFieldEnum::C::field_c]; ReturnValue; value | +| 19 | Summary: main::get_var_pos; Argument[0].Field[main::MyPosEnum::A(0)]; ReturnValue; value | +| 20 | Summary: main::set_array_element; Argument[0]; ReturnValue.Element; value | +| 21 | Summary: main::set_struct_field; Argument[0]; ReturnValue.Field[main::MyStruct::field2]; value | +| 22 | Summary: main::set_tuple_element; Argument[0]; ReturnValue.Field[1]; value | +| 23 | Summary: main::set_var_field; Argument[0]; ReturnValue.Field[main::MyFieldEnum::D::field_d]; value | +| 24 | Summary: main::set_var_pos; Argument[0]; ReturnValue.Field[main::MyPosEnum::B(0)]; value | edges | main.rs:15:9:15:9 | s | main.rs:16:19:16:19 | s | provenance | | | main.rs:15:9:15:9 | s | main.rs:16:19:16:19 | s | provenance | | @@ -31,7 +32,7 @@ edges | main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | QL | | main.rs:25:9:25:9 | s | main.rs:26:17:26:17 | s | provenance | | | main.rs:25:13:25:22 | source(...) | main.rs:25:9:25:9 | s | provenance | | -| main.rs:26:17:26:17 | s | main.rs:26:10:26:18 | coerce(...) | provenance | MaD:12 | +| main.rs:26:17:26:17 | s | main.rs:26:10:26:18 | coerce(...) | provenance | MaD:13 | | main.rs:40:9:40:9 | s | main.rs:41:27:41:27 | s | provenance | | | main.rs:40:9:40:9 | s | main.rs:41:27:41:27 | s | provenance | | | main.rs:40:13:40:21 | source(...) | main.rs:40:9:40:9 | s | provenance | | @@ -42,8 +43,8 @@ edges | main.rs:41:14:41:28 | ...::A(...) [A] | main.rs:41:9:41:10 | e1 [A] | provenance | | | main.rs:41:27:41:27 | s | main.rs:41:14:41:28 | ...::A(...) [A] | provenance | | | main.rs:41:27:41:27 | s | main.rs:41:14:41:28 | ...::A(...) [A] | provenance | | -| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:18 | -| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:18 | +| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:19 | +| main.rs:42:22:42:23 | e1 [A] | main.rs:42:10:42:24 | get_var_pos(...) | provenance | MaD:19 | | main.rs:53:9:53:9 | s | main.rs:54:26:54:26 | s | provenance | | | main.rs:53:9:53:9 | s | main.rs:54:26:54:26 | s | provenance | | | main.rs:53:13:53:21 | source(...) | main.rs:53:9:53:9 | s | provenance | | @@ -52,8 +53,8 @@ edges | main.rs:54:9:54:10 | e1 [B] | main.rs:55:11:55:12 | e1 [B] | provenance | | | main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:54:9:54:10 | e1 [B] | provenance | | | main.rs:54:14:54:27 | set_var_pos(...) [B] | main.rs:54:9:54:10 | e1 [B] | provenance | | -| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:23 | -| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:23 | +| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:24 | +| main.rs:54:26:54:26 | s | main.rs:54:14:54:27 | set_var_pos(...) [B] | provenance | MaD:24 | | main.rs:55:11:55:12 | e1 [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | | | main.rs:55:11:55:12 | e1 [B] | main.rs:57:9:57:23 | ...::B(...) [B] | provenance | | | main.rs:57:9:57:23 | ...::B(...) [B] | main.rs:57:22:57:22 | i | provenance | | @@ -70,8 +71,8 @@ edges | main.rs:73:14:73:42 | ...::C {...} [C] | main.rs:73:9:73:10 | e1 [C] | provenance | | | main.rs:73:40:73:40 | s | main.rs:73:14:73:42 | ...::C {...} [C] | provenance | | | main.rs:73:40:73:40 | s | main.rs:73:14:73:42 | ...::C {...} [C] | provenance | | -| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:17 | -| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:17 | +| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:18 | +| main.rs:74:24:74:25 | e1 [C] | main.rs:74:10:74:26 | get_var_field(...) | provenance | MaD:18 | | main.rs:85:9:85:9 | s | main.rs:86:28:86:28 | s | provenance | | | main.rs:85:9:85:9 | s | main.rs:86:28:86:28 | s | provenance | | | main.rs:85:13:85:21 | source(...) | main.rs:85:9:85:9 | s | provenance | | @@ -80,8 +81,8 @@ edges | main.rs:86:9:86:10 | e1 [D] | main.rs:87:11:87:12 | e1 [D] | provenance | | | main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:86:9:86:10 | e1 [D] | provenance | | | main.rs:86:14:86:29 | set_var_field(...) [D] | main.rs:86:9:86:10 | e1 [D] | provenance | | -| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:22 | -| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:22 | +| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:23 | +| main.rs:86:28:86:28 | s | main.rs:86:14:86:29 | set_var_field(...) [D] | provenance | MaD:23 | | main.rs:87:11:87:12 | e1 [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | | | main.rs:87:11:87:12 | e1 [D] | main.rs:89:9:89:37 | ...::D {...} [D] | provenance | | | main.rs:89:9:89:37 | ...::D {...} [D] | main.rs:89:35:89:35 | i | provenance | | @@ -98,8 +99,8 @@ edges | main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | main.rs:105:9:105:17 | my_struct [MyStruct.field1] | provenance | | | main.rs:106:17:106:17 | s | main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | provenance | | | main.rs:106:17:106:17 | s | main.rs:105:21:108:5 | MyStruct {...} [MyStruct.field1] | provenance | | -| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:15 | -| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:15 | +| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:16 | +| main.rs:109:27:109:35 | my_struct [MyStruct.field1] | main.rs:109:10:109:36 | get_struct_field(...) | provenance | MaD:16 | | main.rs:126:9:126:9 | s | main.rs:127:38:127:38 | s | provenance | | | main.rs:126:9:126:9 | s | main.rs:127:38:127:38 | s | provenance | | | main.rs:126:13:126:21 | source(...) | main.rs:126:9:126:9 | s | provenance | | @@ -108,16 +109,16 @@ edges | main.rs:127:9:127:17 | my_struct [MyStruct.field2] | main.rs:129:10:129:18 | my_struct [MyStruct.field2] | provenance | | | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | main.rs:127:9:127:17 | my_struct [MyStruct.field2] | provenance | | | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | main.rs:127:9:127:17 | my_struct [MyStruct.field2] | provenance | | -| main.rs:127:38:127:38 | s | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | provenance | MaD:20 | -| main.rs:127:38:127:38 | s | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | provenance | MaD:20 | +| main.rs:127:38:127:38 | s | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | provenance | MaD:21 | +| main.rs:127:38:127:38 | s | main.rs:127:21:127:39 | set_struct_field(...) [MyStruct.field2] | provenance | MaD:21 | | main.rs:129:10:129:18 | my_struct [MyStruct.field2] | main.rs:129:10:129:25 | my_struct.field2 | provenance | | | main.rs:129:10:129:18 | my_struct [MyStruct.field2] | main.rs:129:10:129:25 | my_struct.field2 | provenance | | | main.rs:138:9:138:9 | s | main.rs:139:29:139:29 | s | provenance | | | main.rs:138:9:138:9 | s | main.rs:139:29:139:29 | s | provenance | | | main.rs:138:13:138:21 | source(...) | main.rs:138:9:138:9 | s | provenance | | | main.rs:138:13:138:21 | source(...) | main.rs:138:9:138:9 | s | provenance | | -| main.rs:139:28:139:30 | [...] [element] | main.rs:139:10:139:31 | get_array_element(...) | provenance | MaD:13 | -| main.rs:139:28:139:30 | [...] [element] | main.rs:139:10:139:31 | get_array_element(...) | provenance | MaD:13 | +| main.rs:139:28:139:30 | [...] [element] | main.rs:139:10:139:31 | get_array_element(...) | provenance | MaD:14 | +| main.rs:139:28:139:30 | [...] [element] | main.rs:139:10:139:31 | get_array_element(...) | provenance | MaD:14 | | main.rs:139:29:139:29 | s | main.rs:139:28:139:30 | [...] [element] | provenance | | | main.rs:139:29:139:29 | s | main.rs:139:28:139:30 | [...] [element] | provenance | | | main.rs:148:9:148:9 | s | main.rs:149:33:149:33 | s | provenance | | @@ -128,8 +129,8 @@ edges | main.rs:149:9:149:11 | arr [element] | main.rs:150:10:150:12 | arr [element] | provenance | | | main.rs:149:15:149:34 | set_array_element(...) [element] | main.rs:149:9:149:11 | arr [element] | provenance | | | main.rs:149:15:149:34 | set_array_element(...) [element] | main.rs:149:9:149:11 | arr [element] | provenance | | -| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:19 | -| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:19 | +| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:20 | +| main.rs:149:33:149:33 | s | main.rs:149:15:149:34 | set_array_element(...) [element] | provenance | MaD:20 | | main.rs:150:10:150:12 | arr [element] | main.rs:150:10:150:15 | arr[0] | provenance | | | main.rs:150:10:150:12 | arr [element] | main.rs:150:10:150:15 | arr[0] | provenance | | | main.rs:159:9:159:9 | s | main.rs:160:14:160:14 | s | provenance | | @@ -142,8 +143,8 @@ edges | main.rs:160:13:160:18 | TupleExpr [tuple.0] | main.rs:160:9:160:9 | t [tuple.0] | provenance | | | main.rs:160:14:160:14 | s | main.rs:160:13:160:18 | TupleExpr [tuple.0] | provenance | | | main.rs:160:14:160:14 | s | main.rs:160:13:160:18 | TupleExpr [tuple.0] | provenance | | -| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:16 | -| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:16 | +| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:17 | +| main.rs:161:28:161:28 | t [tuple.0] | main.rs:161:10:161:29 | get_tuple_element(...) | provenance | MaD:17 | | main.rs:172:9:172:9 | s | main.rs:173:31:173:31 | s | provenance | | | main.rs:172:9:172:9 | s | main.rs:173:31:173:31 | s | provenance | | | main.rs:172:13:172:22 | source(...) | main.rs:172:9:172:9 | s | provenance | | @@ -152,8 +153,8 @@ edges | main.rs:173:9:173:9 | t [tuple.1] | main.rs:175:10:175:10 | t [tuple.1] | provenance | | | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | main.rs:173:9:173:9 | t [tuple.1] | provenance | | | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | main.rs:173:9:173:9 | t [tuple.1] | provenance | | -| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:21 | -| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:21 | +| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:22 | +| main.rs:173:31:173:31 | s | main.rs:173:13:173:32 | set_tuple_element(...) [tuple.1] | provenance | MaD:22 | | main.rs:175:10:175:10 | t [tuple.1] | main.rs:175:10:175:12 | t.1 | provenance | | | main.rs:175:10:175:10 | t [tuple.1] | main.rs:175:10:175:12 | t.1 | provenance | | | main.rs:187:9:187:9 | s | main.rs:192:11:192:11 | s | provenance | | @@ -162,8 +163,8 @@ edges | main.rs:187:13:187:22 | source(...) | main.rs:187:9:187:9 | s | provenance | | | main.rs:188:14:188:14 | ... | main.rs:189:14:189:14 | n | provenance | | | main.rs:188:14:188:14 | ... | main.rs:189:14:189:14 | n | provenance | | -| main.rs:192:11:192:11 | s | main.rs:188:14:188:14 | ... | provenance | MaD:10 | -| main.rs:192:11:192:11 | s | main.rs:188:14:188:14 | ... | provenance | MaD:10 | +| main.rs:192:11:192:11 | s | main.rs:188:14:188:14 | ... | provenance | MaD:11 | +| main.rs:192:11:192:11 | s | main.rs:188:14:188:14 | ... | provenance | MaD:11 | | main.rs:196:13:196:22 | source(...) | main.rs:198:23:198:23 | f [captured s] | provenance | | | main.rs:196:13:196:22 | source(...) | main.rs:198:23:198:23 | f [captured s] | provenance | | | main.rs:197:40:197:40 | s | main.rs:197:17:197:42 | if ... {...} else {...} | provenance | | @@ -172,14 +173,14 @@ edges | main.rs:198:9:198:9 | t | main.rs:199:10:199:10 | t | provenance | | | main.rs:198:13:198:24 | apply(...) | main.rs:198:9:198:9 | t | provenance | | | main.rs:198:13:198:24 | apply(...) | main.rs:198:9:198:9 | t | provenance | | -| main.rs:198:23:198:23 | f [captured s] | main.rs:197:40:197:40 | s | provenance | MaD:10 | -| main.rs:198:23:198:23 | f [captured s] | main.rs:197:40:197:40 | s | provenance | MaD:10 | | main.rs:198:23:198:23 | f [captured s] | main.rs:197:40:197:40 | s | provenance | MaD:11 | | main.rs:198:23:198:23 | f [captured s] | main.rs:197:40:197:40 | s | provenance | MaD:11 | -| main.rs:198:23:198:23 | f [captured s] | main.rs:198:13:198:24 | apply(...) | provenance | MaD:10 | -| main.rs:198:23:198:23 | f [captured s] | main.rs:198:13:198:24 | apply(...) | provenance | MaD:10 | +| main.rs:198:23:198:23 | f [captured s] | main.rs:197:40:197:40 | s | provenance | MaD:12 | +| main.rs:198:23:198:23 | f [captured s] | main.rs:197:40:197:40 | s | provenance | MaD:12 | | main.rs:198:23:198:23 | f [captured s] | main.rs:198:13:198:24 | apply(...) | provenance | MaD:11 | | main.rs:198:23:198:23 | f [captured s] | main.rs:198:13:198:24 | apply(...) | provenance | MaD:11 | +| main.rs:198:23:198:23 | f [captured s] | main.rs:198:13:198:24 | apply(...) | provenance | MaD:12 | +| main.rs:198:23:198:23 | f [captured s] | main.rs:198:13:198:24 | apply(...) | provenance | MaD:12 | | main.rs:203:9:203:9 | s | main.rs:205:19:205:19 | s | provenance | | | main.rs:203:9:203:9 | s | main.rs:205:19:205:19 | s | provenance | | | main.rs:203:13:203:22 | source(...) | main.rs:203:9:203:9 | s | provenance | | @@ -190,10 +191,10 @@ edges | main.rs:205:9:205:9 | t | main.rs:206:10:206:10 | t | provenance | | | main.rs:205:13:205:23 | apply(...) | main.rs:205:9:205:9 | t | provenance | | | main.rs:205:13:205:23 | apply(...) | main.rs:205:9:205:9 | t | provenance | | -| main.rs:205:19:205:19 | s | main.rs:204:14:204:14 | ... | provenance | MaD:10 | -| main.rs:205:19:205:19 | s | main.rs:204:14:204:14 | ... | provenance | MaD:10 | -| main.rs:205:19:205:19 | s | main.rs:205:13:205:23 | apply(...) | provenance | MaD:10 | -| main.rs:205:19:205:19 | s | main.rs:205:13:205:23 | apply(...) | provenance | MaD:10 | +| main.rs:205:19:205:19 | s | main.rs:204:14:204:14 | ... | provenance | MaD:11 | +| main.rs:205:19:205:19 | s | main.rs:204:14:204:14 | ... | provenance | MaD:11 | +| main.rs:205:19:205:19 | s | main.rs:205:13:205:23 | apply(...) | provenance | MaD:11 | +| main.rs:205:19:205:19 | s | main.rs:205:13:205:23 | apply(...) | provenance | MaD:11 | | main.rs:215:9:215:9 | s | main.rs:216:30:216:30 | s | provenance | | | main.rs:215:9:215:9 | s | main.rs:216:30:216:30 | s | provenance | | | main.rs:215:13:215:22 | source(...) | main.rs:215:9:215:9 | s | provenance | | @@ -204,8 +205,8 @@ edges | main.rs:216:13:216:31 | get_async_number(...) [future] | main.rs:216:13:216:37 | await ... | provenance | | | main.rs:216:13:216:37 | await ... | main.rs:216:9:216:9 | t | provenance | | | main.rs:216:13:216:37 | await ... | main.rs:216:9:216:9 | t | provenance | | -| main.rs:216:30:216:30 | s | main.rs:216:13:216:31 | get_async_number(...) [future] | provenance | MaD:14 | -| main.rs:216:30:216:30 | s | main.rs:216:13:216:31 | get_async_number(...) [future] | provenance | MaD:14 | +| main.rs:216:30:216:30 | s | main.rs:216:13:216:31 | get_async_number(...) [future] | provenance | MaD:15 | +| main.rs:216:30:216:30 | s | main.rs:216:13:216:31 | get_async_number(...) [future] | provenance | MaD:15 | | main.rs:236:9:236:9 | s [D] | main.rs:237:11:237:11 | s [D] | provenance | | | main.rs:236:9:236:9 | s [D] | main.rs:237:11:237:11 | s [D] | provenance | | | main.rs:236:13:236:23 | enum_source | main.rs:236:13:236:27 | enum_source(...) [D] | provenance | Src:MaD:6 | @@ -230,6 +231,22 @@ edges | main.rs:247:9:247:37 | ...::C {...} [C] | main.rs:247:35:247:35 | i | provenance | | | main.rs:247:35:247:35 | i | main.rs:247:47:247:47 | i | provenance | | | main.rs:247:35:247:35 | i | main.rs:247:47:247:47 | i | provenance | | +| main.rs:261:18:261:18 | ... | main.rs:261:26:261:26 | a | provenance | | +| main.rs:261:18:261:18 | ... | main.rs:261:26:261:26 | a | provenance | | +| main.rs:262:9:262:19 | pass_source | main.rs:261:18:261:18 | ... | provenance | Src:MaD:8 MaD:8 | +| main.rs:262:9:262:19 | pass_source | main.rs:261:18:261:18 | ... | provenance | Src:MaD:8 MaD:8 | +| main.rs:264:9:264:19 | pass_source | main.rs:264:25:264:25 | ... | provenance | Src:MaD:8 MaD:8 | +| main.rs:264:9:264:19 | pass_source | main.rs:264:25:264:25 | ... | provenance | Src:MaD:8 MaD:8 | +| main.rs:264:25:264:25 | ... | main.rs:265:18:265:18 | a | provenance | | +| main.rs:264:25:264:25 | ... | main.rs:265:18:265:18 | a | provenance | | +| main.rs:268:14:268:19 | ...: i64 | main.rs:269:18:269:18 | a | provenance | | +| main.rs:268:14:268:19 | ...: i64 | main.rs:269:18:269:18 | a | provenance | | +| main.rs:271:9:271:19 | pass_source | main.rs:268:14:268:19 | ...: i64 | provenance | Src:MaD:8 MaD:8 | +| main.rs:271:9:271:19 | pass_source | main.rs:268:14:268:19 | ...: i64 | provenance | Src:MaD:8 MaD:8 | +| main.rs:273:9:273:19 | pass_source | main.rs:273:36:273:36 | ... | provenance | Src:MaD:8 MaD:8 | +| main.rs:273:9:273:19 | pass_source | main.rs:273:36:273:36 | ... | provenance | Src:MaD:8 MaD:8 | +| main.rs:273:36:273:36 | ... | main.rs:274:18:274:18 | a | provenance | | +| main.rs:273:36:273:36 | ... | main.rs:274:18:274:18 | a | provenance | | | main.rs:283:9:283:9 | s | main.rs:284:41:284:41 | s | provenance | | | main.rs:283:9:283:9 | s | main.rs:284:41:284:41 | s | provenance | | | main.rs:283:13:283:22 | source(...) | main.rs:283:9:283:9 | s | provenance | | @@ -268,31 +285,31 @@ edges | main.rs:317:16:317:16 | [post] i | main.rs:318:10:318:10 | i | provenance | | | main.rs:370:9:370:10 | x1 | main.rs:371:10:371:11 | x1 | provenance | | | main.rs:370:9:370:10 | x1 | main.rs:371:10:371:11 | x1 | provenance | | -| main.rs:370:14:370:23 | source(...) | main.rs:370:14:370:30 | ... .max(...) | provenance | MaD:8 | -| main.rs:370:14:370:23 | source(...) | main.rs:370:14:370:30 | ... .max(...) | provenance | MaD:8 | +| main.rs:370:14:370:23 | source(...) | main.rs:370:14:370:30 | ... .max(...) | provenance | MaD:9 | +| main.rs:370:14:370:23 | source(...) | main.rs:370:14:370:30 | ... .max(...) | provenance | MaD:9 | | main.rs:370:14:370:30 | ... .max(...) | main.rs:370:9:370:10 | x1 | provenance | | | main.rs:370:14:370:30 | ... .max(...) | main.rs:370:9:370:10 | x1 | provenance | | | main.rs:373:9:373:10 | x2 [MyStruct.field1] | main.rs:381:10:381:11 | x2 [MyStruct.field1] | provenance | | | main.rs:373:9:373:10 | x2 [MyStruct.field1] | main.rs:381:10:381:11 | x2 [MyStruct.field1] | provenance | | | main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | main.rs:373:9:373:10 | x2 [MyStruct.field1] | provenance | | | main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | main.rs:373:9:373:10 | x2 [MyStruct.field1] | provenance | | -| main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | provenance | MaD:8 | -| main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | provenance | MaD:8 | +| main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | provenance | MaD:9 | +| main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | main.rs:373:14:380:6 | ... .max(...) [MyStruct.field1] | provenance | MaD:9 | | main.rs:374:17:374:26 | source(...) | main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | provenance | | | main.rs:374:17:374:26 | source(...) | main.rs:373:15:376:5 | MyStruct {...} [MyStruct.field1] | provenance | | | main.rs:381:10:381:11 | x2 [MyStruct.field1] | main.rs:381:10:381:18 | x2.field1 | provenance | | | main.rs:381:10:381:11 | x2 [MyStruct.field1] | main.rs:381:10:381:18 | x2.field1 | provenance | | | main.rs:386:9:386:10 | x4 | main.rs:387:10:387:11 | x4 | provenance | | | main.rs:386:9:386:10 | x4 | main.rs:387:10:387:11 | x4 | provenance | | -| main.rs:386:14:386:23 | source(...) | main.rs:386:14:386:30 | ... .max(...) | provenance | MaD:8 | -| main.rs:386:14:386:23 | source(...) | main.rs:386:14:386:30 | ... .max(...) | provenance | MaD:8 | +| main.rs:386:14:386:23 | source(...) | main.rs:386:14:386:30 | ... .max(...) | provenance | MaD:9 | +| main.rs:386:14:386:23 | source(...) | main.rs:386:14:386:30 | ... .max(...) | provenance | MaD:9 | | main.rs:386:14:386:30 | ... .max(...) | main.rs:386:9:386:10 | x4 | provenance | | | main.rs:386:14:386:30 | ... .max(...) | main.rs:386:9:386:10 | x4 | provenance | | | main.rs:389:9:389:10 | x5 | main.rs:390:10:390:11 | x5 | provenance | | -| main.rs:389:14:389:23 | source(...) | main.rs:389:14:389:30 | ... .lt(...) | provenance | MaD:9 | +| main.rs:389:14:389:23 | source(...) | main.rs:389:14:389:30 | ... .lt(...) | provenance | MaD:10 | | main.rs:389:14:389:30 | ... .lt(...) | main.rs:389:9:389:10 | x5 | provenance | | | main.rs:392:9:392:10 | x6 | main.rs:393:10:393:11 | x6 | provenance | | -| main.rs:392:14:392:23 | source(...) | main.rs:392:14:392:27 | ... < ... | provenance | MaD:9 | +| main.rs:392:14:392:23 | source(...) | main.rs:392:14:392:27 | ... < ... | provenance | MaD:10 | | main.rs:392:14:392:27 | ... < ... | main.rs:392:9:392:10 | x6 | provenance | | nodes | main.rs:15:9:15:9 | s | semmle.label | s | @@ -533,6 +550,30 @@ nodes | main.rs:247:35:247:35 | i | semmle.label | i | | main.rs:247:47:247:47 | i | semmle.label | i | | main.rs:247:47:247:47 | i | semmle.label | i | +| main.rs:261:18:261:18 | ... | semmle.label | ... | +| main.rs:261:18:261:18 | ... | semmle.label | ... | +| main.rs:261:26:261:26 | a | semmle.label | a | +| main.rs:261:26:261:26 | a | semmle.label | a | +| main.rs:262:9:262:19 | pass_source | semmle.label | pass_source | +| main.rs:262:9:262:19 | pass_source | semmle.label | pass_source | +| main.rs:264:9:264:19 | pass_source | semmle.label | pass_source | +| main.rs:264:9:264:19 | pass_source | semmle.label | pass_source | +| main.rs:264:25:264:25 | ... | semmle.label | ... | +| main.rs:264:25:264:25 | ... | semmle.label | ... | +| main.rs:265:18:265:18 | a | semmle.label | a | +| main.rs:265:18:265:18 | a | semmle.label | a | +| main.rs:268:14:268:19 | ...: i64 | semmle.label | ...: i64 | +| main.rs:268:14:268:19 | ...: i64 | semmle.label | ...: i64 | +| main.rs:269:18:269:18 | a | semmle.label | a | +| main.rs:269:18:269:18 | a | semmle.label | a | +| main.rs:271:9:271:19 | pass_source | semmle.label | pass_source | +| main.rs:271:9:271:19 | pass_source | semmle.label | pass_source | +| main.rs:273:9:273:19 | pass_source | semmle.label | pass_source | +| main.rs:273:9:273:19 | pass_source | semmle.label | pass_source | +| main.rs:273:36:273:36 | ... | semmle.label | ... | +| main.rs:273:36:273:36 | ... | semmle.label | ... | +| main.rs:274:18:274:18 | a | semmle.label | a | +| main.rs:274:18:274:18 | a | semmle.label | a | | main.rs:283:9:283:9 | s | semmle.label | s | | main.rs:283:9:283:9 | s | semmle.label | s | | main.rs:283:13:283:22 | source(...) | semmle.label | source(...) | @@ -658,6 +699,14 @@ invalidSpecComponent | main.rs:239:47:239:47 | i | main.rs:236:13:236:23 | enum_source | main.rs:239:47:239:47 | i | $@ | main.rs:236:13:236:23 | enum_source | enum_source | | main.rs:247:47:247:47 | i | main.rs:245:15:245:20 | source | main.rs:247:47:247:47 | i | $@ | main.rs:245:15:245:20 | source | source | | main.rs:247:47:247:47 | i | main.rs:245:15:245:20 | source | main.rs:247:47:247:47 | i | $@ | main.rs:245:15:245:20 | source | source | +| main.rs:261:26:261:26 | a | main.rs:262:9:262:19 | pass_source | main.rs:261:26:261:26 | a | $@ | main.rs:262:9:262:19 | pass_source | pass_source | +| main.rs:261:26:261:26 | a | main.rs:262:9:262:19 | pass_source | main.rs:261:26:261:26 | a | $@ | main.rs:262:9:262:19 | pass_source | pass_source | +| main.rs:265:18:265:18 | a | main.rs:264:9:264:19 | pass_source | main.rs:265:18:265:18 | a | $@ | main.rs:264:9:264:19 | pass_source | pass_source | +| main.rs:265:18:265:18 | a | main.rs:264:9:264:19 | pass_source | main.rs:265:18:265:18 | a | $@ | main.rs:264:9:264:19 | pass_source | pass_source | +| main.rs:269:18:269:18 | a | main.rs:271:9:271:19 | pass_source | main.rs:269:18:269:18 | a | $@ | main.rs:271:9:271:19 | pass_source | pass_source | +| main.rs:269:18:269:18 | a | main.rs:271:9:271:19 | pass_source | main.rs:269:18:269:18 | a | $@ | main.rs:271:9:271:19 | pass_source | pass_source | +| main.rs:274:18:274:18 | a | main.rs:273:9:273:19 | pass_source | main.rs:274:18:274:18 | a | $@ | main.rs:273:9:273:19 | pass_source | pass_source | +| main.rs:274:18:274:18 | a | main.rs:273:9:273:19 | pass_source | main.rs:274:18:274:18 | a | $@ | main.rs:273:9:273:19 | pass_source | pass_source | | main.rs:284:5:284:13 | enum_sink | main.rs:283:13:283:22 | source(...) | main.rs:284:5:284:13 | enum_sink | $@ | main.rs:283:13:283:22 | source(...) | source(...) | | main.rs:284:5:284:13 | enum_sink | main.rs:283:13:283:22 | source(...) | main.rs:284:5:284:13 | enum_sink | $@ | main.rs:283:13:283:22 | source(...) | source(...) | | main.rs:291:7:291:10 | sink | main.rs:289:13:289:22 | source(...) | main.rs:291:7:291:10 | sink | $@ | main.rs:289:13:289:22 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected index af0e73ca2c0..e0855a5d854 100644 --- a/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected +++ b/rust/ql/test/library-tests/dataflow/sources/InlineFlow.expected @@ -1,142 +1,145 @@ models -| 1 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 2 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 3 | Source: ::connect; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | -| 4 | Source: ::send_request; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | -| 5 | Source: ::file_name; ReturnValue; file | -| 6 | Source: ::path; ReturnValue; file | -| 7 | Source: ::open; ReturnValue.Field[core::result::Result::Ok(0)]; file | -| 8 | Source: ::open; ReturnValue.Field[core::result::Result::Ok(0)]; file | -| 9 | Source: ::connect; ReturnValue.Field[core::result::Result::Ok(0)]; remote | -| 10 | Source: ::connect_timeout; ReturnValue.Field[core::result::Result::Ok(0)]; remote | -| 11 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 12 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 13 | Source: ::file_name; ReturnValue; file | -| 14 | Source: ::path; ReturnValue; file | -| 15 | Source: ::connect; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | -| 16 | Source: reqwest::blocking::get; ReturnValue.Field[core::result::Result::Ok(0)]; remote | -| 17 | Source: reqwest::get; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | -| 18 | Source: std::env::args; ReturnValue.Element; commandargs | -| 19 | Source: std::env::args_os; ReturnValue.Element; commandargs | -| 20 | Source: std::env::current_dir; ReturnValue.Field[core::result::Result::Ok(0)]; commandargs | -| 21 | Source: std::env::current_exe; ReturnValue.Field[core::result::Result::Ok(0)]; commandargs | -| 22 | Source: std::env::home_dir; ReturnValue.Field[core::option::Option::Some(0)]; commandargs | -| 23 | Source: std::env::var; ReturnValue.Field[core::result::Result::Ok(0)]; environment | -| 24 | Source: std::env::var_os; ReturnValue.Field[core::option::Option::Some(0)]; environment | -| 25 | Source: std::fs::read; ReturnValue.Field[core::result::Result::Ok(0)]; file | -| 26 | Source: std::fs::read; ReturnValue; file | -| 27 | Source: std::fs::read_link; ReturnValue.Field[core::result::Result::Ok(0)]; file | -| 28 | Source: std::fs::read_to_string; ReturnValue.Field[core::result::Result::Ok(0)]; file | -| 29 | Source: std::fs::read_to_string; ReturnValue; file | -| 30 | Source: std::io::stdio::stdin; ReturnValue; stdin | -| 31 | Source: tokio::fs::read::read; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 32 | Source: tokio::fs::read_link::read_link; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 33 | Source: tokio::fs::read_to_string::read_to_string; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | -| 34 | Source: tokio::io::stdin::stdin; ReturnValue; stdin | -| 35 | Summary: <_ as async_std::io::read::ReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint | -| 36 | Summary: <_ as async_std::io::read::ReadExt>::read; Argument[self]; Argument[0].Reference; taint | -| 37 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value | -| 38 | Summary: <_ as core::iter::traits::iterator::Iterator>::collect; Argument[self].Element; ReturnValue.Element; value | -| 39 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Element; ReturnValue.Field[core::option::Option::Some(0)]; value | -| 40 | Summary: <_ as futures_io::if_std::AsyncBufRead>::poll_fill_buf; Argument[self].Reference; ReturnValue.Field[core::task::poll::Poll::Ready(0)].Field[core::result::Result::Ok(0)]; taint | -| 41 | Summary: <_ as futures_util::io::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 42 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self].Reference; Argument[0].Reference; taint | -| 43 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | -| 44 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self].Reference; Argument[1].Reference; taint | -| 45 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | -| 46 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint | -| 47 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | -| 48 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self].Reference; Argument[0].Reference; taint | -| 49 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 50 | Summary: <_ as std::io::BufRead>::lines; Argument[self]; ReturnValue; taint | -| 51 | Summary: <_ as std::io::BufRead>::read_line; Argument[self]; Argument[0].Reference; taint | -| 52 | Summary: <_ as std::io::BufRead>::read_until; Argument[self]; Argument[1].Reference; taint | -| 53 | Summary: <_ as std::io::BufRead>::split; Argument[self]; ReturnValue; taint | -| 54 | Summary: <_ as std::io::Read>::bytes; Argument[self]; ReturnValue; taint | -| 55 | Summary: <_ as std::io::Read>::chain; Argument[0]; ReturnValue; taint | -| 56 | Summary: <_ as std::io::Read>::chain; Argument[self]; ReturnValue; taint | -| 57 | Summary: <_ as std::io::Read>::read; Argument[self]; Argument[0].Reference; taint | -| 58 | Summary: <_ as std::io::Read>::read_exact; Argument[self]; Argument[0].Reference; taint | -| 59 | Summary: <_ as std::io::Read>::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 60 | Summary: <_ as std::io::Read>::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 61 | Summary: <_ as std::io::Read>::take; Argument[self]; ReturnValue; taint | -| 62 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 63 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::lines; Argument[self]; ReturnValue; taint | -| 64 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | -| 65 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | -| 66 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::split; Argument[self]; ReturnValue; taint | -| 67 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | -| 68 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_buf; Argument[self]; Argument[0].Reference; taint | -| 69 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_exact; Argument[self]; Argument[0].Reference; taint | -| 70 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_f32; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 71 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i16; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 72 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i64_le; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 73 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 74 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 75 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_u8; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 76 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | -| 77 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 78 | Summary: ::expect; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | -| 79 | Summary: ::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | -| 80 | Summary: ::new; Argument[0].Reference; ReturnValue; value | -| 81 | Summary: ::new; Argument[0]; ReturnValue.Field[core::pin::Pin::__pointer]; value | -| 82 | Summary: ::new; Argument[0]; ReturnValue; value | -| 83 | Summary: ::expect; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 84 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 85 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | -| 86 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 87 | Summary: ::parse; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 88 | Summary: ::connect; Argument[1]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 89 | Summary: ::new; Argument[0]; ReturnValue; taint | -| 90 | Summary: ::bytes; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 91 | Summary: ::chunk; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | -| 92 | Summary: ::text; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | -| 93 | Summary: ::bytes; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 94 | Summary: ::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 95 | Summary: ::text_with_charset; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 96 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | -| 97 | Summary: ::read; Argument[self]; Argument[0]; taint | -| 98 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 99 | Summary: ::read_to_end; Argument[self]; Argument[0]; taint | -| 100 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 101 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | -| 102 | Summary: ::next; Argument[self]; ReturnValue.Field[core::option::Option::Some(0)].Field[core::result::Result::Ok(0)]; taint | -| 103 | Summary: ::fill_buf; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 104 | Summary: ::buffer; Argument[self]; ReturnValue; taint | -| 105 | Summary: ::new; Argument[0]; ReturnValue; taint | -| 106 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | -| 107 | Summary: ::read; Argument[self]; Argument[0]; taint | -| 108 | Summary: ::read_exact; Argument[self]; Argument[0].Reference; taint | -| 109 | Summary: ::read_exact; Argument[self]; Argument[0]; taint | -| 110 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | -| 111 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 112 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | -| 113 | Summary: ::lock; Argument[self]; ReturnValue; taint | -| 114 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | -| 115 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | -| 116 | Summary: ::as_path; Argument[self]; ReturnValue; value | -| 117 | Summary: ::buffer; Argument[self]; ReturnValue; taint | -| 118 | Summary: ::new; Argument[0]; ReturnValue; taint | -| 119 | Summary: ::next_line; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | -| 120 | Summary: ::next_segment; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | -| 121 | Summary: ::peek; Argument[self]; Argument[0].Reference; taint | -| 122 | Summary: ::try_read; Argument[self]; Argument[0].Reference; taint | -| 123 | Summary: ::try_read_buf; Argument[self]; Argument[0].Reference; taint | +| 1 | Source: <_ as warp::filter::Filter>::and_then; Argument[0].Parameter[0..7]; remote | +| 2 | Source: <_ as warp::filter::Filter>::map; Argument[0].Parameter[0..7]; remote | +| 3 | Source: <_ as warp::filter::Filter>::then; Argument[0].Parameter[0..7]; remote | +| 4 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 5 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 6 | Source: ::connect; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | +| 7 | Source: ::send_request; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | +| 8 | Source: ::file_name; ReturnValue; file | +| 9 | Source: ::path; ReturnValue; file | +| 10 | Source: ::open; ReturnValue.Field[core::result::Result::Ok(0)]; file | +| 11 | Source: ::open; ReturnValue.Field[core::result::Result::Ok(0)]; file | +| 12 | Source: ::connect; ReturnValue.Field[core::result::Result::Ok(0)]; remote | +| 13 | Source: ::connect_timeout; ReturnValue.Field[core::result::Result::Ok(0)]; remote | +| 14 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 15 | Source: ::open; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 16 | Source: ::file_name; ReturnValue; file | +| 17 | Source: ::path; ReturnValue; file | +| 18 | Source: ::connect; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | +| 19 | Source: reqwest::blocking::get; ReturnValue.Field[core::result::Result::Ok(0)]; remote | +| 20 | Source: reqwest::get; ReturnValue.Future.Field[core::result::Result::Ok(0)]; remote | +| 21 | Source: std::env::args; ReturnValue.Element; commandargs | +| 22 | Source: std::env::args_os; ReturnValue.Element; commandargs | +| 23 | Source: std::env::current_dir; ReturnValue.Field[core::result::Result::Ok(0)]; commandargs | +| 24 | Source: std::env::current_exe; ReturnValue.Field[core::result::Result::Ok(0)]; commandargs | +| 25 | Source: std::env::home_dir; ReturnValue.Field[core::option::Option::Some(0)]; commandargs | +| 26 | Source: std::env::var; ReturnValue.Field[core::result::Result::Ok(0)]; environment | +| 27 | Source: std::env::var_os; ReturnValue.Field[core::option::Option::Some(0)]; environment | +| 28 | Source: std::fs::read; ReturnValue.Field[core::result::Result::Ok(0)]; file | +| 29 | Source: std::fs::read; ReturnValue; file | +| 30 | Source: std::fs::read_link; ReturnValue.Field[core::result::Result::Ok(0)]; file | +| 31 | Source: std::fs::read_to_string; ReturnValue.Field[core::result::Result::Ok(0)]; file | +| 32 | Source: std::fs::read_to_string; ReturnValue; file | +| 33 | Source: std::io::stdio::stdin; ReturnValue; stdin | +| 34 | Source: tokio::fs::read::read; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 35 | Source: tokio::fs::read_link::read_link; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 36 | Source: tokio::fs::read_to_string::read_to_string; ReturnValue.Future.Field[core::result::Result::Ok(0)]; file | +| 37 | Source: tokio::io::stdin::stdin; ReturnValue; stdin | +| 38 | Summary: <_ as async_std::io::read::ReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint | +| 39 | Summary: <_ as async_std::io::read::ReadExt>::read; Argument[self]; Argument[0].Reference; taint | +| 40 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value | +| 41 | Summary: <_ as core::iter::traits::iterator::Iterator>::collect; Argument[self].Element; ReturnValue.Element; value | +| 42 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Element; ReturnValue.Field[core::option::Option::Some(0)]; value | +| 43 | Summary: <_ as futures_io::if_std::AsyncBufRead>::poll_fill_buf; Argument[self].Reference; ReturnValue.Field[core::task::poll::Poll::Ready(0)].Field[core::result::Result::Ok(0)]; taint | +| 44 | Summary: <_ as futures_util::io::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 45 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self].Reference; Argument[0].Reference; taint | +| 46 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | +| 47 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self].Reference; Argument[1].Reference; taint | +| 48 | Summary: <_ as futures_util::io::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | +| 49 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self].Reference; Argument[0].Reference; taint | +| 50 | Summary: <_ as futures_util::io::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | +| 51 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self].Reference; Argument[0].Reference; taint | +| 52 | Summary: <_ as futures_util::io::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 53 | Summary: <_ as std::io::BufRead>::lines; Argument[self]; ReturnValue; taint | +| 54 | Summary: <_ as std::io::BufRead>::read_line; Argument[self]; Argument[0].Reference; taint | +| 55 | Summary: <_ as std::io::BufRead>::read_until; Argument[self]; Argument[1].Reference; taint | +| 56 | Summary: <_ as std::io::BufRead>::split; Argument[self]; ReturnValue; taint | +| 57 | Summary: <_ as std::io::Read>::bytes; Argument[self]; ReturnValue; taint | +| 58 | Summary: <_ as std::io::Read>::chain; Argument[0]; ReturnValue; taint | +| 59 | Summary: <_ as std::io::Read>::chain; Argument[self]; ReturnValue; taint | +| 60 | Summary: <_ as std::io::Read>::read; Argument[self]; Argument[0].Reference; taint | +| 61 | Summary: <_ as std::io::Read>::read_exact; Argument[self]; Argument[0].Reference; taint | +| 62 | Summary: <_ as std::io::Read>::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 63 | Summary: <_ as std::io::Read>::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 64 | Summary: <_ as std::io::Read>::take; Argument[self]; ReturnValue; taint | +| 65 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::fill_buf; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 66 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::lines; Argument[self]; ReturnValue; taint | +| 67 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_line; Argument[self]; Argument[0].Reference; taint | +| 68 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::read_until; Argument[self]; Argument[1].Reference; taint | +| 69 | Summary: <_ as tokio::io::util::async_buf_read_ext::AsyncBufReadExt>::split; Argument[self]; ReturnValue; taint | +| 70 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read; Argument[self]; Argument[0].Reference; taint | +| 71 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_buf; Argument[self]; Argument[0].Reference; taint | +| 72 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_exact; Argument[self]; Argument[0].Reference; taint | +| 73 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_f32; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 74 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i16; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 75 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_i64_le; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 76 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 77 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 78 | Summary: <_ as tokio::io::util::async_read_ext::AsyncReadExt>::read_u8; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 79 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | +| 80 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 81 | Summary: ::expect; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | +| 82 | Summary: ::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | +| 83 | Summary: ::new; Argument[0].Reference; ReturnValue; value | +| 84 | Summary: ::new; Argument[0]; ReturnValue.Field[core::pin::Pin::__pointer]; value | +| 85 | Summary: ::new; Argument[0]; ReturnValue; value | +| 86 | Summary: ::expect; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | +| 87 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | +| 88 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | +| 89 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 90 | Summary: ::parse; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 91 | Summary: ::connect; Argument[1]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 92 | Summary: ::new; Argument[0]; ReturnValue; taint | +| 93 | Summary: ::bytes; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 94 | Summary: ::chunk; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | +| 95 | Summary: ::text; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)]; taint | +| 96 | Summary: ::bytes; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 97 | Summary: ::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 98 | Summary: ::text_with_charset; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 99 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | +| 100 | Summary: ::read; Argument[self]; Argument[0]; taint | +| 101 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 102 | Summary: ::read_to_end; Argument[self]; Argument[0]; taint | +| 103 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 104 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | +| 105 | Summary: ::next; Argument[self]; ReturnValue.Field[core::option::Option::Some(0)].Field[core::result::Result::Ok(0)]; taint | +| 106 | Summary: ::fill_buf; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 107 | Summary: ::buffer; Argument[self]; ReturnValue; taint | +| 108 | Summary: ::new; Argument[0]; ReturnValue; taint | +| 109 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | +| 110 | Summary: ::read; Argument[self]; Argument[0]; taint | +| 111 | Summary: ::read_exact; Argument[self]; Argument[0].Reference; taint | +| 112 | Summary: ::read_exact; Argument[self]; Argument[0]; taint | +| 113 | Summary: ::read_to_end; Argument[self]; Argument[0].Reference; taint | +| 114 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 115 | Summary: ::read_to_string; Argument[self]; Argument[0]; taint | +| 116 | Summary: ::lock; Argument[self]; ReturnValue; taint | +| 117 | Summary: ::read_to_string; Argument[self]; Argument[0].Reference; taint | +| 118 | Summary: ::read; Argument[self]; Argument[0].Reference; taint | +| 119 | Summary: ::as_path; Argument[self]; ReturnValue; value | +| 120 | Summary: ::buffer; Argument[self]; ReturnValue; taint | +| 121 | Summary: ::new; Argument[0]; ReturnValue; taint | +| 122 | Summary: ::next_line; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | +| 123 | Summary: ::next_segment; Argument[self]; ReturnValue.Future.Field[core::result::Result::Ok(0)].Field[core::option::Option::Some(0)]; taint | +| 124 | Summary: ::peek; Argument[self]; Argument[0].Reference; taint | +| 125 | Summary: ::try_read; Argument[self]; Argument[0].Reference; taint | +| 126 | Summary: ::try_read_buf; Argument[self]; Argument[0].Reference; taint | edges -| test.rs:8:10:8:22 | ...::var | test.rs:8:10:8:30 | ...::var(...) | provenance | Src:MaD:23 | -| test.rs:9:10:9:25 | ...::var_os | test.rs:9:10:9:33 | ...::var_os(...) | provenance | Src:MaD:24 | +| test.rs:8:10:8:22 | ...::var | test.rs:8:10:8:30 | ...::var(...) | provenance | Src:MaD:26 | +| test.rs:9:10:9:25 | ...::var_os | test.rs:9:10:9:33 | ...::var_os(...) | provenance | Src:MaD:27 | | test.rs:11:9:11:12 | var1 | test.rs:14:10:14:13 | var1 | provenance | | -| test.rs:11:16:11:28 | ...::var | test.rs:11:16:11:36 | ...::var(...) [Ok] | provenance | Src:MaD:23 | -| test.rs:11:16:11:36 | ...::var(...) [Ok] | test.rs:11:16:11:59 | ... .expect(...) | provenance | MaD:83 | +| test.rs:11:16:11:28 | ...::var | test.rs:11:16:11:36 | ...::var(...) [Ok] | provenance | Src:MaD:26 | +| test.rs:11:16:11:36 | ...::var(...) [Ok] | test.rs:11:16:11:59 | ... .expect(...) | provenance | MaD:86 | | test.rs:11:16:11:59 | ... .expect(...) | test.rs:11:9:11:12 | var1 | provenance | | | test.rs:12:9:12:12 | var2 | test.rs:15:10:15:13 | var2 | provenance | | -| test.rs:12:16:12:31 | ...::var_os | test.rs:12:16:12:39 | ...::var_os(...) [Some] | provenance | Src:MaD:24 | -| test.rs:12:16:12:39 | ...::var_os(...) [Some] | test.rs:12:16:12:48 | ... .unwrap() | provenance | MaD:79 | +| test.rs:12:16:12:31 | ...::var_os | test.rs:12:16:12:39 | ...::var_os(...) [Some] | provenance | Src:MaD:27 | +| test.rs:12:16:12:39 | ...::var_os(...) [Some] | test.rs:12:16:12:48 | ... .unwrap() | provenance | MaD:82 | | test.rs:12:16:12:48 | ... .unwrap() | test.rs:12:9:12:12 | var2 | provenance | | | test.rs:29:9:29:12 | args [element] | test.rs:30:20:30:23 | args [element] | provenance | | | test.rs:29:9:29:12 | args [element] | test.rs:31:17:31:20 | args [element] | provenance | | -| test.rs:29:29:29:42 | ...::args | test.rs:29:29:29:44 | ...::args(...) [element] | provenance | Src:MaD:18 | -| test.rs:29:29:29:44 | ...::args(...) [element] | test.rs:29:29:29:54 | ... .collect() [element] | provenance | MaD:38 | +| test.rs:29:29:29:42 | ...::args | test.rs:29:29:29:44 | ...::args(...) [element] | provenance | Src:MaD:21 | +| test.rs:29:29:29:44 | ...::args(...) [element] | test.rs:29:29:29:54 | ... .collect() [element] | provenance | MaD:41 | | test.rs:29:29:29:54 | ... .collect() [element] | test.rs:29:9:29:12 | args [element] | provenance | | | test.rs:30:9:30:15 | my_path [&ref] | test.rs:36:10:36:16 | my_path | provenance | | | test.rs:30:19:30:26 | &... [&ref] | test.rs:30:9:30:15 | my_path [&ref] | provenance | | @@ -147,89 +150,89 @@ edges | test.rs:31:17:31:20 | args [element] | test.rs:31:17:31:23 | args[1] | provenance | | | test.rs:31:17:31:23 | args[1] | test.rs:31:16:31:23 | &... [&ref] | provenance | | | test.rs:32:9:32:12 | arg2 | test.rs:38:10:38:13 | arg2 | provenance | | -| test.rs:32:16:32:29 | ...::args | test.rs:32:16:32:31 | ...::args(...) [element] | provenance | Src:MaD:18 | -| test.rs:32:16:32:31 | ...::args(...) [element] | test.rs:32:16:32:38 | ... .nth(...) [Some] | provenance | MaD:39 | -| test.rs:32:16:32:38 | ... .nth(...) [Some] | test.rs:32:16:32:47 | ... .unwrap() | provenance | MaD:79 | +| test.rs:32:16:32:29 | ...::args | test.rs:32:16:32:31 | ...::args(...) [element] | provenance | Src:MaD:21 | +| test.rs:32:16:32:31 | ...::args(...) [element] | test.rs:32:16:32:38 | ... .nth(...) [Some] | provenance | MaD:42 | +| test.rs:32:16:32:38 | ... .nth(...) [Some] | test.rs:32:16:32:47 | ... .unwrap() | provenance | MaD:82 | | test.rs:32:16:32:47 | ... .unwrap() | test.rs:32:9:32:12 | arg2 | provenance | | | test.rs:33:9:33:12 | arg3 | test.rs:39:10:39:13 | arg3 | provenance | | -| test.rs:33:16:33:32 | ...::args_os | test.rs:33:16:33:34 | ...::args_os(...) [element] | provenance | Src:MaD:19 | -| test.rs:33:16:33:34 | ...::args_os(...) [element] | test.rs:33:16:33:41 | ... .nth(...) [Some] | provenance | MaD:39 | -| test.rs:33:16:33:41 | ... .nth(...) [Some] | test.rs:33:16:33:50 | ... .unwrap() | provenance | MaD:79 | +| test.rs:33:16:33:32 | ...::args_os | test.rs:33:16:33:34 | ...::args_os(...) [element] | provenance | Src:MaD:22 | +| test.rs:33:16:33:34 | ...::args_os(...) [element] | test.rs:33:16:33:41 | ... .nth(...) [Some] | provenance | MaD:42 | +| test.rs:33:16:33:41 | ... .nth(...) [Some] | test.rs:33:16:33:50 | ... .unwrap() | provenance | MaD:82 | | test.rs:33:16:33:50 | ... .unwrap() | test.rs:33:9:33:12 | arg3 | provenance | | | test.rs:34:9:34:12 | arg4 | test.rs:40:10:40:13 | arg4 | provenance | | -| test.rs:34:16:34:29 | ...::args | test.rs:34:16:34:31 | ...::args(...) [element] | provenance | Src:MaD:18 | -| test.rs:34:16:34:31 | ...::args(...) [element] | test.rs:34:16:34:38 | ... .nth(...) [Some] | provenance | MaD:39 | -| test.rs:34:16:34:38 | ... .nth(...) [Some] | test.rs:34:16:34:47 | ... .unwrap() | provenance | MaD:79 | -| test.rs:34:16:34:47 | ... .unwrap() | test.rs:34:16:34:64 | ... .parse() [Ok] | provenance | MaD:87 | -| test.rs:34:16:34:64 | ... .parse() [Ok] | test.rs:34:16:34:73 | ... .unwrap() | provenance | MaD:84 | +| test.rs:34:16:34:29 | ...::args | test.rs:34:16:34:31 | ...::args(...) [element] | provenance | Src:MaD:21 | +| test.rs:34:16:34:31 | ...::args(...) [element] | test.rs:34:16:34:38 | ... .nth(...) [Some] | provenance | MaD:42 | +| test.rs:34:16:34:38 | ... .nth(...) [Some] | test.rs:34:16:34:47 | ... .unwrap() | provenance | MaD:82 | +| test.rs:34:16:34:47 | ... .unwrap() | test.rs:34:16:34:64 | ... .parse() [Ok] | provenance | MaD:90 | +| test.rs:34:16:34:64 | ... .parse() [Ok] | test.rs:34:16:34:73 | ... .unwrap() | provenance | MaD:87 | | test.rs:34:16:34:73 | ... .unwrap() | test.rs:34:9:34:12 | arg4 | provenance | | | test.rs:42:9:42:11 | arg | test.rs:43:14:43:16 | arg | provenance | | -| test.rs:42:16:42:29 | ...::args | test.rs:42:16:42:31 | ...::args(...) [element] | provenance | Src:MaD:18 | +| test.rs:42:16:42:29 | ...::args | test.rs:42:16:42:31 | ...::args(...) [element] | provenance | Src:MaD:21 | | test.rs:42:16:42:31 | ...::args(...) [element] | test.rs:42:9:42:11 | arg | provenance | | | test.rs:46:9:46:11 | arg | test.rs:47:14:47:16 | arg | provenance | | -| test.rs:46:16:46:32 | ...::args_os | test.rs:46:16:46:34 | ...::args_os(...) [element] | provenance | Src:MaD:19 | +| test.rs:46:16:46:32 | ...::args_os | test.rs:46:16:46:34 | ...::args_os(...) [element] | provenance | Src:MaD:22 | | test.rs:46:16:46:34 | ...::args_os(...) [element] | test.rs:46:9:46:11 | arg | provenance | | | test.rs:52:9:52:11 | dir | test.rs:56:10:56:12 | dir | provenance | | -| test.rs:52:15:52:35 | ...::current_dir | test.rs:52:15:52:37 | ...::current_dir(...) [Ok] | provenance | Src:MaD:20 | -| test.rs:52:15:52:37 | ...::current_dir(...) [Ok] | test.rs:52:15:52:54 | ... .expect(...) | provenance | MaD:83 | +| test.rs:52:15:52:35 | ...::current_dir | test.rs:52:15:52:37 | ...::current_dir(...) [Ok] | provenance | Src:MaD:23 | +| test.rs:52:15:52:37 | ...::current_dir(...) [Ok] | test.rs:52:15:52:54 | ... .expect(...) | provenance | MaD:86 | | test.rs:52:15:52:54 | ... .expect(...) | test.rs:52:9:52:11 | dir | provenance | | | test.rs:53:9:53:11 | exe | test.rs:57:10:57:12 | exe | provenance | | -| test.rs:53:15:53:35 | ...::current_exe | test.rs:53:15:53:37 | ...::current_exe(...) [Ok] | provenance | Src:MaD:21 | -| test.rs:53:15:53:37 | ...::current_exe(...) [Ok] | test.rs:53:15:53:54 | ... .expect(...) | provenance | MaD:83 | +| test.rs:53:15:53:35 | ...::current_exe | test.rs:53:15:53:37 | ...::current_exe(...) [Ok] | provenance | Src:MaD:24 | +| test.rs:53:15:53:37 | ...::current_exe(...) [Ok] | test.rs:53:15:53:54 | ... .expect(...) | provenance | MaD:86 | | test.rs:53:15:53:54 | ... .expect(...) | test.rs:53:9:53:11 | exe | provenance | | | test.rs:54:9:54:12 | home | test.rs:58:10:58:13 | home | provenance | | -| test.rs:54:16:54:33 | ...::home_dir | test.rs:54:16:54:35 | ...::home_dir(...) [Some] | provenance | Src:MaD:22 | -| test.rs:54:16:54:35 | ...::home_dir(...) [Some] | test.rs:54:16:54:52 | ... .expect(...) | provenance | MaD:78 | +| test.rs:54:16:54:33 | ...::home_dir | test.rs:54:16:54:35 | ...::home_dir(...) [Some] | provenance | Src:MaD:25 | +| test.rs:54:16:54:35 | ...::home_dir(...) [Some] | test.rs:54:16:54:52 | ... .expect(...) | provenance | MaD:81 | | test.rs:54:16:54:52 | ... .expect(...) | test.rs:54:9:54:12 | home | provenance | | | test.rs:62:9:62:22 | remote_string1 | test.rs:63:10:63:23 | remote_string1 | provenance | | -| test.rs:62:26:62:47 | ...::get | test.rs:62:26:62:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | +| test.rs:62:26:62:47 | ...::get | test.rs:62:26:62:62 | ...::get(...) [Ok] | provenance | Src:MaD:19 | | test.rs:62:26:62:62 | ...::get(...) [Ok] | test.rs:62:26:62:63 | TryExpr | provenance | | -| test.rs:62:26:62:63 | TryExpr | test.rs:62:26:62:70 | ... .text() [Ok] | provenance | MaD:94 | +| test.rs:62:26:62:63 | TryExpr | test.rs:62:26:62:70 | ... .text() [Ok] | provenance | MaD:97 | | test.rs:62:26:62:70 | ... .text() [Ok] | test.rs:62:26:62:71 | TryExpr | provenance | | | test.rs:62:26:62:71 | TryExpr | test.rs:62:9:62:22 | remote_string1 | provenance | | | test.rs:65:9:65:22 | remote_string2 | test.rs:66:10:66:23 | remote_string2 | provenance | | -| test.rs:65:26:65:47 | ...::get | test.rs:65:26:65:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | -| test.rs:65:26:65:62 | ...::get(...) [Ok] | test.rs:65:26:65:71 | ... .unwrap() | provenance | MaD:84 | -| test.rs:65:26:65:71 | ... .unwrap() | test.rs:65:26:65:78 | ... .text() [Ok] | provenance | MaD:94 | -| test.rs:65:26:65:78 | ... .text() [Ok] | test.rs:65:26:65:87 | ... .unwrap() | provenance | MaD:84 | +| test.rs:65:26:65:47 | ...::get | test.rs:65:26:65:62 | ...::get(...) [Ok] | provenance | Src:MaD:19 | +| test.rs:65:26:65:62 | ...::get(...) [Ok] | test.rs:65:26:65:71 | ... .unwrap() | provenance | MaD:87 | +| test.rs:65:26:65:71 | ... .unwrap() | test.rs:65:26:65:78 | ... .text() [Ok] | provenance | MaD:97 | +| test.rs:65:26:65:78 | ... .text() [Ok] | test.rs:65:26:65:87 | ... .unwrap() | provenance | MaD:87 | | test.rs:65:26:65:87 | ... .unwrap() | test.rs:65:9:65:22 | remote_string2 | provenance | | | test.rs:68:9:68:22 | remote_string3 | test.rs:69:10:69:23 | remote_string3 | provenance | | -| test.rs:68:26:68:47 | ...::get | test.rs:68:26:68:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | -| test.rs:68:26:68:62 | ...::get(...) [Ok] | test.rs:68:26:68:71 | ... .unwrap() | provenance | MaD:84 | -| test.rs:68:26:68:71 | ... .unwrap() | test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | provenance | MaD:95 | -| test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | test.rs:68:26:68:107 | ... .unwrap() | provenance | MaD:84 | +| test.rs:68:26:68:47 | ...::get | test.rs:68:26:68:62 | ...::get(...) [Ok] | provenance | Src:MaD:19 | +| test.rs:68:26:68:62 | ...::get(...) [Ok] | test.rs:68:26:68:71 | ... .unwrap() | provenance | MaD:87 | +| test.rs:68:26:68:71 | ... .unwrap() | test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | provenance | MaD:98 | +| test.rs:68:26:68:98 | ... .text_with_charset(...) [Ok] | test.rs:68:26:68:107 | ... .unwrap() | provenance | MaD:87 | | test.rs:68:26:68:107 | ... .unwrap() | test.rs:68:9:68:22 | remote_string3 | provenance | | | test.rs:71:9:71:22 | remote_string4 | test.rs:72:10:72:23 | remote_string4 | provenance | | -| test.rs:71:26:71:47 | ...::get | test.rs:71:26:71:62 | ...::get(...) [Ok] | provenance | Src:MaD:16 | -| test.rs:71:26:71:62 | ...::get(...) [Ok] | test.rs:71:26:71:71 | ... .unwrap() | provenance | MaD:84 | -| test.rs:71:26:71:71 | ... .unwrap() | test.rs:71:26:71:79 | ... .bytes() [Ok] | provenance | MaD:93 | -| test.rs:71:26:71:79 | ... .bytes() [Ok] | test.rs:71:26:71:88 | ... .unwrap() | provenance | MaD:84 | +| test.rs:71:26:71:47 | ...::get | test.rs:71:26:71:62 | ...::get(...) [Ok] | provenance | Src:MaD:19 | +| test.rs:71:26:71:62 | ...::get(...) [Ok] | test.rs:71:26:71:71 | ... .unwrap() | provenance | MaD:87 | +| test.rs:71:26:71:71 | ... .unwrap() | test.rs:71:26:71:79 | ... .bytes() [Ok] | provenance | MaD:96 | +| test.rs:71:26:71:79 | ... .bytes() [Ok] | test.rs:71:26:71:88 | ... .unwrap() | provenance | MaD:87 | | test.rs:71:26:71:88 | ... .unwrap() | test.rs:71:9:71:22 | remote_string4 | provenance | | | test.rs:74:9:74:22 | remote_string5 | test.rs:75:10:75:23 | remote_string5 | provenance | | -| test.rs:74:26:74:37 | ...::get | test.rs:74:26:74:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:17 | +| test.rs:74:26:74:37 | ...::get | test.rs:74:26:74:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:20 | | test.rs:74:26:74:52 | ...::get(...) [future, Ok] | test.rs:74:26:74:58 | await ... [Ok] | provenance | | | test.rs:74:26:74:58 | await ... [Ok] | test.rs:74:26:74:59 | TryExpr | provenance | | -| test.rs:74:26:74:59 | TryExpr | test.rs:74:26:74:66 | ... .text() [future, Ok] | provenance | MaD:92 | +| test.rs:74:26:74:59 | TryExpr | test.rs:74:26:74:66 | ... .text() [future, Ok] | provenance | MaD:95 | | test.rs:74:26:74:66 | ... .text() [future, Ok] | test.rs:74:26:74:72 | await ... [Ok] | provenance | | | test.rs:74:26:74:72 | await ... [Ok] | test.rs:74:26:74:73 | TryExpr | provenance | | | test.rs:74:26:74:73 | TryExpr | test.rs:74:9:74:22 | remote_string5 | provenance | | | test.rs:77:9:77:22 | remote_string6 | test.rs:78:10:78:23 | remote_string6 | provenance | | -| test.rs:77:26:77:37 | ...::get | test.rs:77:26:77:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:17 | +| test.rs:77:26:77:37 | ...::get | test.rs:77:26:77:52 | ...::get(...) [future, Ok] | provenance | Src:MaD:20 | | test.rs:77:26:77:52 | ...::get(...) [future, Ok] | test.rs:77:26:77:58 | await ... [Ok] | provenance | | | test.rs:77:26:77:58 | await ... [Ok] | test.rs:77:26:77:59 | TryExpr | provenance | | -| test.rs:77:26:77:59 | TryExpr | test.rs:77:26:77:67 | ... .bytes() [future, Ok] | provenance | MaD:90 | +| test.rs:77:26:77:59 | TryExpr | test.rs:77:26:77:67 | ... .bytes() [future, Ok] | provenance | MaD:93 | | test.rs:77:26:77:67 | ... .bytes() [future, Ok] | test.rs:77:26:77:73 | await ... [Ok] | provenance | | | test.rs:77:26:77:73 | await ... [Ok] | test.rs:77:26:77:74 | TryExpr | provenance | | | test.rs:77:26:77:74 | TryExpr | test.rs:77:9:77:22 | remote_string6 | provenance | | -| test.rs:80:9:80:20 | mut request1 | test.rs:81:10:81:25 | request1.chunk() [future, Ok, Some] | provenance | MaD:91 | -| test.rs:80:9:80:20 | mut request1 | test.rs:82:29:82:44 | request1.chunk() [future, Ok, Some] | provenance | MaD:91 | -| test.rs:80:24:80:35 | ...::get | test.rs:80:24:80:50 | ...::get(...) [future, Ok] | provenance | Src:MaD:17 | +| test.rs:80:9:80:20 | mut request1 | test.rs:81:10:81:25 | request1.chunk() [future, Ok, Some] | provenance | MaD:94 | +| test.rs:80:9:80:20 | mut request1 | test.rs:82:29:82:44 | request1.chunk() [future, Ok, Some] | provenance | MaD:94 | +| test.rs:80:24:80:35 | ...::get | test.rs:80:24:80:50 | ...::get(...) [future, Ok] | provenance | Src:MaD:20 | | test.rs:80:24:80:50 | ...::get(...) [future, Ok] | test.rs:80:24:80:56 | await ... [Ok] | provenance | | | test.rs:80:24:80:56 | await ... [Ok] | test.rs:80:24:80:57 | TryExpr | provenance | | | test.rs:80:24:80:57 | TryExpr | test.rs:80:9:80:20 | mut request1 | provenance | | | test.rs:81:10:81:25 | request1.chunk() [future, Ok, Some] | test.rs:81:10:81:31 | await ... [Ok, Some] | provenance | | | test.rs:81:10:81:31 | await ... [Ok, Some] | test.rs:81:10:81:32 | TryExpr [Some] | provenance | | -| test.rs:81:10:81:32 | TryExpr [Some] | test.rs:81:10:81:41 | ... .unwrap() | provenance | MaD:79 | +| test.rs:81:10:81:32 | TryExpr [Some] | test.rs:81:10:81:41 | ... .unwrap() | provenance | MaD:82 | | test.rs:82:15:82:25 | Some(...) [Some] | test.rs:82:20:82:24 | chunk | provenance | | | test.rs:82:20:82:24 | chunk | test.rs:83:14:83:18 | chunk | provenance | | | test.rs:82:29:82:44 | request1.chunk() [future, Ok, Some] | test.rs:82:29:82:50 | await ... [Ok, Some] | provenance | | @@ -240,129 +243,129 @@ edges | test.rs:114:24:114:51 | sender.send_request(...) [future, Ok] | test.rs:114:24:114:57 | await ... [Ok] | provenance | | | test.rs:114:24:114:57 | await ... [Ok] | test.rs:114:24:114:58 | TryExpr | provenance | | | test.rs:114:24:114:58 | TryExpr | test.rs:114:13:114:20 | response | provenance | | -| test.rs:114:31:114:42 | send_request | test.rs:114:24:114:51 | sender.send_request(...) [future, Ok] | provenance | Src:MaD:4 | +| test.rs:114:31:114:42 | send_request | test.rs:114:24:114:51 | sender.send_request(...) [future, Ok] | provenance | Src:MaD:7 | | test.rs:115:15:115:22 | response | test.rs:115:14:115:22 | &response | provenance | | | test.rs:121:9:121:20 | mut response | test.rs:122:11:122:18 | response | provenance | | | test.rs:121:24:121:51 | sender.send_request(...) [future, Ok] | test.rs:121:24:121:57 | await ... [Ok] | provenance | | | test.rs:121:24:121:57 | await ... [Ok] | test.rs:121:24:121:58 | TryExpr | provenance | | | test.rs:121:24:121:58 | TryExpr | test.rs:121:9:121:20 | mut response | provenance | | -| test.rs:121:31:121:42 | send_request | test.rs:121:24:121:51 | sender.send_request(...) [future, Ok] | provenance | Src:MaD:4 | +| test.rs:121:31:121:42 | send_request | test.rs:121:24:121:51 | sender.send_request(...) [future, Ok] | provenance | Src:MaD:7 | | test.rs:122:11:122:18 | response | test.rs:122:10:122:18 | &response | provenance | | -| test.rs:211:22:211:35 | ...::stdin | test.rs:211:22:211:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer | provenance | MaD:107 | -| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:57 | -| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:106 | +| test.rs:211:22:211:35 | ...::stdin | test.rs:211:22:211:37 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer | provenance | MaD:110 | +| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:211:22:211:37 | ...::stdin(...) | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | provenance | MaD:109 | | test.rs:211:44:211:54 | [post] &mut buffer | test.rs:212:15:212:20 | buffer | provenance | | | test.rs:211:44:211:54 | [post] &mut buffer [&ref] | test.rs:211:49:211:54 | [post] buffer | provenance | | | test.rs:211:49:211:54 | [post] buffer | test.rs:212:15:212:20 | buffer | provenance | | | test.rs:212:15:212:20 | buffer | test.rs:212:14:212:20 | &buffer | provenance | | -| test.rs:217:22:217:35 | ...::stdin | test.rs:217:22:217:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:59 | -| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:110 | +| test.rs:217:22:217:35 | ...::stdin | test.rs:217:22:217:37 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:62 | +| test.rs:217:22:217:37 | ...::stdin(...) | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | provenance | MaD:113 | | test.rs:217:51:217:61 | [post] &mut buffer [&ref] | test.rs:217:56:217:61 | [post] buffer | provenance | | | test.rs:217:56:217:61 | [post] buffer | test.rs:218:15:218:20 | buffer | provenance | | | test.rs:218:15:218:20 | buffer | test.rs:218:14:218:20 | &buffer | provenance | | -| test.rs:223:22:223:35 | ...::stdin | test.rs:223:22:223:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer | provenance | MaD:112 | -| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:60 | -| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:111 | +| test.rs:223:22:223:35 | ...::stdin | test.rs:223:22:223:37 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer | provenance | MaD:115 | +| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:63 | +| test.rs:223:22:223:37 | ...::stdin(...) | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | provenance | MaD:114 | | test.rs:223:54:223:64 | [post] &mut buffer | test.rs:224:15:224:20 | buffer | provenance | | | test.rs:223:54:223:64 | [post] &mut buffer [&ref] | test.rs:223:59:223:64 | [post] buffer | provenance | | | test.rs:223:59:223:64 | [post] buffer | test.rs:224:15:224:20 | buffer | provenance | | | test.rs:224:15:224:20 | buffer | test.rs:224:14:224:20 | &buffer | provenance | | -| test.rs:229:22:229:35 | ...::stdin | test.rs:229:22:229:37 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:229:22:229:37 | ...::stdin(...) | test.rs:229:22:229:44 | ... .lock() | provenance | MaD:113 | -| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:60 | -| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:114 | +| test.rs:229:22:229:35 | ...::stdin | test.rs:229:22:229:37 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:229:22:229:37 | ...::stdin(...) | test.rs:229:22:229:44 | ... .lock() | provenance | MaD:116 | +| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:63 | +| test.rs:229:22:229:44 | ... .lock() | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | provenance | MaD:117 | | test.rs:229:61:229:71 | [post] &mut buffer [&ref] | test.rs:229:66:229:71 | [post] buffer | provenance | | | test.rs:229:66:229:71 | [post] buffer | test.rs:230:15:230:20 | buffer | provenance | | | test.rs:230:15:230:20 | buffer | test.rs:230:14:230:20 | &buffer | provenance | | -| test.rs:235:9:235:22 | ...::stdin | test.rs:235:9:235:24 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer | provenance | MaD:109 | -| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:58 | -| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:108 | +| test.rs:235:9:235:22 | ...::stdin | test.rs:235:9:235:24 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer | provenance | MaD:112 | +| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:61 | +| test.rs:235:9:235:24 | ...::stdin(...) | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | provenance | MaD:111 | | test.rs:235:37:235:47 | [post] &mut buffer | test.rs:236:15:236:20 | buffer | provenance | | | test.rs:235:37:235:47 | [post] &mut buffer [&ref] | test.rs:235:42:235:47 | [post] buffer | provenance | | | test.rs:235:42:235:47 | [post] buffer | test.rs:236:15:236:20 | buffer | provenance | | | test.rs:236:15:236:20 | buffer | test.rs:236:14:236:20 | &buffer | provenance | | -| test.rs:239:17:239:30 | ...::stdin | test.rs:239:17:239:32 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:239:17:239:32 | ...::stdin(...) | test.rs:239:17:239:40 | ... .bytes() | provenance | MaD:54 | +| test.rs:239:17:239:30 | ...::stdin | test.rs:239:17:239:32 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:239:17:239:32 | ...::stdin(...) | test.rs:239:17:239:40 | ... .bytes() | provenance | MaD:57 | | test.rs:239:17:239:40 | ... .bytes() | test.rs:240:14:240:17 | byte | provenance | | -| test.rs:246:13:246:22 | mut reader | test.rs:247:20:247:36 | reader.fill_buf() [Ok] | provenance | MaD:103 | +| test.rs:246:13:246:22 | mut reader | test.rs:247:20:247:36 | reader.fill_buf() [Ok] | provenance | MaD:106 | | test.rs:246:26:246:66 | ...::new(...) | test.rs:246:13:246:22 | mut reader | provenance | | -| test.rs:246:50:246:63 | ...::stdin | test.rs:246:50:246:65 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:246:50:246:65 | ...::stdin(...) | test.rs:246:26:246:66 | ...::new(...) | provenance | MaD:105 | +| test.rs:246:50:246:63 | ...::stdin | test.rs:246:50:246:65 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:246:50:246:65 | ...::stdin(...) | test.rs:246:26:246:66 | ...::new(...) | provenance | MaD:108 | | test.rs:247:13:247:16 | data | test.rs:248:15:248:18 | data | provenance | | | test.rs:247:20:247:36 | reader.fill_buf() [Ok] | test.rs:247:20:247:37 | TryExpr | provenance | | | test.rs:247:20:247:37 | TryExpr | test.rs:247:13:247:16 | data | provenance | | | test.rs:248:15:248:18 | data | test.rs:248:14:248:18 | &data | provenance | | -| test.rs:252:13:252:18 | reader | test.rs:253:20:253:34 | reader.buffer() | provenance | MaD:104 | +| test.rs:252:13:252:18 | reader | test.rs:253:20:253:34 | reader.buffer() | provenance | MaD:107 | | test.rs:252:22:252:62 | ...::new(...) | test.rs:252:13:252:18 | reader | provenance | | -| test.rs:252:46:252:59 | ...::stdin | test.rs:252:46:252:61 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:252:46:252:61 | ...::stdin(...) | test.rs:252:22:252:62 | ...::new(...) | provenance | MaD:105 | +| test.rs:252:46:252:59 | ...::stdin | test.rs:252:46:252:61 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:252:46:252:61 | ...::stdin(...) | test.rs:252:22:252:62 | ...::new(...) | provenance | MaD:108 | | test.rs:253:13:253:16 | data | test.rs:254:15:254:18 | data | provenance | | | test.rs:253:20:253:34 | reader.buffer() | test.rs:253:13:253:16 | data | provenance | | | test.rs:254:15:254:18 | data | test.rs:254:14:254:18 | &data | provenance | | -| test.rs:259:13:259:22 | mut reader | test.rs:260:26:260:36 | [post] &mut buffer [&ref] | provenance | MaD:51 | +| test.rs:259:13:259:22 | mut reader | test.rs:260:26:260:36 | [post] &mut buffer [&ref] | provenance | MaD:54 | | test.rs:259:26:259:66 | ...::new(...) | test.rs:259:13:259:22 | mut reader | provenance | | -| test.rs:259:50:259:63 | ...::stdin | test.rs:259:50:259:65 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:259:50:259:65 | ...::stdin(...) | test.rs:259:26:259:66 | ...::new(...) | provenance | MaD:105 | +| test.rs:259:50:259:63 | ...::stdin | test.rs:259:50:259:65 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:259:50:259:65 | ...::stdin(...) | test.rs:259:26:259:66 | ...::new(...) | provenance | MaD:108 | | test.rs:260:26:260:36 | [post] &mut buffer [&ref] | test.rs:260:31:260:36 | [post] buffer | provenance | | | test.rs:260:31:260:36 | [post] buffer | test.rs:261:15:261:20 | buffer | provenance | | | test.rs:261:15:261:20 | buffer | test.rs:261:14:261:20 | &buffer | provenance | | -| test.rs:266:13:266:22 | mut reader | test.rs:267:33:267:43 | [post] &mut buffer [&ref] | provenance | MaD:52 | +| test.rs:266:13:266:22 | mut reader | test.rs:267:33:267:43 | [post] &mut buffer [&ref] | provenance | MaD:55 | | test.rs:266:26:266:66 | ...::new(...) | test.rs:266:13:266:22 | mut reader | provenance | | -| test.rs:266:50:266:63 | ...::stdin | test.rs:266:50:266:65 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:266:50:266:65 | ...::stdin(...) | test.rs:266:26:266:66 | ...::new(...) | provenance | MaD:105 | +| test.rs:266:50:266:63 | ...::stdin | test.rs:266:50:266:65 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:266:50:266:65 | ...::stdin(...) | test.rs:266:26:266:66 | ...::new(...) | provenance | MaD:108 | | test.rs:267:33:267:43 | [post] &mut buffer [&ref] | test.rs:267:38:267:43 | [post] buffer | provenance | | | test.rs:267:38:267:43 | [post] buffer | test.rs:268:15:268:20 | buffer | provenance | | | test.rs:267:38:267:43 | [post] buffer | test.rs:269:14:269:22 | buffer[0] | provenance | | | test.rs:268:15:268:20 | buffer | test.rs:268:14:268:20 | &buffer | provenance | | -| test.rs:273:13:273:28 | mut reader_split | test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | provenance | MaD:102 | -| test.rs:273:13:273:28 | mut reader_split | test.rs:275:33:275:51 | reader_split.next() [Some, Ok] | provenance | MaD:102 | -| test.rs:273:32:273:72 | ...::new(...) | test.rs:273:32:273:84 | ... .split(...) | provenance | MaD:53 | +| test.rs:273:13:273:28 | mut reader_split | test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | provenance | MaD:105 | +| test.rs:273:13:273:28 | mut reader_split | test.rs:275:33:275:51 | reader_split.next() [Some, Ok] | provenance | MaD:105 | +| test.rs:273:32:273:72 | ...::new(...) | test.rs:273:32:273:84 | ... .split(...) | provenance | MaD:56 | | test.rs:273:32:273:84 | ... .split(...) | test.rs:273:13:273:28 | mut reader_split | provenance | | -| test.rs:273:56:273:69 | ...::stdin | test.rs:273:56:273:71 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:273:56:273:71 | ...::stdin(...) | test.rs:273:32:273:72 | ...::new(...) | provenance | MaD:105 | -| test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | test.rs:274:14:274:41 | ... .unwrap() [Ok] | provenance | MaD:79 | -| test.rs:274:14:274:41 | ... .unwrap() [Ok] | test.rs:274:14:274:50 | ... .unwrap() | provenance | MaD:84 | +| test.rs:273:56:273:69 | ...::stdin | test.rs:273:56:273:71 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:273:56:273:71 | ...::stdin(...) | test.rs:273:32:273:72 | ...::new(...) | provenance | MaD:108 | +| test.rs:274:14:274:32 | reader_split.next() [Some, Ok] | test.rs:274:14:274:41 | ... .unwrap() [Ok] | provenance | MaD:82 | +| test.rs:274:14:274:41 | ... .unwrap() [Ok] | test.rs:274:14:274:50 | ... .unwrap() | provenance | MaD:87 | | test.rs:275:19:275:29 | Some(...) [Some, Ok] | test.rs:275:24:275:28 | chunk [Ok] | provenance | | -| test.rs:275:24:275:28 | chunk [Ok] | test.rs:276:18:276:31 | chunk.unwrap() | provenance | MaD:84 | +| test.rs:275:24:275:28 | chunk [Ok] | test.rs:276:18:276:31 | chunk.unwrap() | provenance | MaD:87 | | test.rs:275:33:275:51 | reader_split.next() [Some, Ok] | test.rs:275:19:275:29 | Some(...) [Some, Ok] | provenance | | -| test.rs:281:13:281:18 | reader | test.rs:282:21:282:34 | reader.lines() | provenance | MaD:50 | +| test.rs:281:13:281:18 | reader | test.rs:282:21:282:34 | reader.lines() | provenance | MaD:53 | | test.rs:281:22:281:62 | ...::new(...) | test.rs:281:13:281:18 | reader | provenance | | -| test.rs:281:46:281:59 | ...::stdin | test.rs:281:46:281:61 | ...::stdin(...) | provenance | Src:MaD:30 MaD:30 | -| test.rs:281:46:281:61 | ...::stdin(...) | test.rs:281:22:281:62 | ...::new(...) | provenance | MaD:105 | +| test.rs:281:46:281:59 | ...::stdin | test.rs:281:46:281:61 | ...::stdin(...) | provenance | Src:MaD:33 MaD:33 | +| test.rs:281:46:281:61 | ...::stdin(...) | test.rs:281:22:281:62 | ...::new(...) | provenance | MaD:108 | | test.rs:282:21:282:34 | reader.lines() | test.rs:283:18:283:21 | line | provenance | | -| test.rs:309:13:309:21 | mut stdin | test.rs:311:33:311:43 | [post] &mut buffer [&ref] | provenance | MaD:67 | -| test.rs:309:25:309:40 | ...::stdin | test.rs:309:25:309:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:309:13:309:21 | mut stdin | test.rs:311:33:311:43 | [post] &mut buffer [&ref] | provenance | MaD:70 | +| test.rs:309:25:309:40 | ...::stdin | test.rs:309:25:309:42 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | | test.rs:309:25:309:42 | ...::stdin(...) | test.rs:309:13:309:21 | mut stdin | provenance | | | test.rs:311:33:311:43 | [post] &mut buffer [&ref] | test.rs:311:38:311:43 | [post] buffer | provenance | | | test.rs:311:38:311:43 | [post] buffer | test.rs:312:15:312:20 | buffer | provenance | | | test.rs:312:15:312:20 | buffer | test.rs:312:14:312:20 | &buffer | provenance | | -| test.rs:316:13:316:21 | mut stdin | test.rs:318:40:318:50 | [post] &mut buffer [&ref] | provenance | MaD:73 | -| test.rs:316:25:316:40 | ...::stdin | test.rs:316:25:316:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:316:13:316:21 | mut stdin | test.rs:318:40:318:50 | [post] &mut buffer [&ref] | provenance | MaD:76 | +| test.rs:316:25:316:40 | ...::stdin | test.rs:316:25:316:42 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | | test.rs:316:25:316:42 | ...::stdin(...) | test.rs:316:13:316:21 | mut stdin | provenance | | | test.rs:318:40:318:50 | [post] &mut buffer [&ref] | test.rs:318:45:318:50 | [post] buffer | provenance | | | test.rs:318:45:318:50 | [post] buffer | test.rs:319:15:319:20 | buffer | provenance | | | test.rs:319:15:319:20 | buffer | test.rs:319:14:319:20 | &buffer | provenance | | -| test.rs:323:13:323:21 | mut stdin | test.rs:325:43:325:53 | [post] &mut buffer [&ref] | provenance | MaD:74 | -| test.rs:323:25:323:40 | ...::stdin | test.rs:323:25:323:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:323:13:323:21 | mut stdin | test.rs:325:43:325:53 | [post] &mut buffer [&ref] | provenance | MaD:77 | +| test.rs:323:25:323:40 | ...::stdin | test.rs:323:25:323:42 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | | test.rs:323:25:323:42 | ...::stdin(...) | test.rs:323:13:323:21 | mut stdin | provenance | | | test.rs:325:43:325:53 | [post] &mut buffer [&ref] | test.rs:325:48:325:53 | [post] buffer | provenance | | | test.rs:325:48:325:53 | [post] buffer | test.rs:326:15:326:20 | buffer | provenance | | | test.rs:326:15:326:20 | buffer | test.rs:326:14:326:20 | &buffer | provenance | | -| test.rs:330:13:330:21 | mut stdin | test.rs:332:26:332:36 | [post] &mut buffer [&ref] | provenance | MaD:69 | -| test.rs:330:25:330:40 | ...::stdin | test.rs:330:25:330:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:330:13:330:21 | mut stdin | test.rs:332:26:332:36 | [post] &mut buffer [&ref] | provenance | MaD:72 | +| test.rs:330:25:330:40 | ...::stdin | test.rs:330:25:330:42 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | | test.rs:330:25:330:42 | ...::stdin(...) | test.rs:330:13:330:21 | mut stdin | provenance | | | test.rs:332:26:332:36 | [post] &mut buffer [&ref] | test.rs:332:31:332:36 | [post] buffer | provenance | | | test.rs:332:31:332:36 | [post] buffer | test.rs:333:15:333:20 | buffer | provenance | | | test.rs:333:15:333:20 | buffer | test.rs:333:14:333:20 | &buffer | provenance | | -| test.rs:337:13:337:21 | mut stdin | test.rs:338:18:338:32 | stdin.read_u8() [future, Ok] | provenance | MaD:75 | -| test.rs:337:13:337:21 | mut stdin | test.rs:339:18:339:33 | stdin.read_i16() [future, Ok] | provenance | MaD:71 | -| test.rs:337:13:337:21 | mut stdin | test.rs:340:18:340:33 | stdin.read_f32() [future, Ok] | provenance | MaD:70 | -| test.rs:337:13:337:21 | mut stdin | test.rs:341:18:341:36 | stdin.read_i64_le() [future, Ok] | provenance | MaD:72 | -| test.rs:337:25:337:40 | ...::stdin | test.rs:337:25:337:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:337:13:337:21 | mut stdin | test.rs:338:18:338:32 | stdin.read_u8() [future, Ok] | provenance | MaD:78 | +| test.rs:337:13:337:21 | mut stdin | test.rs:339:18:339:33 | stdin.read_i16() [future, Ok] | provenance | MaD:74 | +| test.rs:337:13:337:21 | mut stdin | test.rs:340:18:340:33 | stdin.read_f32() [future, Ok] | provenance | MaD:73 | +| test.rs:337:13:337:21 | mut stdin | test.rs:341:18:341:36 | stdin.read_i64_le() [future, Ok] | provenance | MaD:75 | +| test.rs:337:25:337:40 | ...::stdin | test.rs:337:25:337:42 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | | test.rs:337:25:337:42 | ...::stdin(...) | test.rs:337:13:337:21 | mut stdin | provenance | | | test.rs:338:13:338:14 | v1 | test.rs:342:14:342:15 | v1 | provenance | | | test.rs:338:18:338:32 | stdin.read_u8() [future, Ok] | test.rs:338:18:338:38 | await ... [Ok] | provenance | | @@ -380,150 +383,150 @@ edges | test.rs:341:18:341:36 | stdin.read_i64_le() [future, Ok] | test.rs:341:18:341:42 | await ... [Ok] | provenance | | | test.rs:341:18:341:42 | await ... [Ok] | test.rs:341:18:341:43 | TryExpr | provenance | | | test.rs:341:18:341:43 | TryExpr | test.rs:341:13:341:14 | v4 | provenance | | -| test.rs:349:13:349:21 | mut stdin | test.rs:351:24:351:34 | [post] &mut buffer [&ref] | provenance | MaD:68 | -| test.rs:349:25:349:40 | ...::stdin | test.rs:349:25:349:42 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | +| test.rs:349:13:349:21 | mut stdin | test.rs:351:24:351:34 | [post] &mut buffer [&ref] | provenance | MaD:71 | +| test.rs:349:25:349:40 | ...::stdin | test.rs:349:25:349:42 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | | test.rs:349:25:349:42 | ...::stdin(...) | test.rs:349:13:349:21 | mut stdin | provenance | | | test.rs:351:24:351:34 | [post] &mut buffer [&ref] | test.rs:351:29:351:34 | [post] buffer | provenance | | | test.rs:351:29:351:34 | [post] buffer | test.rs:352:15:352:20 | buffer | provenance | | | test.rs:352:15:352:20 | buffer | test.rs:352:14:352:20 | &buffer | provenance | | -| test.rs:358:13:358:22 | mut reader | test.rs:359:20:359:36 | reader.fill_buf() [future, Ok] | provenance | MaD:62 | +| test.rs:358:13:358:22 | mut reader | test.rs:359:20:359:36 | reader.fill_buf() [future, Ok] | provenance | MaD:65 | | test.rs:358:26:358:70 | ...::new(...) | test.rs:358:13:358:22 | mut reader | provenance | | -| test.rs:358:52:358:67 | ...::stdin | test.rs:358:52:358:69 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:358:52:358:69 | ...::stdin(...) | test.rs:358:26:358:70 | ...::new(...) | provenance | MaD:118 | +| test.rs:358:52:358:67 | ...::stdin | test.rs:358:52:358:69 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | +| test.rs:358:52:358:69 | ...::stdin(...) | test.rs:358:26:358:70 | ...::new(...) | provenance | MaD:121 | | test.rs:359:13:359:16 | data | test.rs:360:15:360:18 | data | provenance | | | test.rs:359:20:359:36 | reader.fill_buf() [future, Ok] | test.rs:359:20:359:42 | await ... [Ok] | provenance | | | test.rs:359:20:359:42 | await ... [Ok] | test.rs:359:20:359:43 | TryExpr | provenance | | | test.rs:359:20:359:43 | TryExpr | test.rs:359:13:359:16 | data | provenance | | | test.rs:360:15:360:18 | data | test.rs:360:14:360:18 | &data | provenance | | -| test.rs:364:13:364:18 | reader | test.rs:365:20:365:34 | reader.buffer() | provenance | MaD:117 | +| test.rs:364:13:364:18 | reader | test.rs:365:20:365:34 | reader.buffer() | provenance | MaD:120 | | test.rs:364:22:364:66 | ...::new(...) | test.rs:364:13:364:18 | reader | provenance | | -| test.rs:364:48:364:63 | ...::stdin | test.rs:364:48:364:65 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:364:48:364:65 | ...::stdin(...) | test.rs:364:22:364:66 | ...::new(...) | provenance | MaD:118 | +| test.rs:364:48:364:63 | ...::stdin | test.rs:364:48:364:65 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | +| test.rs:364:48:364:65 | ...::stdin(...) | test.rs:364:22:364:66 | ...::new(...) | provenance | MaD:121 | | test.rs:365:13:365:16 | data | test.rs:366:15:366:18 | data | provenance | | | test.rs:365:20:365:34 | reader.buffer() | test.rs:365:13:365:16 | data | provenance | | | test.rs:366:15:366:18 | data | test.rs:366:14:366:18 | &data | provenance | | -| test.rs:371:13:371:22 | mut reader | test.rs:372:26:372:36 | [post] &mut buffer [&ref] | provenance | MaD:64 | +| test.rs:371:13:371:22 | mut reader | test.rs:372:26:372:36 | [post] &mut buffer [&ref] | provenance | MaD:67 | | test.rs:371:26:371:70 | ...::new(...) | test.rs:371:13:371:22 | mut reader | provenance | | -| test.rs:371:52:371:67 | ...::stdin | test.rs:371:52:371:69 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:371:52:371:69 | ...::stdin(...) | test.rs:371:26:371:70 | ...::new(...) | provenance | MaD:118 | +| test.rs:371:52:371:67 | ...::stdin | test.rs:371:52:371:69 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | +| test.rs:371:52:371:69 | ...::stdin(...) | test.rs:371:26:371:70 | ...::new(...) | provenance | MaD:121 | | test.rs:372:26:372:36 | [post] &mut buffer [&ref] | test.rs:372:31:372:36 | [post] buffer | provenance | | | test.rs:372:31:372:36 | [post] buffer | test.rs:373:15:373:20 | buffer | provenance | | | test.rs:373:15:373:20 | buffer | test.rs:373:14:373:20 | &buffer | provenance | | -| test.rs:378:13:378:22 | mut reader | test.rs:379:33:379:43 | [post] &mut buffer [&ref] | provenance | MaD:65 | +| test.rs:378:13:378:22 | mut reader | test.rs:379:33:379:43 | [post] &mut buffer [&ref] | provenance | MaD:68 | | test.rs:378:26:378:70 | ...::new(...) | test.rs:378:13:378:22 | mut reader | provenance | | -| test.rs:378:52:378:67 | ...::stdin | test.rs:378:52:378:69 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:378:52:378:69 | ...::stdin(...) | test.rs:378:26:378:70 | ...::new(...) | provenance | MaD:118 | +| test.rs:378:52:378:67 | ...::stdin | test.rs:378:52:378:69 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | +| test.rs:378:52:378:69 | ...::stdin(...) | test.rs:378:26:378:70 | ...::new(...) | provenance | MaD:121 | | test.rs:379:33:379:43 | [post] &mut buffer [&ref] | test.rs:379:38:379:43 | [post] buffer | provenance | | | test.rs:379:38:379:43 | [post] buffer | test.rs:380:15:380:20 | buffer | provenance | | | test.rs:379:38:379:43 | [post] buffer | test.rs:381:14:381:22 | buffer[0] | provenance | | | test.rs:380:15:380:20 | buffer | test.rs:380:14:380:20 | &buffer | provenance | | -| test.rs:385:13:385:28 | mut reader_split | test.rs:386:14:386:40 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:120 | -| test.rs:385:13:385:28 | mut reader_split | test.rs:387:33:387:59 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:120 | -| test.rs:385:32:385:76 | ...::new(...) | test.rs:385:32:385:88 | ... .split(...) | provenance | MaD:66 | +| test.rs:385:13:385:28 | mut reader_split | test.rs:386:14:386:40 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:123 | +| test.rs:385:13:385:28 | mut reader_split | test.rs:387:33:387:59 | reader_split.next_segment() [future, Ok, Some] | provenance | MaD:123 | +| test.rs:385:32:385:76 | ...::new(...) | test.rs:385:32:385:88 | ... .split(...) | provenance | MaD:69 | | test.rs:385:32:385:88 | ... .split(...) | test.rs:385:13:385:28 | mut reader_split | provenance | | -| test.rs:385:58:385:73 | ...::stdin | test.rs:385:58:385:75 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:385:58:385:75 | ...::stdin(...) | test.rs:385:32:385:76 | ...::new(...) | provenance | MaD:118 | +| test.rs:385:58:385:73 | ...::stdin | test.rs:385:58:385:75 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | +| test.rs:385:58:385:75 | ...::stdin(...) | test.rs:385:32:385:76 | ...::new(...) | provenance | MaD:121 | | test.rs:386:14:386:40 | reader_split.next_segment() [future, Ok, Some] | test.rs:386:14:386:46 | await ... [Ok, Some] | provenance | | | test.rs:386:14:386:46 | await ... [Ok, Some] | test.rs:386:14:386:47 | TryExpr [Some] | provenance | | -| test.rs:386:14:386:47 | TryExpr [Some] | test.rs:386:14:386:56 | ... .unwrap() | provenance | MaD:79 | +| test.rs:386:14:386:47 | TryExpr [Some] | test.rs:386:14:386:56 | ... .unwrap() | provenance | MaD:82 | | test.rs:387:19:387:29 | Some(...) [Some] | test.rs:387:24:387:28 | chunk | provenance | | | test.rs:387:24:387:28 | chunk | test.rs:388:18:388:22 | chunk | provenance | | | test.rs:387:33:387:59 | reader_split.next_segment() [future, Ok, Some] | test.rs:387:33:387:65 | await ... [Ok, Some] | provenance | | | test.rs:387:33:387:65 | await ... [Ok, Some] | test.rs:387:33:387:66 | TryExpr [Some] | provenance | | | test.rs:387:33:387:66 | TryExpr [Some] | test.rs:387:19:387:29 | Some(...) [Some] | provenance | | -| test.rs:393:13:393:18 | reader | test.rs:394:25:394:38 | reader.lines() | provenance | MaD:63 | +| test.rs:393:13:393:18 | reader | test.rs:394:25:394:38 | reader.lines() | provenance | MaD:66 | | test.rs:393:22:393:66 | ...::new(...) | test.rs:393:13:393:18 | reader | provenance | | -| test.rs:393:48:393:63 | ...::stdin | test.rs:393:48:393:65 | ...::stdin(...) | provenance | Src:MaD:34 MaD:34 | -| test.rs:393:48:393:65 | ...::stdin(...) | test.rs:393:22:393:66 | ...::new(...) | provenance | MaD:118 | -| test.rs:394:13:394:21 | mut lines | test.rs:395:14:395:30 | lines.next_line() [future, Ok, Some] | provenance | MaD:119 | -| test.rs:394:13:394:21 | mut lines | test.rs:396:32:396:48 | lines.next_line() [future, Ok, Some] | provenance | MaD:119 | +| test.rs:393:48:393:63 | ...::stdin | test.rs:393:48:393:65 | ...::stdin(...) | provenance | Src:MaD:37 MaD:37 | +| test.rs:393:48:393:65 | ...::stdin(...) | test.rs:393:22:393:66 | ...::new(...) | provenance | MaD:121 | +| test.rs:394:13:394:21 | mut lines | test.rs:395:14:395:30 | lines.next_line() [future, Ok, Some] | provenance | MaD:122 | +| test.rs:394:13:394:21 | mut lines | test.rs:396:32:396:48 | lines.next_line() [future, Ok, Some] | provenance | MaD:122 | | test.rs:394:25:394:38 | reader.lines() | test.rs:394:13:394:21 | mut lines | provenance | | | test.rs:395:14:395:30 | lines.next_line() [future, Ok, Some] | test.rs:395:14:395:36 | await ... [Ok, Some] | provenance | | | test.rs:395:14:395:36 | await ... [Ok, Some] | test.rs:395:14:395:37 | TryExpr [Some] | provenance | | -| test.rs:395:14:395:37 | TryExpr [Some] | test.rs:395:14:395:46 | ... .unwrap() | provenance | MaD:79 | +| test.rs:395:14:395:37 | TryExpr [Some] | test.rs:395:14:395:46 | ... .unwrap() | provenance | MaD:82 | | test.rs:396:19:396:28 | Some(...) [Some] | test.rs:396:24:396:27 | line | provenance | | | test.rs:396:24:396:27 | line | test.rs:397:18:397:21 | line | provenance | | | test.rs:396:32:396:48 | lines.next_line() [future, Ok, Some] | test.rs:396:32:396:54 | await ... [Ok, Some] | provenance | | | test.rs:396:32:396:54 | await ... [Ok, Some] | test.rs:396:32:396:55 | TryExpr [Some] | provenance | | | test.rs:396:32:396:55 | TryExpr [Some] | test.rs:396:19:396:28 | Some(...) [Some] | provenance | | | test.rs:408:13:408:18 | buffer | test.rs:409:14:409:19 | buffer | provenance | | -| test.rs:408:31:408:43 | ...::read | test.rs:408:31:408:43 | ...::read [Ok] | provenance | Src:MaD:25 | -| test.rs:408:31:408:43 | ...::read | test.rs:408:31:408:55 | ...::read(...) [Ok] | provenance | Src:MaD:25 | -| test.rs:408:31:408:43 | ...::read [Ok] | test.rs:408:31:408:55 | ...::read(...) [Ok] | provenance | MaD:26 | +| test.rs:408:31:408:43 | ...::read | test.rs:408:31:408:43 | ...::read [Ok] | provenance | Src:MaD:28 | +| test.rs:408:31:408:43 | ...::read | test.rs:408:31:408:55 | ...::read(...) [Ok] | provenance | Src:MaD:28 | +| test.rs:408:31:408:43 | ...::read [Ok] | test.rs:408:31:408:55 | ...::read(...) [Ok] | provenance | MaD:29 | | test.rs:408:31:408:55 | ...::read(...) [Ok] | test.rs:408:31:408:56 | TryExpr | provenance | | | test.rs:408:31:408:56 | TryExpr | test.rs:408:13:408:18 | buffer | provenance | | | test.rs:413:13:413:18 | buffer | test.rs:414:14:414:19 | buffer | provenance | | -| test.rs:413:31:413:38 | ...::read | test.rs:413:31:413:38 | ...::read [Ok] | provenance | Src:MaD:25 | -| test.rs:413:31:413:38 | ...::read | test.rs:413:31:413:50 | ...::read(...) [Ok] | provenance | Src:MaD:25 | -| test.rs:413:31:413:38 | ...::read [Ok] | test.rs:413:31:413:50 | ...::read(...) [Ok] | provenance | MaD:26 | +| test.rs:413:31:413:38 | ...::read | test.rs:413:31:413:38 | ...::read [Ok] | provenance | Src:MaD:28 | +| test.rs:413:31:413:38 | ...::read | test.rs:413:31:413:50 | ...::read(...) [Ok] | provenance | Src:MaD:28 | +| test.rs:413:31:413:38 | ...::read [Ok] | test.rs:413:31:413:50 | ...::read(...) [Ok] | provenance | MaD:29 | | test.rs:413:31:413:50 | ...::read(...) [Ok] | test.rs:413:31:413:51 | TryExpr | provenance | | | test.rs:413:31:413:51 | TryExpr | test.rs:413:13:413:18 | buffer | provenance | | | test.rs:418:13:418:18 | buffer | test.rs:419:14:419:19 | buffer | provenance | | -| test.rs:418:22:418:39 | ...::read_to_string | test.rs:418:22:418:39 | ...::read_to_string [Ok] | provenance | Src:MaD:28 | -| test.rs:418:22:418:39 | ...::read_to_string | test.rs:418:22:418:51 | ...::read_to_string(...) [Ok] | provenance | Src:MaD:28 | -| test.rs:418:22:418:39 | ...::read_to_string [Ok] | test.rs:418:22:418:51 | ...::read_to_string(...) [Ok] | provenance | MaD:29 | +| test.rs:418:22:418:39 | ...::read_to_string | test.rs:418:22:418:39 | ...::read_to_string [Ok] | provenance | Src:MaD:31 | +| test.rs:418:22:418:39 | ...::read_to_string | test.rs:418:22:418:51 | ...::read_to_string(...) [Ok] | provenance | Src:MaD:31 | +| test.rs:418:22:418:39 | ...::read_to_string [Ok] | test.rs:418:22:418:51 | ...::read_to_string(...) [Ok] | provenance | MaD:32 | | test.rs:418:22:418:51 | ...::read_to_string(...) [Ok] | test.rs:418:22:418:52 | TryExpr | provenance | | | test.rs:418:22:418:52 | TryExpr | test.rs:418:13:418:18 | buffer | provenance | | | test.rs:425:13:425:16 | path | test.rs:426:14:426:17 | path | provenance | | -| test.rs:425:13:425:16 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:37 | +| test.rs:425:13:425:16 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:40 | | test.rs:425:13:425:16 | path | test.rs:427:14:427:17 | path | provenance | | -| test.rs:425:13:425:16 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:37 | +| test.rs:425:13:425:16 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:40 | | test.rs:425:13:425:16 | path | test.rs:437:14:437:17 | path | provenance | | | test.rs:425:20:425:27 | e.path() | test.rs:425:13:425:16 | path | provenance | | -| test.rs:425:22:425:25 | path | test.rs:425:20:425:27 | e.path() | provenance | Src:MaD:6 MaD:6 | -| test.rs:426:14:426:17 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:37 | -| test.rs:427:14:427:17 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:37 | -| test.rs:427:14:427:25 | path.clone() | test.rs:427:14:427:35 | ... .as_path() | provenance | MaD:116 | +| test.rs:425:22:425:25 | path | test.rs:425:20:425:27 | e.path() | provenance | Src:MaD:9 MaD:9 | +| test.rs:426:14:426:17 | path | test.rs:426:14:426:25 | path.clone() | provenance | MaD:40 | +| test.rs:427:14:427:17 | path | test.rs:427:14:427:25 | path.clone() | provenance | MaD:40 | +| test.rs:427:14:427:25 | path.clone() | test.rs:427:14:427:35 | ... .as_path() | provenance | MaD:119 | | test.rs:439:13:439:21 | file_name | test.rs:440:14:440:22 | file_name | provenance | | -| test.rs:439:13:439:21 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:37 | +| test.rs:439:13:439:21 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:40 | | test.rs:439:13:439:21 | file_name | test.rs:445:14:445:22 | file_name | provenance | | | test.rs:439:25:439:37 | e.file_name() | test.rs:439:13:439:21 | file_name | provenance | | -| test.rs:439:27:439:35 | file_name | test.rs:439:25:439:37 | e.file_name() | provenance | Src:MaD:5 MaD:5 | -| test.rs:440:14:440:22 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:37 | +| test.rs:439:27:439:35 | file_name | test.rs:439:25:439:37 | e.file_name() | provenance | Src:MaD:8 MaD:8 | +| test.rs:440:14:440:22 | file_name | test.rs:440:14:440:30 | file_name.clone() | provenance | MaD:40 | | test.rs:461:13:461:18 | target | test.rs:462:14:462:19 | target | provenance | | -| test.rs:461:22:461:34 | ...::read_link | test.rs:461:22:461:49 | ...::read_link(...) [Ok] | provenance | Src:MaD:27 | +| test.rs:461:22:461:34 | ...::read_link | test.rs:461:22:461:49 | ...::read_link(...) [Ok] | provenance | Src:MaD:30 | | test.rs:461:22:461:49 | ...::read_link(...) [Ok] | test.rs:461:22:461:50 | TryExpr | provenance | | | test.rs:461:22:461:50 | TryExpr | test.rs:461:13:461:18 | target | provenance | | | test.rs:470:13:470:18 | buffer | test.rs:471:14:471:19 | buffer | provenance | | -| test.rs:470:31:470:45 | ...::read | test.rs:470:31:470:57 | ...::read(...) [future, Ok] | provenance | Src:MaD:31 | +| test.rs:470:31:470:45 | ...::read | test.rs:470:31:470:57 | ...::read(...) [future, Ok] | provenance | Src:MaD:34 | | test.rs:470:31:470:57 | ...::read(...) [future, Ok] | test.rs:470:31:470:63 | await ... [Ok] | provenance | | | test.rs:470:31:470:63 | await ... [Ok] | test.rs:470:31:470:64 | TryExpr | provenance | | | test.rs:470:31:470:64 | TryExpr | test.rs:470:13:470:18 | buffer | provenance | | | test.rs:475:13:475:18 | buffer | test.rs:476:14:476:19 | buffer | provenance | | -| test.rs:475:31:475:45 | ...::read | test.rs:475:31:475:57 | ...::read(...) [future, Ok] | provenance | Src:MaD:31 | +| test.rs:475:31:475:45 | ...::read | test.rs:475:31:475:57 | ...::read(...) [future, Ok] | provenance | Src:MaD:34 | | test.rs:475:31:475:57 | ...::read(...) [future, Ok] | test.rs:475:31:475:63 | await ... [Ok] | provenance | | | test.rs:475:31:475:63 | await ... [Ok] | test.rs:475:31:475:64 | TryExpr | provenance | | | test.rs:475:31:475:64 | TryExpr | test.rs:475:13:475:18 | buffer | provenance | | | test.rs:480:13:480:18 | buffer | test.rs:481:14:481:19 | buffer | provenance | | -| test.rs:480:22:480:46 | ...::read_to_string | test.rs:480:22:480:58 | ...::read_to_string(...) [future, Ok] | provenance | Src:MaD:33 | +| test.rs:480:22:480:46 | ...::read_to_string | test.rs:480:22:480:58 | ...::read_to_string(...) [future, Ok] | provenance | Src:MaD:36 | | test.rs:480:22:480:58 | ...::read_to_string(...) [future, Ok] | test.rs:480:22:480:64 | await ... [Ok] | provenance | | | test.rs:480:22:480:64 | await ... [Ok] | test.rs:480:22:480:65 | TryExpr | provenance | | | test.rs:480:22:480:65 | TryExpr | test.rs:480:13:480:18 | buffer | provenance | | | test.rs:486:13:486:16 | path | test.rs:488:14:488:17 | path | provenance | | | test.rs:486:20:486:31 | entry.path() | test.rs:486:13:486:16 | path | provenance | | -| test.rs:486:26:486:29 | path | test.rs:486:20:486:31 | entry.path() | provenance | Src:MaD:14 MaD:14 | -| test.rs:486:26:486:29 | path | test.rs:486:20:486:31 | entry.path() | provenance | Src:MaD:14 MaD:14 | +| test.rs:486:26:486:29 | path | test.rs:486:20:486:31 | entry.path() | provenance | Src:MaD:17 MaD:17 | +| test.rs:486:26:486:29 | path | test.rs:486:20:486:31 | entry.path() | provenance | Src:MaD:17 MaD:17 | | test.rs:487:13:487:21 | file_name | test.rs:489:14:489:22 | file_name | provenance | | | test.rs:487:25:487:41 | entry.file_name() | test.rs:487:13:487:21 | file_name | provenance | | -| test.rs:487:31:487:39 | file_name | test.rs:487:25:487:41 | entry.file_name() | provenance | Src:MaD:13 MaD:13 | -| test.rs:487:31:487:39 | file_name | test.rs:487:25:487:41 | entry.file_name() | provenance | Src:MaD:13 MaD:13 | +| test.rs:487:31:487:39 | file_name | test.rs:487:25:487:41 | entry.file_name() | provenance | Src:MaD:16 MaD:16 | +| test.rs:487:31:487:39 | file_name | test.rs:487:25:487:41 | entry.file_name() | provenance | Src:MaD:16 MaD:16 | | test.rs:493:13:493:18 | target | test.rs:494:14:494:19 | target | provenance | | -| test.rs:493:22:493:41 | ...::read_link | test.rs:493:22:493:56 | ...::read_link(...) [future, Ok] | provenance | Src:MaD:32 | +| test.rs:493:22:493:41 | ...::read_link | test.rs:493:22:493:56 | ...::read_link(...) [future, Ok] | provenance | Src:MaD:35 | | test.rs:493:22:493:56 | ...::read_link(...) [future, Ok] | test.rs:493:22:493:62 | await ... [Ok] | provenance | | | test.rs:493:22:493:62 | await ... [Ok] | test.rs:493:22:493:63 | TryExpr | provenance | | | test.rs:493:22:493:63 | TryExpr | test.rs:493:13:493:18 | target | provenance | | -| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer | provenance | MaD:97 | -| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:57 | -| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:96 | -| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer | provenance | MaD:99 | -| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:59 | -| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:98 | -| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer | provenance | MaD:101 | -| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:60 | -| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:100 | -| test.rs:503:9:503:16 | mut file | test.rs:525:25:525:35 | [post] &mut buffer [&ref] | provenance | MaD:58 | -| test.rs:503:9:503:16 | mut file | test.rs:529:17:529:28 | file.bytes() | provenance | MaD:54 | -| test.rs:503:20:503:38 | ...::open | test.rs:503:20:503:50 | ...::open(...) [Ok] | provenance | Src:MaD:7 | +| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer | provenance | MaD:100 | +| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:503:9:503:16 | mut file | test.rs:507:32:507:42 | [post] &mut buffer [&ref] | provenance | MaD:99 | +| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer | provenance | MaD:102 | +| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:62 | +| test.rs:503:9:503:16 | mut file | test.rs:513:39:513:49 | [post] &mut buffer [&ref] | provenance | MaD:101 | +| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer | provenance | MaD:104 | +| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:63 | +| test.rs:503:9:503:16 | mut file | test.rs:519:42:519:52 | [post] &mut buffer [&ref] | provenance | MaD:103 | +| test.rs:503:9:503:16 | mut file | test.rs:525:25:525:35 | [post] &mut buffer [&ref] | provenance | MaD:61 | +| test.rs:503:9:503:16 | mut file | test.rs:529:17:529:28 | file.bytes() | provenance | MaD:57 | +| test.rs:503:20:503:38 | ...::open | test.rs:503:20:503:50 | ...::open(...) [Ok] | provenance | Src:MaD:10 | | test.rs:503:20:503:50 | ...::open(...) [Ok] | test.rs:503:20:503:51 | TryExpr | provenance | | | test.rs:503:20:503:51 | TryExpr | test.rs:503:9:503:16 | mut file | provenance | | | test.rs:507:32:507:42 | [post] &mut buffer | test.rs:508:15:508:20 | buffer | provenance | | @@ -542,69 +545,69 @@ edges | test.rs:525:30:525:35 | [post] buffer | test.rs:526:15:526:20 | buffer | provenance | | | test.rs:526:15:526:20 | buffer | test.rs:526:14:526:20 | &buffer | provenance | | | test.rs:529:17:529:28 | file.bytes() | test.rs:530:14:530:17 | byte | provenance | | -| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer | provenance | MaD:97 | -| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:57 | -| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:96 | -| test.rs:536:22:536:63 | ... .open(...) [Ok] | test.rs:536:22:536:72 | ... .unwrap() | provenance | MaD:84 | +| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer | provenance | MaD:100 | +| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:536:13:536:18 | mut f1 | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | provenance | MaD:99 | +| test.rs:536:22:536:63 | ... .open(...) [Ok] | test.rs:536:22:536:72 | ... .unwrap() | provenance | MaD:87 | | test.rs:536:22:536:72 | ... .unwrap() | test.rs:536:13:536:18 | mut f1 | provenance | | -| test.rs:536:50:536:53 | open | test.rs:536:22:536:63 | ... .open(...) [Ok] | provenance | Src:MaD:8 | +| test.rs:536:50:536:53 | open | test.rs:536:22:536:63 | ... .open(...) [Ok] | provenance | Src:MaD:11 | | test.rs:538:30:538:40 | [post] &mut buffer | test.rs:539:15:539:20 | buffer | provenance | | | test.rs:538:30:538:40 | [post] &mut buffer [&ref] | test.rs:538:35:538:40 | [post] buffer | provenance | | | test.rs:538:35:538:40 | [post] buffer | test.rs:539:15:539:20 | buffer | provenance | | | test.rs:539:15:539:20 | buffer | test.rs:539:14:539:20 | &buffer | provenance | | -| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer | provenance | MaD:97 | -| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:57 | -| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:96 | -| test.rs:543:22:543:80 | ... .open(...) [Ok] | test.rs:543:22:543:89 | ... .unwrap() | provenance | MaD:84 | +| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer | provenance | MaD:100 | +| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:543:13:543:18 | mut f2 | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | provenance | MaD:99 | +| test.rs:543:22:543:80 | ... .open(...) [Ok] | test.rs:543:22:543:89 | ... .unwrap() | provenance | MaD:87 | | test.rs:543:22:543:89 | ... .unwrap() | test.rs:543:13:543:18 | mut f2 | provenance | | -| test.rs:543:67:543:70 | open | test.rs:543:22:543:80 | ... .open(...) [Ok] | provenance | Src:MaD:8 | +| test.rs:543:67:543:70 | open | test.rs:543:22:543:80 | ... .open(...) [Ok] | provenance | Src:MaD:11 | | test.rs:545:30:545:40 | [post] &mut buffer | test.rs:546:15:546:20 | buffer | provenance | | | test.rs:545:30:545:40 | [post] &mut buffer [&ref] | test.rs:545:35:545:40 | [post] buffer | provenance | | | test.rs:545:35:545:40 | [post] buffer | test.rs:546:15:546:20 | buffer | provenance | | | test.rs:546:15:546:20 | buffer | test.rs:546:14:546:20 | &buffer | provenance | | -| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer | provenance | MaD:97 | -| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:57 | -| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:96 | -| test.rs:550:22:550:114 | ... .open(...) [Ok] | test.rs:550:22:550:123 | ... .unwrap() | provenance | MaD:84 | +| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer | provenance | MaD:100 | +| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:550:13:550:18 | mut f3 | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | provenance | MaD:99 | +| test.rs:550:22:550:114 | ... .open(...) [Ok] | test.rs:550:22:550:123 | ... .unwrap() | provenance | MaD:87 | | test.rs:550:22:550:123 | ... .unwrap() | test.rs:550:13:550:18 | mut f3 | provenance | | -| test.rs:550:101:550:104 | open | test.rs:550:22:550:114 | ... .open(...) [Ok] | provenance | Src:MaD:8 | +| test.rs:550:101:550:104 | open | test.rs:550:22:550:114 | ... .open(...) [Ok] | provenance | Src:MaD:11 | | test.rs:552:30:552:40 | [post] &mut buffer | test.rs:553:15:553:20 | buffer | provenance | | | test.rs:552:30:552:40 | [post] &mut buffer [&ref] | test.rs:552:35:552:40 | [post] buffer | provenance | | | test.rs:552:35:552:40 | [post] buffer | test.rs:553:15:553:20 | buffer | provenance | | | test.rs:553:15:553:20 | buffer | test.rs:553:14:553:20 | &buffer | provenance | | -| test.rs:560:13:560:17 | file1 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:56 | -| test.rs:560:21:560:39 | ...::open | test.rs:560:21:560:51 | ...::open(...) [Ok] | provenance | Src:MaD:7 | +| test.rs:560:13:560:17 | file1 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:59 | +| test.rs:560:21:560:39 | ...::open | test.rs:560:21:560:51 | ...::open(...) [Ok] | provenance | Src:MaD:10 | | test.rs:560:21:560:51 | ...::open(...) [Ok] | test.rs:560:21:560:52 | TryExpr | provenance | | | test.rs:560:21:560:52 | TryExpr | test.rs:560:13:560:17 | file1 | provenance | | | test.rs:561:13:561:17 | file2 | test.rs:562:38:562:42 | file2 | provenance | | -| test.rs:561:21:561:39 | ...::open | test.rs:561:21:561:59 | ...::open(...) [Ok] | provenance | Src:MaD:7 | +| test.rs:561:21:561:39 | ...::open | test.rs:561:21:561:59 | ...::open(...) [Ok] | provenance | Src:MaD:10 | | test.rs:561:21:561:59 | ...::open(...) [Ok] | test.rs:561:21:561:60 | TryExpr | provenance | | | test.rs:561:21:561:60 | TryExpr | test.rs:561:13:561:17 | file2 | provenance | | -| test.rs:562:13:562:22 | mut reader | test.rs:563:31:563:41 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:562:13:562:22 | mut reader | test.rs:563:31:563:41 | [post] &mut buffer [&ref] | provenance | MaD:63 | | test.rs:562:26:562:43 | file1.chain(...) | test.rs:562:13:562:22 | mut reader | provenance | | -| test.rs:562:38:562:42 | file2 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:55 | +| test.rs:562:38:562:42 | file2 | test.rs:562:26:562:43 | file1.chain(...) | provenance | MaD:58 | | test.rs:563:31:563:41 | [post] &mut buffer [&ref] | test.rs:563:36:563:41 | [post] buffer | provenance | | | test.rs:563:36:563:41 | [post] buffer | test.rs:564:15:564:20 | buffer | provenance | | | test.rs:564:15:564:20 | buffer | test.rs:564:14:564:20 | &buffer | provenance | | -| test.rs:569:13:569:17 | file1 | test.rs:570:26:570:40 | file1.take(...) | provenance | MaD:61 | -| test.rs:569:21:569:39 | ...::open | test.rs:569:21:569:51 | ...::open(...) [Ok] | provenance | Src:MaD:7 | +| test.rs:569:13:569:17 | file1 | test.rs:570:26:570:40 | file1.take(...) | provenance | MaD:64 | +| test.rs:569:21:569:39 | ...::open | test.rs:569:21:569:51 | ...::open(...) [Ok] | provenance | Src:MaD:10 | | test.rs:569:21:569:51 | ...::open(...) [Ok] | test.rs:569:21:569:52 | TryExpr | provenance | | | test.rs:569:21:569:52 | TryExpr | test.rs:569:13:569:17 | file1 | provenance | | -| test.rs:570:13:570:22 | mut reader | test.rs:571:31:571:41 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:570:13:570:22 | mut reader | test.rs:571:31:571:41 | [post] &mut buffer [&ref] | provenance | MaD:63 | | test.rs:570:26:570:40 | file1.take(...) | test.rs:570:13:570:22 | mut reader | provenance | | | test.rs:571:31:571:41 | [post] &mut buffer [&ref] | test.rs:571:36:571:41 | [post] buffer | provenance | | | test.rs:571:36:571:41 | [post] buffer | test.rs:572:15:572:20 | buffer | provenance | | | test.rs:572:15:572:20 | buffer | test.rs:572:14:572:20 | &buffer | provenance | | -| test.rs:581:9:581:16 | mut file | test.rs:585:32:585:42 | [post] &mut buffer [&ref] | provenance | MaD:67 | -| test.rs:581:9:581:16 | mut file | test.rs:591:39:591:49 | [post] &mut buffer [&ref] | provenance | MaD:73 | -| test.rs:581:9:581:16 | mut file | test.rs:597:42:597:52 | [post] &mut buffer [&ref] | provenance | MaD:74 | -| test.rs:581:9:581:16 | mut file | test.rs:603:25:603:35 | [post] &mut buffer [&ref] | provenance | MaD:69 | -| test.rs:581:9:581:16 | mut file | test.rs:608:18:608:31 | file.read_u8() [future, Ok] | provenance | MaD:75 | -| test.rs:581:9:581:16 | mut file | test.rs:609:18:609:32 | file.read_i16() [future, Ok] | provenance | MaD:71 | -| test.rs:581:9:581:16 | mut file | test.rs:610:18:610:32 | file.read_f32() [future, Ok] | provenance | MaD:70 | -| test.rs:581:9:581:16 | mut file | test.rs:611:18:611:35 | file.read_i64_le() [future, Ok] | provenance | MaD:72 | -| test.rs:581:9:581:16 | mut file | test.rs:620:23:620:33 | [post] &mut buffer [&ref] | provenance | MaD:68 | -| test.rs:581:20:581:40 | ...::open | test.rs:581:20:581:52 | ...::open(...) [future, Ok] | provenance | Src:MaD:11 | +| test.rs:581:9:581:16 | mut file | test.rs:585:32:585:42 | [post] &mut buffer [&ref] | provenance | MaD:70 | +| test.rs:581:9:581:16 | mut file | test.rs:591:39:591:49 | [post] &mut buffer [&ref] | provenance | MaD:76 | +| test.rs:581:9:581:16 | mut file | test.rs:597:42:597:52 | [post] &mut buffer [&ref] | provenance | MaD:77 | +| test.rs:581:9:581:16 | mut file | test.rs:603:25:603:35 | [post] &mut buffer [&ref] | provenance | MaD:72 | +| test.rs:581:9:581:16 | mut file | test.rs:608:18:608:31 | file.read_u8() [future, Ok] | provenance | MaD:78 | +| test.rs:581:9:581:16 | mut file | test.rs:609:18:609:32 | file.read_i16() [future, Ok] | provenance | MaD:74 | +| test.rs:581:9:581:16 | mut file | test.rs:610:18:610:32 | file.read_f32() [future, Ok] | provenance | MaD:73 | +| test.rs:581:9:581:16 | mut file | test.rs:611:18:611:35 | file.read_i64_le() [future, Ok] | provenance | MaD:75 | +| test.rs:581:9:581:16 | mut file | test.rs:620:23:620:33 | [post] &mut buffer [&ref] | provenance | MaD:71 | +| test.rs:581:20:581:40 | ...::open | test.rs:581:20:581:52 | ...::open(...) [future, Ok] | provenance | Src:MaD:14 | | test.rs:581:20:581:52 | ...::open(...) [future, Ok] | test.rs:581:20:581:58 | await ... [Ok] | provenance | | | test.rs:581:20:581:58 | await ... [Ok] | test.rs:581:20:581:59 | TryExpr | provenance | | | test.rs:581:20:581:59 | TryExpr | test.rs:581:9:581:16 | mut file | provenance | | @@ -639,45 +642,45 @@ edges | test.rs:620:23:620:33 | [post] &mut buffer [&ref] | test.rs:620:28:620:33 | [post] buffer | provenance | | | test.rs:620:28:620:33 | [post] buffer | test.rs:621:15:621:20 | buffer | provenance | | | test.rs:621:15:621:20 | buffer | test.rs:621:14:621:20 | &buffer | provenance | | -| test.rs:627:13:627:18 | mut f1 | test.rs:629:30:629:40 | [post] &mut buffer [&ref] | provenance | MaD:67 | +| test.rs:627:13:627:18 | mut f1 | test.rs:629:30:629:40 | [post] &mut buffer [&ref] | provenance | MaD:70 | | test.rs:627:22:627:65 | ... .open(...) [future, Ok] | test.rs:627:22:627:71 | await ... [Ok] | provenance | | | test.rs:627:22:627:71 | await ... [Ok] | test.rs:627:22:627:72 | TryExpr | provenance | | | test.rs:627:22:627:72 | TryExpr | test.rs:627:13:627:18 | mut f1 | provenance | | -| test.rs:627:52:627:55 | open | test.rs:627:22:627:65 | ... .open(...) [future, Ok] | provenance | Src:MaD:12 | +| test.rs:627:52:627:55 | open | test.rs:627:22:627:65 | ... .open(...) [future, Ok] | provenance | Src:MaD:15 | | test.rs:629:30:629:40 | [post] &mut buffer [&ref] | test.rs:629:35:629:40 | [post] buffer | provenance | | | test.rs:629:35:629:40 | [post] buffer | test.rs:630:15:630:20 | buffer | provenance | | | test.rs:630:15:630:20 | buffer | test.rs:630:14:630:20 | &buffer | provenance | | | test.rs:660:9:660:16 | mut file | test.rs:664:22:664:25 | file | provenance | | -| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:35 | -| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:36 | -| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:46 | -| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:47 | -| test.rs:660:20:660:44 | ...::open | test.rs:660:20:660:56 | ...::open(...) [future, Ok] | provenance | Src:MaD:1 | +| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:38 | +| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:39 | +| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:49 | +| test.rs:660:9:660:16 | mut file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:50 | +| test.rs:660:20:660:44 | ...::open | test.rs:660:20:660:56 | ...::open(...) [future, Ok] | provenance | Src:MaD:4 | | test.rs:660:20:660:56 | ...::open(...) [future, Ok] | test.rs:660:20:660:62 | await ... [Ok] | provenance | | | test.rs:660:20:660:62 | await ... [Ok] | test.rs:660:20:660:63 | TryExpr | provenance | | | test.rs:660:20:660:63 | TryExpr | test.rs:660:9:660:16 | mut file | provenance | | -| test.rs:664:22:664:25 | file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:35 | -| test.rs:664:22:664:25 | file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:46 | +| test.rs:664:22:664:25 | file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:38 | +| test.rs:664:22:664:25 | file | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | provenance | MaD:49 | | test.rs:664:32:664:42 | [post] &mut buffer [&ref] | test.rs:664:37:664:42 | [post] buffer | provenance | | | test.rs:664:37:664:42 | [post] buffer | test.rs:665:15:665:20 | buffer | provenance | | | test.rs:665:15:665:20 | buffer | test.rs:665:14:665:20 | &buffer | provenance | | | test.rs:671:13:671:18 | mut f1 | test.rs:673:22:673:23 | f1 | provenance | | -| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:35 | -| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:36 | -| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:46 | -| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:47 | +| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:38 | +| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:39 | +| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:49 | +| test.rs:671:13:671:18 | mut f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:50 | | test.rs:671:22:671:69 | ... .open(...) [future, Ok] | test.rs:671:22:671:75 | await ... [Ok] | provenance | | | test.rs:671:22:671:75 | await ... [Ok] | test.rs:671:22:671:76 | TryExpr | provenance | | | test.rs:671:22:671:76 | TryExpr | test.rs:671:13:671:18 | mut f1 | provenance | | -| test.rs:671:56:671:59 | open | test.rs:671:22:671:69 | ... .open(...) [future, Ok] | provenance | Src:MaD:2 | -| test.rs:673:22:673:23 | f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:35 | -| test.rs:673:22:673:23 | f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:46 | +| test.rs:671:56:671:59 | open | test.rs:671:22:671:69 | ... .open(...) [future, Ok] | provenance | Src:MaD:5 | +| test.rs:673:22:673:23 | f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:38 | +| test.rs:673:22:673:23 | f1 | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | provenance | MaD:49 | | test.rs:673:30:673:40 | [post] &mut buffer [&ref] | test.rs:673:35:673:40 | [post] buffer | provenance | | | test.rs:673:35:673:40 | [post] buffer | test.rs:674:15:674:20 | buffer | provenance | | | test.rs:674:15:674:20 | buffer | test.rs:674:14:674:20 | &buffer | provenance | | -| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:57 | -| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:115 | -| test.rs:688:26:688:53 | ...::connect | test.rs:688:26:688:62 | ...::connect(...) [Ok] | provenance | Src:MaD:9 | +| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:60 | +| test.rs:688:13:688:22 | mut stream | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | provenance | MaD:118 | +| test.rs:688:26:688:53 | ...::connect | test.rs:688:26:688:62 | ...::connect(...) [Ok] | provenance | Src:MaD:12 | | test.rs:688:26:688:62 | ...::connect(...) [Ok] | test.rs:688:26:688:63 | TryExpr | provenance | | | test.rs:688:26:688:63 | TryExpr | test.rs:688:13:688:22 | mut stream | provenance | | | test.rs:695:29:695:39 | [post] &mut buffer [&ref] | test.rs:695:34:695:39 | [post] buffer | provenance | | @@ -685,21 +688,21 @@ edges | test.rs:695:34:695:39 | [post] buffer | test.rs:699:14:699:22 | buffer[0] | provenance | | | test.rs:698:15:698:20 | buffer | test.rs:698:14:698:20 | &buffer | provenance | | | test.rs:707:13:707:22 | mut stream | test.rs:715:58:715:63 | stream | provenance | | -| test.rs:707:26:707:61 | ...::connect_timeout | test.rs:707:26:707:105 | ...::connect_timeout(...) [Ok] | provenance | Src:MaD:10 | +| test.rs:707:26:707:61 | ...::connect_timeout | test.rs:707:26:707:105 | ...::connect_timeout(...) [Ok] | provenance | Src:MaD:13 | | test.rs:707:26:707:105 | ...::connect_timeout(...) [Ok] | test.rs:707:26:707:106 | TryExpr | provenance | | | test.rs:707:26:707:106 | TryExpr | test.rs:707:13:707:22 | mut stream | provenance | | -| test.rs:715:21:715:30 | mut reader | test.rs:718:44:718:52 | [post] &mut line [&ref] | provenance | MaD:51 | -| test.rs:715:34:715:64 | ...::new(...) | test.rs:715:34:715:74 | ... .take(...) | provenance | MaD:61 | +| test.rs:715:21:715:30 | mut reader | test.rs:718:44:718:52 | [post] &mut line [&ref] | provenance | MaD:54 | +| test.rs:715:34:715:64 | ...::new(...) | test.rs:715:34:715:74 | ... .take(...) | provenance | MaD:64 | | test.rs:715:34:715:74 | ... .take(...) | test.rs:715:21:715:30 | mut reader | provenance | | -| test.rs:715:58:715:63 | stream | test.rs:715:34:715:64 | ...::new(...) | provenance | MaD:105 | +| test.rs:715:58:715:63 | stream | test.rs:715:34:715:64 | ...::new(...) | provenance | MaD:108 | | test.rs:718:44:718:52 | [post] &mut line [&ref] | test.rs:718:49:718:52 | [post] line | provenance | | | test.rs:718:49:718:52 | [post] line | test.rs:725:35:725:38 | line | provenance | | | test.rs:725:35:725:38 | line | test.rs:725:34:725:38 | &line | provenance | | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:767:35:767:46 | [post] &mut buffer1 [&ref] | provenance | MaD:121 | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:771:36:771:47 | [post] &mut buffer2 [&ref] | provenance | MaD:67 | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:787:41:787:51 | [post] &mut buffer [&ref] | provenance | MaD:122 | -| test.rs:759:9:759:24 | mut tokio_stream | test.rs:810:45:810:55 | [post] &mut buffer [&ref] | provenance | MaD:123 | -| test.rs:759:28:759:57 | ...::connect | test.rs:759:28:759:66 | ...::connect(...) [future, Ok] | provenance | Src:MaD:15 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:767:35:767:46 | [post] &mut buffer1 [&ref] | provenance | MaD:124 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:771:36:771:47 | [post] &mut buffer2 [&ref] | provenance | MaD:70 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:787:41:787:51 | [post] &mut buffer [&ref] | provenance | MaD:125 | +| test.rs:759:9:759:24 | mut tokio_stream | test.rs:810:45:810:55 | [post] &mut buffer [&ref] | provenance | MaD:126 | +| test.rs:759:28:759:57 | ...::connect | test.rs:759:28:759:66 | ...::connect(...) [future, Ok] | provenance | Src:MaD:18 | | test.rs:759:28:759:66 | ...::connect(...) [future, Ok] | test.rs:759:28:759:72 | await ... [Ok] | provenance | | | test.rs:759:28:759:72 | await ... [Ok] | test.rs:759:28:759:73 | TryExpr | provenance | | | test.rs:759:28:759:73 | TryExpr | test.rs:759:9:759:24 | mut tokio_stream | provenance | | @@ -719,7 +722,7 @@ edges | test.rs:817:27:817:32 | buffer | test.rs:817:26:817:32 | &buffer | provenance | | | test_futures_io.rs:19:9:19:11 | tcp | test_futures_io.rs:20:11:20:13 | tcp | provenance | | | test_futures_io.rs:19:9:19:11 | tcp | test_futures_io.rs:26:53:26:55 | tcp | provenance | | -| test_futures_io.rs:19:15:19:32 | ...::connect | test_futures_io.rs:19:15:19:37 | ...::connect(...) [future, Ok] | provenance | Src:MaD:3 | +| test_futures_io.rs:19:15:19:32 | ...::connect | test_futures_io.rs:19:15:19:37 | ...::connect(...) [future, Ok] | provenance | Src:MaD:6 | | test_futures_io.rs:19:15:19:37 | ...::connect(...) [future, Ok] | test_futures_io.rs:19:15:19:43 | await ... [Ok] | provenance | | | test_futures_io.rs:19:15:19:43 | await ... [Ok] | test_futures_io.rs:19:15:19:44 | TryExpr | provenance | | | test_futures_io.rs:19:15:19:44 | TryExpr | test_futures_io.rs:19:9:19:11 | tcp | provenance | | @@ -728,15 +731,15 @@ edges | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:32:40:32:45 | reader | provenance | | | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:45:64:45:69 | reader | provenance | | | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:27:49:32 | reader | provenance | | -| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:35 | -| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:36 | -| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:46 | -| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:47 | +| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:38 | +| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:39 | +| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:49 | +| test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:50 | | test_futures_io.rs:26:9:26:18 | mut reader | test_futures_io.rs:54:51:54:56 | reader | provenance | | | test_futures_io.rs:26:22:26:56 | connector.connect(...) [future, Ok] | test_futures_io.rs:26:22:26:62 | await ... [Ok] | provenance | | | test_futures_io.rs:26:22:26:62 | await ... [Ok] | test_futures_io.rs:26:22:26:63 | TryExpr | provenance | | | test_futures_io.rs:26:22:26:63 | TryExpr | test_futures_io.rs:26:9:26:18 | mut reader | provenance | | -| test_futures_io.rs:26:53:26:55 | tcp | test_futures_io.rs:26:22:26:56 | connector.connect(...) [future, Ok] | provenance | MaD:88 | +| test_futures_io.rs:26:53:26:55 | tcp | test_futures_io.rs:26:22:26:56 | connector.connect(...) [future, Ok] | provenance | MaD:91 | | test_futures_io.rs:27:11:27:16 | reader | test_futures_io.rs:27:10:27:16 | &reader | provenance | | | test_futures_io.rs:32:13:32:22 | mut pinned | test_futures_io.rs:33:15:33:20 | pinned | provenance | | | test_futures_io.rs:32:13:32:22 | mut pinned [&ref] | test_futures_io.rs:33:15:33:20 | pinned [&ref] | provenance | | @@ -744,60 +747,60 @@ edges | test_futures_io.rs:32:26:32:46 | ...::new(...) | test_futures_io.rs:32:13:32:22 | mut pinned | provenance | | | test_futures_io.rs:32:26:32:46 | ...::new(...) [&ref] | test_futures_io.rs:32:13:32:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:32:26:32:46 | ...::new(...) [Pin, &ref] | test_futures_io.rs:32:13:32:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) | provenance | MaD:80 | -| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [&ref] | provenance | MaD:82 | -| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [Pin, &ref] | provenance | MaD:81 | +| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) | provenance | MaD:83 | +| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [&ref] | provenance | MaD:85 | +| test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | test_futures_io.rs:32:26:32:46 | ...::new(...) [Pin, &ref] | provenance | MaD:84 | | test_futures_io.rs:32:40:32:45 | reader | test_futures_io.rs:32:35:32:45 | &mut reader [&ref] | provenance | | | test_futures_io.rs:33:15:33:20 | pinned | test_futures_io.rs:33:14:33:20 | &pinned | provenance | | | test_futures_io.rs:33:15:33:20 | pinned [&ref] | test_futures_io.rs:33:14:33:20 | &pinned | provenance | | | test_futures_io.rs:33:15:33:20 | pinned [Pin, &ref] | test_futures_io.rs:33:14:33:20 | &pinned | provenance | | -| test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | provenance | MaD:35 | -| test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | provenance | MaD:46 | +| test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | provenance | MaD:38 | +| test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | provenance | MaD:49 | | test_futures_io.rs:45:64:45:69 | reader | test_futures_io.rs:45:59:45:69 | &mut reader [&ref] | provenance | | | test_futures_io.rs:45:72:45:83 | [post] &mut buffer1 [&ref] | test_futures_io.rs:45:77:45:83 | [post] buffer1 | provenance | | | test_futures_io.rs:45:77:45:83 | [post] buffer1 | test_futures_io.rs:46:15:46:36 | buffer1[...] | provenance | | | test_futures_io.rs:46:15:46:36 | buffer1[...] | test_futures_io.rs:46:14:46:36 | &... | provenance | | -| test_futures_io.rs:49:27:49:32 | reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:35 | -| test_futures_io.rs:49:27:49:32 | reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:46 | +| test_futures_io.rs:49:27:49:32 | reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:38 | +| test_futures_io.rs:49:27:49:32 | reader | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | provenance | MaD:49 | | test_futures_io.rs:49:39:49:50 | [post] &mut buffer2 [&ref] | test_futures_io.rs:49:44:49:50 | [post] buffer2 | provenance | | | test_futures_io.rs:49:44:49:50 | [post] buffer2 | test_futures_io.rs:51:15:51:36 | buffer2[...] | provenance | | | test_futures_io.rs:51:15:51:36 | buffer2[...] | test_futures_io.rs:51:14:51:36 | &... | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:55:11:55:17 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:59:40:59:46 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:69:37:69:43 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:83:22:83:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:41 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:83:22:83:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:44 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:90:40:90:46 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:103:64:103:70 | reader2 | provenance | | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:27:107:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:35 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:36 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:46 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:47 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:38 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:39 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:49 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:50 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:113:40:113:46 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:125:22:125:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:41 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:125:22:125:39 | reader2.fill_buf() [future, Ok] | provenance | MaD:44 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:27:132:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:44 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:45 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:47 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:48 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:27:139:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:42 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:43 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:45 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:46 | | test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:27:146:33 | reader2 | provenance | | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:48 | -| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:49 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:51 | +| test_futures_io.rs:54:9:54:19 | mut reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:52 | | test_futures_io.rs:54:23:54:57 | ...::new(...) | test_futures_io.rs:54:9:54:19 | mut reader2 | provenance | | -| test_futures_io.rs:54:51:54:56 | reader | test_futures_io.rs:54:23:54:57 | ...::new(...) | provenance | MaD:89 | +| test_futures_io.rs:54:51:54:56 | reader | test_futures_io.rs:54:23:54:57 | ...::new(...) | provenance | MaD:92 | | test_futures_io.rs:55:11:55:17 | reader2 | test_futures_io.rs:55:10:55:17 | &reader2 | provenance | | | test_futures_io.rs:59:13:59:22 | mut pinned | test_futures_io.rs:60:15:60:20 | pinned | provenance | | -| test_futures_io.rs:59:13:59:22 | mut pinned | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | +| test_futures_io.rs:59:13:59:22 | mut pinned | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:43 | | test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | test_futures_io.rs:60:15:60:20 | pinned [&ref] | provenance | | -| test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | +| test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | test_futures_io.rs:62:22:62:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:43 | | test_futures_io.rs:59:13:59:22 | mut pinned [Pin, &ref] | test_futures_io.rs:60:15:60:20 | pinned [Pin, &ref] | provenance | | | test_futures_io.rs:59:26:59:47 | ...::new(...) | test_futures_io.rs:59:13:59:22 | mut pinned | provenance | | | test_futures_io.rs:59:26:59:47 | ...::new(...) [&ref] | test_futures_io.rs:59:13:59:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:59:26:59:47 | ...::new(...) [Pin, &ref] | test_futures_io.rs:59:13:59:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) | provenance | MaD:80 | -| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [&ref] | provenance | MaD:82 | -| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [Pin, &ref] | provenance | MaD:81 | +| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) | provenance | MaD:83 | +| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [&ref] | provenance | MaD:85 | +| test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | test_futures_io.rs:59:26:59:47 | ...::new(...) [Pin, &ref] | provenance | MaD:84 | | test_futures_io.rs:59:40:59:46 | reader2 | test_futures_io.rs:59:35:59:46 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:60:15:60:20 | pinned | test_futures_io.rs:60:14:60:20 | &pinned | provenance | | | test_futures_io.rs:60:15:60:20 | pinned [&ref] | test_futures_io.rs:60:14:60:20 | &pinned | provenance | | @@ -810,11 +813,11 @@ edges | test_futures_io.rs:63:31:63:33 | buf | test_futures_io.rs:65:18:65:20 | buf | provenance | | | test_futures_io.rs:64:19:64:24 | buffer [Ready, Ok] | test_futures_io.rs:64:18:64:24 | &buffer | provenance | | | test_futures_io.rs:69:13:69:19 | buffer2 [Ready, Ok] | test_futures_io.rs:70:16:70:22 | buffer2 [Ready, Ok] | provenance | | -| test_futures_io.rs:69:23:69:44 | ...::new(...) | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | -| test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | +| test_futures_io.rs:69:23:69:44 | ...::new(...) | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:43 | +| test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | provenance | MaD:43 | | test_futures_io.rs:69:23:69:67 | ... .poll_fill_buf(...) [Ready, Ok] | test_futures_io.rs:69:13:69:19 | buffer2 [Ready, Ok] | provenance | | -| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) | provenance | MaD:80 | -| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | provenance | MaD:82 | +| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) | provenance | MaD:83 | +| test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | test_futures_io.rs:69:23:69:44 | ...::new(...) [&ref] | provenance | MaD:85 | | test_futures_io.rs:69:37:69:43 | reader2 | test_futures_io.rs:69:32:69:43 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:70:16:70:22 | buffer2 [Ready, Ok] | test_futures_io.rs:71:13:71:32 | ...::Ready(...) [Ready, Ok] | provenance | | | test_futures_io.rs:70:16:70:22 | buffer2 [Ready, Ok] | test_futures_io.rs:72:23:72:29 | buffer2 [Ready, Ok] | provenance | | @@ -832,35 +835,35 @@ edges | test_futures_io.rs:90:26:90:47 | ...::new(...) | test_futures_io.rs:90:13:90:22 | mut pinned | provenance | | | test_futures_io.rs:90:26:90:47 | ...::new(...) [&ref] | test_futures_io.rs:90:13:90:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:90:26:90:47 | ...::new(...) [Pin, &ref] | test_futures_io.rs:90:13:90:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) | provenance | MaD:80 | -| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [&ref] | provenance | MaD:82 | -| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [Pin, &ref] | provenance | MaD:81 | +| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) | provenance | MaD:83 | +| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [&ref] | provenance | MaD:85 | +| test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | test_futures_io.rs:90:26:90:47 | ...::new(...) [Pin, &ref] | provenance | MaD:84 | | test_futures_io.rs:90:40:90:46 | reader2 | test_futures_io.rs:90:35:90:46 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:91:15:91:20 | pinned | test_futures_io.rs:91:14:91:20 | &pinned | provenance | | | test_futures_io.rs:91:15:91:20 | pinned [&ref] | test_futures_io.rs:91:14:91:20 | &pinned | provenance | | | test_futures_io.rs:91:15:91:20 | pinned [Pin, &ref] | test_futures_io.rs:91:14:91:20 | &pinned | provenance | | -| test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | provenance | MaD:35 | -| test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | provenance | MaD:46 | +| test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | provenance | MaD:38 | +| test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | provenance | MaD:49 | | test_futures_io.rs:103:64:103:70 | reader2 | test_futures_io.rs:103:59:103:70 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:103:73:103:84 | [post] &mut buffer1 [&ref] | test_futures_io.rs:103:78:103:84 | [post] buffer1 | provenance | | | test_futures_io.rs:103:78:103:84 | [post] buffer1 | test_futures_io.rs:104:15:104:36 | buffer1[...] | provenance | | | test_futures_io.rs:104:15:104:36 | buffer1[...] | test_futures_io.rs:104:14:104:36 | &... | provenance | | -| test_futures_io.rs:107:27:107:33 | reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:35 | -| test_futures_io.rs:107:27:107:33 | reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:46 | +| test_futures_io.rs:107:27:107:33 | reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:38 | +| test_futures_io.rs:107:27:107:33 | reader2 | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | provenance | MaD:49 | | test_futures_io.rs:107:40:107:51 | [post] &mut buffer2 [&ref] | test_futures_io.rs:107:45:107:51 | [post] buffer2 | provenance | | | test_futures_io.rs:107:45:107:51 | [post] buffer2 | test_futures_io.rs:108:15:108:36 | buffer2[...] | provenance | | | test_futures_io.rs:108:15:108:36 | buffer2[...] | test_futures_io.rs:108:14:108:36 | &... | provenance | | | test_futures_io.rs:113:13:113:22 | mut pinned | test_futures_io.rs:114:15:114:20 | pinned | provenance | | -| test_futures_io.rs:113:13:113:22 | mut pinned | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | +| test_futures_io.rs:113:13:113:22 | mut pinned | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:43 | | test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | test_futures_io.rs:114:15:114:20 | pinned [&ref] | provenance | | -| test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:40 | +| test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | test_futures_io.rs:116:22:116:50 | pinned.poll_fill_buf(...) [Ready, Ok] | provenance | MaD:43 | | test_futures_io.rs:113:13:113:22 | mut pinned [Pin, &ref] | test_futures_io.rs:114:15:114:20 | pinned [Pin, &ref] | provenance | | | test_futures_io.rs:113:26:113:47 | ...::new(...) | test_futures_io.rs:113:13:113:22 | mut pinned | provenance | | | test_futures_io.rs:113:26:113:47 | ...::new(...) [&ref] | test_futures_io.rs:113:13:113:22 | mut pinned [&ref] | provenance | | | test_futures_io.rs:113:26:113:47 | ...::new(...) [Pin, &ref] | test_futures_io.rs:113:13:113:22 | mut pinned [Pin, &ref] | provenance | | -| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) | provenance | MaD:80 | -| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [&ref] | provenance | MaD:82 | -| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [Pin, &ref] | provenance | MaD:81 | +| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) | provenance | MaD:83 | +| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [&ref] | provenance | MaD:85 | +| test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | test_futures_io.rs:113:26:113:47 | ...::new(...) [Pin, &ref] | provenance | MaD:84 | | test_futures_io.rs:113:40:113:46 | reader2 | test_futures_io.rs:113:35:113:46 | &mut reader2 [&ref] | provenance | | | test_futures_io.rs:114:15:114:20 | pinned | test_futures_io.rs:114:14:114:20 | &pinned | provenance | | | test_futures_io.rs:114:15:114:20 | pinned [&ref] | test_futures_io.rs:114:14:114:20 | &pinned | provenance | | @@ -876,42 +879,58 @@ edges | test_futures_io.rs:125:22:125:39 | reader2.fill_buf() [future, Ok] | test_futures_io.rs:125:22:125:45 | await ... [Ok] | provenance | | | test_futures_io.rs:125:22:125:45 | await ... [Ok] | test_futures_io.rs:125:22:125:46 | TryExpr | provenance | | | test_futures_io.rs:125:22:125:46 | TryExpr | test_futures_io.rs:125:13:125:18 | buffer | provenance | | -| test_futures_io.rs:132:27:132:33 | reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:44 | +| test_futures_io.rs:132:27:132:33 | reader2 | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | provenance | MaD:47 | | test_futures_io.rs:132:53:132:61 | [post] &mut line [&ref] | test_futures_io.rs:132:58:132:61 | [post] line | provenance | | | test_futures_io.rs:132:58:132:61 | [post] line | test_futures_io.rs:133:15:133:18 | line | provenance | | | test_futures_io.rs:133:15:133:18 | line | test_futures_io.rs:133:14:133:18 | &line | provenance | | -| test_futures_io.rs:139:27:139:33 | reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:42 | +| test_futures_io.rs:139:27:139:33 | reader2 | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | provenance | MaD:45 | | test_futures_io.rs:139:45:139:53 | [post] &mut line [&ref] | test_futures_io.rs:139:50:139:53 | [post] line | provenance | | | test_futures_io.rs:139:50:139:53 | [post] line | test_futures_io.rs:140:15:140:18 | line | provenance | | | test_futures_io.rs:140:15:140:18 | line | test_futures_io.rs:140:14:140:18 | &line | provenance | | -| test_futures_io.rs:146:27:146:33 | reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:48 | +| test_futures_io.rs:146:27:146:33 | reader2 | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | provenance | MaD:51 | | test_futures_io.rs:146:47:146:57 | [post] &mut buffer [&ref] | test_futures_io.rs:146:52:146:57 | [post] buffer | provenance | | | test_futures_io.rs:146:52:146:57 | [post] buffer | test_futures_io.rs:147:15:147:20 | buffer | provenance | | | test_futures_io.rs:147:15:147:20 | buffer | test_futures_io.rs:147:14:147:20 | &buffer | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:14 | a | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:14 | a | provenance | | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:77 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:86 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:77 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:86 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:80 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:89 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:80 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:89 | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:14 | a | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:14 | a | provenance | | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:76 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:85 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:76 | -| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:85 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:79 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:88 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:79 | +| web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:88 | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:15:14:15:14 | a | provenance | | | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:15:14:15:14 | a | provenance | | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:77 | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:86 | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:77 | -| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:86 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:76 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:85 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:76 | -| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:85 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:80 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:22 | a.as_str() | provenance | MaD:89 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:80 | +| web_frameworks.rs:13:14:13:14 | a | web_frameworks.rs:13:14:13:23 | a.as_str() | provenance | MaD:89 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:79 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:24 | a.as_bytes() | provenance | MaD:88 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:79 | +| web_frameworks.rs:14:14:14:14 | a | web_frameworks.rs:14:14:14:25 | a.as_bytes() | provenance | MaD:88 | | web_frameworks.rs:68:15:68:15 | a | web_frameworks.rs:70:14:70:14 | a | provenance | | | web_frameworks.rs:68:15:68:15 | a | web_frameworks.rs:70:14:70:14 | a | provenance | | +| web_frameworks.rs:242:33:242:35 | map | web_frameworks.rs:242:38:242:46 | ...: String | provenance | Src:MaD:2 | +| web_frameworks.rs:242:33:242:35 | map | web_frameworks.rs:242:38:242:46 | ...: String | provenance | Src:MaD:2 | +| web_frameworks.rs:242:38:242:46 | ...: String | web_frameworks.rs:244:18:244:18 | a | provenance | | +| web_frameworks.rs:242:38:242:46 | ...: String | web_frameworks.rs:244:18:244:18 | a | provenance | | +| web_frameworks.rs:250:46:250:49 | then | web_frameworks.rs:251:25:251:33 | ...: String | provenance | Src:MaD:3 | +| web_frameworks.rs:250:46:250:49 | then | web_frameworks.rs:251:25:251:33 | ...: String | provenance | Src:MaD:3 | +| web_frameworks.rs:251:25:251:33 | ...: String | web_frameworks.rs:252:22:252:22 | a | provenance | | +| web_frameworks.rs:251:25:251:33 | ...: String | web_frameworks.rs:252:22:252:22 | a | provenance | | +| web_frameworks.rs:259:50:259:57 | and_then | web_frameworks.rs:260:26:260:32 | ...: u64 | provenance | Src:MaD:1 | +| web_frameworks.rs:259:50:259:57 | and_then | web_frameworks.rs:260:26:260:32 | ...: u64 | provenance | Src:MaD:1 | +| web_frameworks.rs:260:26:260:32 | ...: u64 | web_frameworks.rs:263:22:263:23 | id | provenance | | +| web_frameworks.rs:260:26:260:32 | ...: u64 | web_frameworks.rs:263:22:263:23 | id | provenance | | +| web_frameworks.rs:272:75:272:77 | map | web_frameworks.rs:273:15:273:23 | ...: String | provenance | Src:MaD:2 | +| web_frameworks.rs:272:75:272:77 | map | web_frameworks.rs:273:15:273:23 | ...: String | provenance | Src:MaD:2 | +| web_frameworks.rs:273:15:273:23 | ...: String | web_frameworks.rs:275:22:275:22 | a | provenance | | +| web_frameworks.rs:273:15:273:23 | ...: String | web_frameworks.rs:275:22:275:22 | a | provenance | | nodes | test.rs:8:10:8:22 | ...::var | semmle.label | ...::var | | test.rs:8:10:8:30 | ...::var(...) | semmle.label | ...::var(...) | @@ -1700,6 +1719,30 @@ nodes | web_frameworks.rs:68:15:68:15 | a | semmle.label | a | | web_frameworks.rs:70:14:70:14 | a | semmle.label | a | | web_frameworks.rs:70:14:70:14 | a | semmle.label | a | +| web_frameworks.rs:242:33:242:35 | map | semmle.label | map | +| web_frameworks.rs:242:33:242:35 | map | semmle.label | map | +| web_frameworks.rs:242:38:242:46 | ...: String | semmle.label | ...: String | +| web_frameworks.rs:242:38:242:46 | ...: String | semmle.label | ...: String | +| web_frameworks.rs:244:18:244:18 | a | semmle.label | a | +| web_frameworks.rs:244:18:244:18 | a | semmle.label | a | +| web_frameworks.rs:250:46:250:49 | then | semmle.label | then | +| web_frameworks.rs:250:46:250:49 | then | semmle.label | then | +| web_frameworks.rs:251:25:251:33 | ...: String | semmle.label | ...: String | +| web_frameworks.rs:251:25:251:33 | ...: String | semmle.label | ...: String | +| web_frameworks.rs:252:22:252:22 | a | semmle.label | a | +| web_frameworks.rs:252:22:252:22 | a | semmle.label | a | +| web_frameworks.rs:259:50:259:57 | and_then | semmle.label | and_then | +| web_frameworks.rs:259:50:259:57 | and_then | semmle.label | and_then | +| web_frameworks.rs:260:26:260:32 | ...: u64 | semmle.label | ...: u64 | +| web_frameworks.rs:260:26:260:32 | ...: u64 | semmle.label | ...: u64 | +| web_frameworks.rs:263:22:263:23 | id | semmle.label | id | +| web_frameworks.rs:263:22:263:23 | id | semmle.label | id | +| web_frameworks.rs:272:75:272:77 | map | semmle.label | map | +| web_frameworks.rs:272:75:272:77 | map | semmle.label | map | +| web_frameworks.rs:273:15:273:23 | ...: String | semmle.label | ...: String | +| web_frameworks.rs:273:15:273:23 | ...: String | semmle.label | ...: String | +| web_frameworks.rs:275:22:275:22 | a | semmle.label | a | +| web_frameworks.rs:275:22:275:22 | a | semmle.label | a | subpaths testFailures #select @@ -1839,3 +1882,11 @@ testFailures | web_frameworks.rs:15:14:15:14 | a | web_frameworks.rs:11:31:11:31 | a | web_frameworks.rs:15:14:15:14 | a | $@ | web_frameworks.rs:11:31:11:31 | a | a | | web_frameworks.rs:70:14:70:14 | a | web_frameworks.rs:68:15:68:15 | a | web_frameworks.rs:70:14:70:14 | a | $@ | web_frameworks.rs:68:15:68:15 | a | a | | web_frameworks.rs:70:14:70:14 | a | web_frameworks.rs:68:15:68:15 | a | web_frameworks.rs:70:14:70:14 | a | $@ | web_frameworks.rs:68:15:68:15 | a | a | +| web_frameworks.rs:244:18:244:18 | a | web_frameworks.rs:242:33:242:35 | map | web_frameworks.rs:244:18:244:18 | a | $@ | web_frameworks.rs:242:33:242:35 | map | map | +| web_frameworks.rs:244:18:244:18 | a | web_frameworks.rs:242:33:242:35 | map | web_frameworks.rs:244:18:244:18 | a | $@ | web_frameworks.rs:242:33:242:35 | map | map | +| web_frameworks.rs:252:22:252:22 | a | web_frameworks.rs:250:46:250:49 | then | web_frameworks.rs:252:22:252:22 | a | $@ | web_frameworks.rs:250:46:250:49 | then | then | +| web_frameworks.rs:252:22:252:22 | a | web_frameworks.rs:250:46:250:49 | then | web_frameworks.rs:252:22:252:22 | a | $@ | web_frameworks.rs:250:46:250:49 | then | then | +| web_frameworks.rs:263:22:263:23 | id | web_frameworks.rs:259:50:259:57 | and_then | web_frameworks.rs:263:22:263:23 | id | $@ | web_frameworks.rs:259:50:259:57 | and_then | and_then | +| web_frameworks.rs:263:22:263:23 | id | web_frameworks.rs:259:50:259:57 | and_then | web_frameworks.rs:263:22:263:23 | id | $@ | web_frameworks.rs:259:50:259:57 | and_then | and_then | +| web_frameworks.rs:275:22:275:22 | a | web_frameworks.rs:272:75:272:77 | map | web_frameworks.rs:275:22:275:22 | a | $@ | web_frameworks.rs:272:75:272:77 | map | map | +| web_frameworks.rs:275:22:275:22 | a | web_frameworks.rs:272:75:272:77 | map | web_frameworks.rs:275:22:275:22 | a | $@ | web_frameworks.rs:272:75:272:77 | map | map | diff --git a/rust/ql/test/library-tests/dataflow/sources/web_frameworks.rs b/rust/ql/test/library-tests/dataflow/sources/web_frameworks.rs index 857fc3b479e..3b901bd823f 100644 --- a/rust/ql/test/library-tests/dataflow/sources/web_frameworks.rs +++ b/rust/ql/test/library-tests/dataflow/sources/web_frameworks.rs @@ -241,7 +241,7 @@ mod warp_test { let map_route = warp::path::param().map(|a: String| // $ Alert[rust/summary/taint-sources] { - sink(a); // $ MISSING: hasTaintFlow + sink(a); // $ hasTaintFlow "".to_string() }); @@ -249,7 +249,7 @@ mod warp_test { // A route with parameter and `then` let then_route = warp::path::param().then( // $ Alert[rust/summary/taint-sources] async move |a: String| { - sink(a); // $ MISSING: hasTaintFlow + sink(a); // $ hasTaintFlow "".to_string() }, @@ -260,7 +260,7 @@ mod warp_test { async move | id: u64 | { if id != 0 { - sink(id); // $ MISSING: hasTaintFlow + sink(id); // $ hasTaintFlow Ok("".to_string()) } else { Err(warp::reject::not_found()) @@ -272,7 +272,7 @@ mod warp_test { let path_and_map_route = warp::path("1").and(warp::path::param()).map( // $ Alert[rust/summary/taint-sources] | a: String | { - sink(a); // $ MISSING: hasTaintFlow + sink(a); // $ hasTaintFlow "".to_string() }, diff --git a/rust/ql/test/query-tests/security/CWE-918/RequestForgery.expected b/rust/ql/test/query-tests/security/CWE-918/RequestForgery.expected index 4d44df7349f..a33742a7c4b 100644 --- a/rust/ql/test/query-tests/security/CWE-918/RequestForgery.expected +++ b/rust/ql/test/query-tests/security/CWE-918/RequestForgery.expected @@ -8,6 +8,8 @@ | request_forgery_tests.rs:31:29:31:40 | ...::get | request_forgery_tests.rs:5:29:5:36 | user_url | request_forgery_tests.rs:31:29:31:40 | ...::get | The URL of this request depends on a $@. | request_forgery_tests.rs:5:29:5:36 | user_url | user-provided value | | request_forgery_tests.rs:37:37:37:48 | ...::get | request_forgery_tests.rs:5:29:5:36 | user_url | request_forgery_tests.rs:37:37:37:48 | ...::get | The URL of this request depends on a $@. | request_forgery_tests.rs:5:29:5:36 | user_url | user-provided value | | request_forgery_tests.rs:37:37:37:48 | ...::get | request_forgery_tests.rs:5:29:5:36 | user_url | request_forgery_tests.rs:37:37:37:48 | ...::get | The URL of this request depends on a $@. | request_forgery_tests.rs:5:29:5:36 | user_url | user-provided value | +| request_forgery_tests.rs:68:28:68:39 | ...::get | request_forgery_tests.rs:65:33:65:40 | and_then | request_forgery_tests.rs:68:28:68:39 | ...::get | The URL of this request depends on a $@. | request_forgery_tests.rs:65:33:65:40 | and_then | user-provided value | +| request_forgery_tests.rs:68:28:68:39 | ...::get | request_forgery_tests.rs:65:33:65:40 | and_then | request_forgery_tests.rs:68:28:68:39 | ...::get | The URL of this request depends on a $@. | request_forgery_tests.rs:65:33:65:40 | and_then | user-provided value | edges | request_forgery_tests.rs:4:5:4:14 | res | request_forgery_tests.rs:16:27:16:49 | { ... } | provenance | | | request_forgery_tests.rs:4:5:4:14 | res | request_forgery_tests.rs:20:27:20:57 | { ... } | provenance | | @@ -28,22 +30,22 @@ edges | request_forgery_tests.rs:16:13:16:15 | url | request_forgery_tests.rs:17:39:17:41 | url | provenance | | | request_forgery_tests.rs:16:27:16:49 | ...::format(...) | request_forgery_tests.rs:4:5:4:14 | res | provenance | | | request_forgery_tests.rs:16:27:16:49 | ...::must_use(...) | request_forgery_tests.rs:16:13:16:15 | url | provenance | | -| request_forgery_tests.rs:16:27:16:49 | MacroExpr | request_forgery_tests.rs:16:27:16:49 | ...::format(...) | provenance | MaD:2 | -| request_forgery_tests.rs:16:27:16:49 | { ... } | request_forgery_tests.rs:16:27:16:49 | ...::must_use(...) | provenance | MaD:3 | +| request_forgery_tests.rs:16:27:16:49 | MacroExpr | request_forgery_tests.rs:16:27:16:49 | ...::format(...) | provenance | MaD:3 | +| request_forgery_tests.rs:16:27:16:49 | { ... } | request_forgery_tests.rs:16:27:16:49 | ...::must_use(...) | provenance | MaD:4 | | request_forgery_tests.rs:17:38:17:41 | &url [&ref] | request_forgery_tests.rs:17:25:17:36 | ...::get | provenance | MaD:1 Sink:MaD:1 | | request_forgery_tests.rs:17:39:17:41 | url | request_forgery_tests.rs:17:38:17:41 | &url [&ref] | provenance | | | request_forgery_tests.rs:20:13:20:15 | url | request_forgery_tests.rs:21:39:21:41 | url | provenance | | | request_forgery_tests.rs:20:27:20:57 | ...::format(...) | request_forgery_tests.rs:4:5:4:14 | res | provenance | | | request_forgery_tests.rs:20:27:20:57 | ...::must_use(...) | request_forgery_tests.rs:20:13:20:15 | url | provenance | | -| request_forgery_tests.rs:20:27:20:57 | MacroExpr | request_forgery_tests.rs:20:27:20:57 | ...::format(...) | provenance | MaD:2 | -| request_forgery_tests.rs:20:27:20:57 | { ... } | request_forgery_tests.rs:20:27:20:57 | ...::must_use(...) | provenance | MaD:3 | +| request_forgery_tests.rs:20:27:20:57 | MacroExpr | request_forgery_tests.rs:20:27:20:57 | ...::format(...) | provenance | MaD:3 | +| request_forgery_tests.rs:20:27:20:57 | { ... } | request_forgery_tests.rs:20:27:20:57 | ...::must_use(...) | provenance | MaD:4 | | request_forgery_tests.rs:21:38:21:41 | &url [&ref] | request_forgery_tests.rs:21:25:21:36 | ...::get | provenance | MaD:1 Sink:MaD:1 | | request_forgery_tests.rs:21:39:21:41 | url | request_forgery_tests.rs:21:38:21:41 | &url [&ref] | provenance | | | request_forgery_tests.rs:24:13:24:15 | url | request_forgery_tests.rs:25:39:25:41 | url | provenance | | | request_forgery_tests.rs:24:27:24:70 | ...::format(...) | request_forgery_tests.rs:4:5:4:14 | res | provenance | | | request_forgery_tests.rs:24:27:24:70 | ...::must_use(...) | request_forgery_tests.rs:24:13:24:15 | url | provenance | | -| request_forgery_tests.rs:24:27:24:70 | MacroExpr | request_forgery_tests.rs:24:27:24:70 | ...::format(...) | provenance | MaD:2 | -| request_forgery_tests.rs:24:27:24:70 | { ... } | request_forgery_tests.rs:24:27:24:70 | ...::must_use(...) | provenance | MaD:3 | +| request_forgery_tests.rs:24:27:24:70 | MacroExpr | request_forgery_tests.rs:24:27:24:70 | ...::format(...) | provenance | MaD:3 | +| request_forgery_tests.rs:24:27:24:70 | { ... } | request_forgery_tests.rs:24:27:24:70 | ...::must_use(...) | provenance | MaD:4 | | request_forgery_tests.rs:25:38:25:41 | &url [&ref] | request_forgery_tests.rs:25:25:25:36 | ...::get | provenance | MaD:1 Sink:MaD:1 | | request_forgery_tests.rs:25:39:25:41 | url | request_forgery_tests.rs:25:38:25:41 | &url [&ref] | provenance | | | request_forgery_tests.rs:31:42:31:50 | &user_url [&ref] | request_forgery_tests.rs:31:29:31:40 | ...::get | provenance | MaD:1 Sink:MaD:1 | @@ -54,10 +56,19 @@ edges | request_forgery_tests.rs:37:50:37:58 | &user_url [&ref] | request_forgery_tests.rs:37:37:37:48 | ...::get | provenance | MaD:1 Sink:MaD:1 | | request_forgery_tests.rs:37:51:37:58 | user_url | request_forgery_tests.rs:37:50:37:58 | &user_url [&ref] | provenance | | | request_forgery_tests.rs:37:51:37:58 | user_url | request_forgery_tests.rs:37:50:37:58 | &user_url [&ref] | provenance | | +| request_forgery_tests.rs:65:33:65:40 | and_then | request_forgery_tests.rs:65:49:65:57 | ...: String | provenance | Src:MaD:2 | +| request_forgery_tests.rs:65:33:65:40 | and_then | request_forgery_tests.rs:65:49:65:57 | ...: String | provenance | Src:MaD:2 | +| request_forgery_tests.rs:65:49:65:57 | ...: String | request_forgery_tests.rs:68:42:68:42 | a | provenance | | +| request_forgery_tests.rs:65:49:65:57 | ...: String | request_forgery_tests.rs:68:42:68:42 | a | provenance | | +| request_forgery_tests.rs:68:41:68:42 | &a [&ref] | request_forgery_tests.rs:68:28:68:39 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| request_forgery_tests.rs:68:41:68:42 | &a [&ref] | request_forgery_tests.rs:68:28:68:39 | ...::get | provenance | MaD:1 Sink:MaD:1 | +| request_forgery_tests.rs:68:42:68:42 | a | request_forgery_tests.rs:68:41:68:42 | &a [&ref] | provenance | | +| request_forgery_tests.rs:68:42:68:42 | a | request_forgery_tests.rs:68:41:68:42 | &a [&ref] | provenance | | models | 1 | Sink: reqwest::get; Argument[0]; request-url | -| 2 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | -| 3 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value | +| 2 | Source: <_ as warp::filter::Filter>::and_then; Argument[0].Parameter[0..7]; remote | +| 3 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | +| 4 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value | nodes | request_forgery_tests.rs:4:5:4:14 | res | semmle.label | res | | request_forgery_tests.rs:4:5:4:14 | res | semmle.label | res | @@ -106,4 +117,14 @@ nodes | request_forgery_tests.rs:37:50:37:58 | &user_url [&ref] | semmle.label | &user_url [&ref] | | request_forgery_tests.rs:37:51:37:58 | user_url | semmle.label | user_url | | request_forgery_tests.rs:37:51:37:58 | user_url | semmle.label | user_url | +| request_forgery_tests.rs:65:33:65:40 | and_then | semmle.label | and_then | +| request_forgery_tests.rs:65:33:65:40 | and_then | semmle.label | and_then | +| request_forgery_tests.rs:65:49:65:57 | ...: String | semmle.label | ...: String | +| request_forgery_tests.rs:65:49:65:57 | ...: String | semmle.label | ...: String | +| request_forgery_tests.rs:68:28:68:39 | ...::get | semmle.label | ...::get | +| request_forgery_tests.rs:68:28:68:39 | ...::get | semmle.label | ...::get | +| request_forgery_tests.rs:68:41:68:42 | &a [&ref] | semmle.label | &a [&ref] | +| request_forgery_tests.rs:68:41:68:42 | &a [&ref] | semmle.label | &a [&ref] | +| request_forgery_tests.rs:68:42:68:42 | a | semmle.label | a | +| request_forgery_tests.rs:68:42:68:42 | a | semmle.label | a | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-918/request_forgery_tests.rs b/rust/ql/test/query-tests/security/CWE-918/request_forgery_tests.rs index ab99d73db43..f9abf14de4f 100644 --- a/rust/ql/test/query-tests/security/CWE-918/request_forgery_tests.rs +++ b/rust/ql/test/query-tests/security/CWE-918/request_forgery_tests.rs @@ -62,10 +62,10 @@ mod warp_test { async fn test_warp() { // A route with parameter and `and_then` let map_route = - warp::path::param().and_then(async |a: String| // $ MISSING: Source=a + warp::path::param().and_then(async |a: String| // $ Source=a { - let response = reqwest::get(&a).await; // $ MISSING: Alert[rust/request-forgery]=a + let response = reqwest::get(&a).await; // $ Alert[rust/request-forgery]=a match response { Ok(resp) => Ok(resp.text().await.unwrap_or_default()), Err(_err) => Err(warp::reject::not_found()), diff --git a/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll b/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll index 3eda6709517..9c46e04bf4b 100644 --- a/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll @@ -1206,12 +1206,12 @@ module Make< * Holds if this node is an exit node, i.e. after all stores have been performed. * * A local flow step should be added from this node to a data flow node representing - * `sc` inside `source`. + * `s` inside `source`. */ - predicate isExit(SourceElement source, SummaryComponent sc, string model) { + predicate isExit(SourceElement source, SummaryComponentStack s, string model) { source = source_ and model = model_ and - state_.isSourceOutputState(source, TSingletonSummaryComponentStack(sc), _, model) + state_.isSourceOutputState(source, s, _, model) } override predicate isHidden() { not this.isEntry(_, _) } @@ -1460,7 +1460,7 @@ module Make< DataFlowType getSyntheticGlobalType(SyntheticGlobal sg); - DataFlowType getSourceType(SourceBase source, SummaryComponent sc); + DataFlowType getSourceType(SourceBase source, SummaryComponentStack sc); DataFlowType getSinkType(SinkBase sink, SummaryComponent sc); } @@ -1543,9 +1543,9 @@ module Make< ) or exists(SourceElement source | - exists(SummaryComponent sc | - n.(SourceOutputNode).isExit(source, sc, _) and - result = getSourceType(source, sc) + exists(SummaryComponentStack s | + n.(SourceOutputNode).isExit(source, s, _) and + result = getSourceType(source, s) ) or exists(SummaryComponentStack s, ContentSet cont | @@ -1574,13 +1574,16 @@ module Make< /** Gets a call that targets summarized callable `sc`. */ DataFlowCall getACall(SummarizedCallable sc); + /** Gets the enclosing callable of `source`. */ + DataFlowCallable getSourceNodeEnclosingCallable(SourceBase source); + /** - * Gets a data flow node corresponding to the `sc` part of `source`. + * Gets a data flow node corresponding to the `s` part of `source`. * - * `sc` is typically `ReturnValue` and the result is the node that + * `s` is typically `ReturnValue` and the result is the node that * represents the return value of `source`. */ - Node getSourceNode(SourceBase source, SummaryComponent sc); + Node getSourceNode(SourceBase source, SummaryComponentStack s); /** * Gets a data flow node corresponding to the `sc` part of `sink`. @@ -1622,13 +1625,20 @@ module Make< ) } - predicate sourceLocalStep(SourceOutputNode nodeFrom, Node nodeTo, string model) { - exists(SummaryComponent sc, SourceElement source | + predicate sourceStep(SourceOutputNode nodeFrom, Node nodeTo, string model, boolean local) { + exists(SummaryComponentStack sc, SourceElement source | nodeFrom.isExit(source, sc, model) and - nodeTo = StepsInput::getSourceNode(source, sc) + nodeTo = StepsInput::getSourceNode(source, sc) and + if StepsInput::getSourceNodeEnclosingCallable(source) = getNodeEnclosingCallable(nodeTo) + then local = true + else local = false ) } + predicate sourceLocalStep(SourceOutputNode nodeFrom, Node nodeTo, string model) { + sourceStep(nodeFrom, nodeTo, model, true) + } + predicate sinkLocalStep(Node nodeFrom, SinkInputNode nodeTo, string model) { exists(SummaryComponent sc, SinkElement sink | nodeFrom = StepsInput::getSinkNode(sink, sc) and @@ -1689,6 +1699,10 @@ module Make< ) } + predicate sourceJumpStep(SourceOutputNode nodeFrom, Node nodeTo) { + sourceStep(nodeFrom, nodeTo, _, false) + } + /** * Holds if values stored inside content `c` are cleared at `n`. `n` is a * synthesized summary node, so in order for values to be cleared at calls From 7d6e2060e526419ac1f14cf127b7d8e42bbcacfe Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Wed, 17 Sep 2025 14:05:39 +0200 Subject: [PATCH 067/160] Adapt all languages to changes in shared library --- .../semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll | 4 +++- .../code/csharp/dataflow/internal/FlowSummaryImpl.qll | 6 ++++-- go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll | 4 +++- .../semmle/code/java/dataflow/internal/FlowSummaryImpl.qll | 6 ++++-- .../javascript/dataflow/internal/FlowSummaryPrivate.qll | 4 +++- .../semmle/python/dataflow/new/internal/FlowSummaryImpl.qll | 4 +++- .../lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll | 4 +++- .../lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll | 4 +++- 8 files changed, 26 insertions(+), 10 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll index 58c3dfdea16..d89ab06ed82 100644 --- a/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll @@ -104,7 +104,9 @@ private module StepsInput implements Impl::Private::StepsInputSig { result.getStaticCallTarget().getUnderlyingCallable() = sc } - Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() } + DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() } + + Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() } Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll index 90db68f7c93..3ee16f21489 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll @@ -183,7 +183,7 @@ private module TypesInput implements Impl::Private::TypesInputSig { ) } - DataFlowType getSourceType(Input::SourceBase source, Impl::Private::SummaryComponent sc) { + DataFlowType getSourceType(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() } @@ -195,7 +195,9 @@ private module StepsInput implements Impl::Private::StepsInputSig { sc = viableCallable(result).asSummarizedCallable() } - Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() } + DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() } + + Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() } Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() } } diff --git a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll index 35887d076c0..496870286e9 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/FlowSummaryImpl.qll @@ -117,7 +117,9 @@ private module StepsInput implements Impl::Private::StepsInputSig { ) } - Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() } + DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() } + + Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() } Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll index a2d25cadd88..8dc28ea2f60 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll @@ -132,7 +132,7 @@ private module TypesInput implements Impl::Private::TypesInputSig { exists(rk) } - DataFlowType getSourceType(Input::SourceBase source, Impl::Private::SummaryComponent sc) { + DataFlowType getSourceType(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() } @@ -144,7 +144,9 @@ private module StepsInput implements Impl::Private::StepsInputSig { sc = viableCallable(result).asSummarizedCallable() } - Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() } + DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() } + + Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() } Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() } } diff --git a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll index 6315b34b0a4..a5131e4fd64 100644 --- a/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll +++ b/javascript/ql/lib/semmle/javascript/dataflow/internal/FlowSummaryPrivate.qll @@ -150,7 +150,9 @@ private module FlowSummaryStepInput implements Private::StepsInputSig { ) } - DataFlow::Node getSourceNode(SourceBase source, Private::SummaryComponent sc) { none() } + DataFlowCallable getSourceNodeEnclosingCallable(SourceBase source) { none() } + + DataFlow::Node getSourceNode(SourceBase source, Private::SummaryComponentStack s) { none() } DataFlow::Node getSinkNode(SinkBase sink, Private::SummaryComponent sc) { none() } } diff --git a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll index f7fdf84549e..396154c06ee 100644 --- a/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll +++ b/python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll @@ -105,7 +105,9 @@ private module StepsInput implements Impl::Private::StepsInputSig { ]) } - Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() } + DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() } + + Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() } Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() } } diff --git a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll index c85d2230b23..f8e3894a833 100644 --- a/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll +++ b/ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll @@ -161,7 +161,9 @@ private module StepsInput implements Impl::Private::StepsInputSig { result.asCall().getAstNode() = sc.(LibraryCallable).getACallSimple() } - Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() } + DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() } + + Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() } Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() } } diff --git a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll index cb889baaebc..46e2e63f2ca 100644 --- a/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll +++ b/swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll @@ -113,7 +113,9 @@ private import Make as Imp private module StepsInput implements Impl::Private::StepsInputSig { DataFlowCall getACall(Public::SummarizedCallable sc) { result.asCall().getStaticTarget() = sc } - Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) { none() } + DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() } + + Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() } Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { none() } } From a4c61f69456415bdcf18b837d4adbe15e0bc6adf Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Thu, 18 Sep 2025 16:01:07 +0200 Subject: [PATCH 068/160] Rust: Accept test changes --- .../PathResolutionConsistency.expected | 2 +- .../dataflow/models/models.expected | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/models/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/library-tests/dataflow/models/CONSISTENCY/PathResolutionConsistency.expected index ebe4e66e6e2..7db15783781 100644 --- a/rust/ql/test/library-tests/dataflow/models/CONSISTENCY/PathResolutionConsistency.expected +++ b/rust/ql/test/library-tests/dataflow/models/CONSISTENCY/PathResolutionConsistency.expected @@ -1,2 +1,2 @@ multipleCallTargets -| main.rs:362:14:362:30 | ... .lt(...) | +| main.rs:389:14:389:30 | ... .lt(...) | diff --git a/rust/ql/test/library-tests/dataflow/models/models.expected b/rust/ql/test/library-tests/dataflow/models/models.expected index 2918e5c3c39..955b0b81b44 100644 --- a/rust/ql/test/library-tests/dataflow/models/models.expected +++ b/rust/ql/test/library-tests/dataflow/models/models.expected @@ -233,18 +233,18 @@ edges | main.rs:247:35:247:35 | i | main.rs:247:47:247:47 | i | provenance | | | main.rs:261:18:261:18 | ... | main.rs:261:26:261:26 | a | provenance | | | main.rs:261:18:261:18 | ... | main.rs:261:26:261:26 | a | provenance | | -| main.rs:262:9:262:19 | pass_source | main.rs:261:18:261:18 | ... | provenance | Src:MaD:8 MaD:8 | -| main.rs:262:9:262:19 | pass_source | main.rs:261:18:261:18 | ... | provenance | Src:MaD:8 MaD:8 | -| main.rs:264:9:264:19 | pass_source | main.rs:264:25:264:25 | ... | provenance | Src:MaD:8 MaD:8 | -| main.rs:264:9:264:19 | pass_source | main.rs:264:25:264:25 | ... | provenance | Src:MaD:8 MaD:8 | +| main.rs:262:9:262:19 | pass_source | main.rs:261:18:261:18 | ... | provenance | Src:MaD:8 | +| main.rs:262:9:262:19 | pass_source | main.rs:261:18:261:18 | ... | provenance | Src:MaD:8 | +| main.rs:264:9:264:19 | pass_source | main.rs:264:25:264:25 | ... | provenance | Src:MaD:8 | +| main.rs:264:9:264:19 | pass_source | main.rs:264:25:264:25 | ... | provenance | Src:MaD:8 | | main.rs:264:25:264:25 | ... | main.rs:265:18:265:18 | a | provenance | | | main.rs:264:25:264:25 | ... | main.rs:265:18:265:18 | a | provenance | | | main.rs:268:14:268:19 | ...: i64 | main.rs:269:18:269:18 | a | provenance | | | main.rs:268:14:268:19 | ...: i64 | main.rs:269:18:269:18 | a | provenance | | -| main.rs:271:9:271:19 | pass_source | main.rs:268:14:268:19 | ...: i64 | provenance | Src:MaD:8 MaD:8 | -| main.rs:271:9:271:19 | pass_source | main.rs:268:14:268:19 | ...: i64 | provenance | Src:MaD:8 MaD:8 | -| main.rs:273:9:273:19 | pass_source | main.rs:273:36:273:36 | ... | provenance | Src:MaD:8 MaD:8 | -| main.rs:273:9:273:19 | pass_source | main.rs:273:36:273:36 | ... | provenance | Src:MaD:8 MaD:8 | +| main.rs:271:9:271:19 | pass_source | main.rs:268:14:268:19 | ...: i64 | provenance | Src:MaD:8 | +| main.rs:271:9:271:19 | pass_source | main.rs:268:14:268:19 | ...: i64 | provenance | Src:MaD:8 | +| main.rs:273:9:273:19 | pass_source | main.rs:273:36:273:36 | ... | provenance | Src:MaD:8 | +| main.rs:273:9:273:19 | pass_source | main.rs:273:36:273:36 | ... | provenance | Src:MaD:8 | | main.rs:273:36:273:36 | ... | main.rs:274:18:274:18 | a | provenance | | | main.rs:273:36:273:36 | ... | main.rs:274:18:274:18 | a | provenance | | | main.rs:283:9:283:9 | s | main.rs:284:41:284:41 | s | provenance | | From 4244a6569c53e3f3b2fdf270769bbe23d2d84f22 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Fri, 19 Sep 2025 09:19:17 +0200 Subject: [PATCH 069/160] Rust: Add change note --- rust/ql/lib/change-notes/2025-09-19-parameter-mad.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 rust/ql/lib/change-notes/2025-09-19-parameter-mad.md diff --git a/rust/ql/lib/change-notes/2025-09-19-parameter-mad.md b/rust/ql/lib/change-notes/2025-09-19-parameter-mad.md new file mode 100644 index 00000000000..06f664a5213 --- /dev/null +++ b/rust/ql/lib/change-notes/2025-09-19-parameter-mad.md @@ -0,0 +1,7 @@ +--- +category: feature +--- +* The models-as-data format for sources now supports access paths of the form + `Argument[i].Parameter[j]`. This denotes that the source passes tainted data to + the `j`th parameter of it's `i`th argument (which must be a function or a + closure). \ No newline at end of file From 45b84ffb3195f7b0069494624cd47e805c539872 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Mon, 22 Sep 2025 14:23:50 +0200 Subject: [PATCH 070/160] Rust: Ensure singleton --- rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll | 4 ++-- shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll index 129bd468e01..2763908ae02 100644 --- a/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll +++ b/rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll @@ -168,12 +168,12 @@ private module StepsInput implements Impl::Private::StepsInputSig { or exists(ArgumentPosition pos, Expr arg | s.head() = Impl::Private::SummaryComponent::parameter(pos) and - arg = getSourceNodeArgument(source, s.tail().head()) and + arg = getSourceNodeArgument(source, s.tail().headOfSingleton()) and result.asParameter() = getCallable(arg).getParam(pos.getPosition()) ) or result.(RustDataFlow::PostUpdateNode).getPreUpdateNode().asExpr().getExpr() = - getSourceNodeArgument(source, s.head()) + getSourceNodeArgument(source, s.headOfSingleton()) } RustDataFlow::Node getSinkNode(Input::SinkBase sink, Impl::Private::SummaryComponent sc) { diff --git a/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll b/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll index 9c46e04bf4b..6cc9d6f88a4 100644 --- a/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll +++ b/shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll @@ -709,6 +709,9 @@ module Make< this = TConsSummaryComponentStack(result, _) } + /** Gets the head of this stack if it is a singleton. */ + SummaryComponent headOfSingleton() { this = TSingletonSummaryComponentStack(result) } + /** Gets the tail of this stack, if any. */ SummaryComponentStack tail() { this = TConsSummaryComponentStack(_, result) } From b837c56bec5a598bdd951e30e998e449f8f19305 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Mon, 22 Sep 2025 10:13:33 -0400 Subject: [PATCH 071/160] Refactor RootApi and GrapeApiClass constructors for improved readability; add getHelperSelf method to retrieve self parameter in helpers block. --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 39 +++++++++++--------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index 4e178792572..95aa42fdfad 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -25,9 +25,7 @@ module Grape { * In other words, it does not subclass any other Grape API class in source code. */ class RootApi extends GrapeApiClass { - RootApi() { - not this = any(GrapeApiClass parent).getAnImmediateDescendent() - } + RootApi() { not this = any(GrapeApiClass parent).getAnImmediateDescendent() } } /** @@ -44,9 +42,7 @@ module Grape { * ``` */ class GrapeApiClass extends DataFlow::ClassNode { - GrapeApiClass() { - this = grapeApiBaseClass().getADescendentModule() - } + GrapeApiClass() { this = grapeApiBaseClass().getADescendentModule() } /** * Gets a `GrapeEndpoint` defined in this class. @@ -63,6 +59,20 @@ module Grape { // is invoked with an instance as the `self`. result = this.getModuleLevelSelf() } + + /** + * Gets the `self` parameter belonging to a method defined within a + * `helpers` block in this API class. + * + * These methods become available in endpoint contexts through Grape's DSL. + */ + DataFlow::SelfParameterNode getHelperSelf() { + exists(DataFlow::CallNode helpersCall | + helpersCall = this.getAModuleLevelCall("helpers") and + result.getSelfVariable().getDeclaringScope().getOuterScope+() = + helpersCall.getBlock().asExpr().getExpr() + ) + } } private DataFlow::ConstRef grapeApiBaseClass() { @@ -122,17 +132,12 @@ module Grape { */ private class GrapeParamsCall extends ParamsCallImpl { GrapeParamsCall() { - // Params calls within endpoint blocks - exists(GrapeApiClass api | - this.getMethodName() = "params" and - this.getParent+() = api.getADeclaration() - ) - or - // Params calls within helper methods (defined in helpers blocks) - exists(GrapeApiClass api, DataFlow::CallNode helpersCall | - helpersCall = api.getAModuleLevelCall("helpers") and - this.getMethodName() = "params" and - this.getParent+() = helpersCall.getBlock().asExpr().getExpr() + exists(API::Node n | this = n.getAMethodCall("params").asExpr().getExpr() | + // Params calls within endpoint blocks + n = grapeApiInstance() + or + // Params calls within helper methods (defined in helpers blocks) + n = any(GrapeApiClass c).getHelperSelf().track() ) } } From 513ae2ab54ec75a62d73d9912b156a4ed8282919 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 9 Sep 2025 18:05:27 +0100 Subject: [PATCH 072/160] Rust: Add tests for insecure cookies. --- .../query-tests/security/CWE-614/Cargo.lock | 684 ++++++++++++++++++ .../test/query-tests/security/CWE-614/main.rs | 174 +++++ .../query-tests/security/CWE-614/options.yml | 4 + 3 files changed, 862 insertions(+) create mode 100644 rust/ql/test/query-tests/security/CWE-614/Cargo.lock create mode 100644 rust/ql/test/query-tests/security/CWE-614/main.rs create mode 100644 rust/ql/test/query-tests/security/CWE-614/options.yml diff --git a/rust/ql/test/query-tests/security/CWE-614/Cargo.lock b/rust/ql/test/query-tests/security/CWE-614/Cargo.lock new file mode 100644 index 00000000000..1d2124de710 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/Cargo.lock @@ -0,0 +1,684 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "anyhow" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "biscotti" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddb6f28a3d15d18cace7a8010282a4d9cee1452dcd33f5861c173b4a31095b79" +dependencies = [ + "aes-gcm-siv", + "anyhow", + "base64", + "hkdf", + "hmac", + "jiff", + "percent-encoding", + "rand 0.9.2", + "serde", + "sha2", + "subtle", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "aes-gcm", + "base64", + "hmac", + "percent-encoding", + "rand 0.8.5", + "sha2", + "subtle", + "time", + "version_check", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "deranged" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.5+wasi-0.2.4", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "jiff" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +dependencies = [ + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", + "windows-sys", +] + +[[package]] +name = "jiff-static" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "test" +version = "0.0.1" +dependencies = [ + "biscotti", + "cookie", +] + +[[package]] +name = "time" +version = "0.3.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.5+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4494f6290a82f5fe584817a676a34b9d6763e8d9d18204009fb31dceca98fd4" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.0+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03fa2761397e5bd52002cd7e73110c71af2109aca4e521a9f40473fe685b0a24" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen" +version = "0.45.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs new file mode 100644 index 00000000000..da11fa5e5bc --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -0,0 +1,174 @@ +use cookie::{Cookie, CookieBuilder, CookieJar, Key}; + +fn test_cookie(sometimes: bool) { + let always = true; + let never = false; + + // secure set to false + let cookie1 = Cookie::build(("name", "value")).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + println!("cookie1 = '{}'", cookie1.to_string()); + + // secure set to true + let cookie2 = Cookie::build(("name", "value")).secure(true).build(); // good + println!("cookie2 = '{}'", cookie2.to_string()); + + // secure left as default (which is `None`, equivalent here to `false`) + let cookie3 = Cookie::build(("name", "value")).build(); // $ MISSING: Alert[rust/insecure-cookie] + println!("cookie3 = '{}'", cookie3.to_string()); + + // secure setting varies (may be false) + Cookie::build(("name", "value")).secure(sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(!sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] + + // with data flow on the "secure" value + Cookie::build(("name", "value")).secure(always).build(); // good + Cookie::build(("name", "value")).secure(!always).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(never).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(!never).build(); // good + Cookie::build(("name", "value")).secure(always && never).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(always || never).build(); // good + + // with guards + if sometimes { + Cookie::build(("name", "value")).secure(sometimes).build(); // good + } else { + Cookie::build(("name", "value")).secure(sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] + } + + // variant uses (all insecure) + CookieBuilder::new("name", "value").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).expires(None).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).max_age(cookie::time::Duration::hours(12)).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).domain("example.com").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).path("/").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).http_only(true).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).same_site(cookie::SameSite::Strict).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).permanent().secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).removal().secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(false).finish(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build("name").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(Cookie::build("name")).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + + // edge cases + Cookie::build(("name", "value")).secure(true).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(false).secure(true).build(); // good + + // mutable cookie + let mut jar = CookieJar::new(); + let mut a = Cookie::new("name", "value"); + jar.add(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + a.set_secure(true); + jar.add(a.clone()); // good + a.set_secure(false); + jar.add(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + + let key = Key::generate(); + let mut signed_jar = jar.signed_mut(&key); + let mut b = Cookie::named("name"); + signed_jar.add(b.clone()); // $ MISSING: Alert[rust/insecure-cookie] + signed_jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + b.set_secure(sometimes); + signed_jar.add(b.clone()); // $ MISSING: Alert[rust/insecure-cookie] + b.set_secure(true); + signed_jar.add(b.clone()); // good + + let mut private_jar = jar.private_mut(&key); + let mut c = Cookie::from("name"); + private_jar.add(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] + private_jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + if sometimes { + c.set_secure(true); + } + private_jar.add(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] + c.set_secure(true); + private_jar.add(c.clone()); // good + + let mut d = Cookie::from("name"); + jar.add(d.clone()); // $ MISSING: Alert[rust/insecure-cookie] + if sometimes { + c.set_secure(true); + } else { + c.set_partitioned(true); + } + jar.add(d.clone()); // good + + // parse + jar.add(Cookie::parse("name=value; HttpOnly").unwrap()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add(Cookie::parse("name=value; Secure; HttpOnly").unwrap()); // good + jar.add(Cookie::parse_encoded("name=value; HttpOnly").unwrap()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add(Cookie::parse_encoded("name=value; Secure; HttpOnly").unwrap()); // good + + for cookie in Cookie::split_parse("name1=value1; name2=value2") { + jar.add(cookie.unwrap()); // $ MISSING: Alert[rust/insecure-cookie] + } + + for cookie in Cookie::split_parse_encoded("name1=value1; name2=value2") { + let mut e = cookie.unwrap(); + jar.add(e.clone()); // $ MISSING: Alert[rust/insecure-cookie] + e.set_secure(true); + jar.add(e.clone()); // good + } + + // partitioned (implies secure) + Cookie::build(("name", "value")).partitioned(true).build(); // good +} + +fn test_biscotti() { + let mut cookies = biscotti::ResponseCookies::new(); + + // test set_secure, set_partitioned + + let a = biscotti::ResponseCookie::new("name", "value"); + cookies.insert(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + println!("biscotti1 = {}", a.to_string()); + + let b = a.set_secure(true); + cookies.insert(b.clone()); // good (secure) + println!("biscotti2 = {}", b.to_string()); + + let c = b.set_secure(false); + cookies.insert(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] + println!("biscotti3 = {}", c.to_string()); + + let d = c.set_partitioned(true); // (implies secure) + cookies.insert(d.clone()); // good (partitioned) + println!("biscotti4 = {}", d.to_string()); + + let e = d.set_secure(true); + cookies.insert(e.clone()); // good (partitioned + secure) + println!("biscotti5 = {}", e.to_string()); + + let f = e.set_partitioned(false); + cookies.insert(f.clone()); // good (secure) + println!("biscotti6 = {}", f.to_string()); + + let g = f.set_secure(false); + cookies.insert(g.clone()); // $ MISSING: Alert[rust/insecure-cookie] + println!("biscotti7 = {}", g.to_string()); + + // variant creation (insecure) + let h = biscotti::ResponseCookie::from(("name", "value")); + cookies.insert(h); // $ MISSING: Alert[rust/insecure-cookie] + + // variant uses (all insecure) + let i = biscotti::ResponseCookie::new("name", "value"); + cookies.insert(i.clone().set_name("name2")); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_value("value2")); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_http_only(true)); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_same_site(biscotti::SameSite::Strict)); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_max_age(None)); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_path("/")); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_path()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_domain("example.com")); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_domain()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_expires(None)); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_expires()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().make_permanent()); // $ MISSING: Alert[rust/insecure-cookie] +} + +fn main() { + test_cookie(true); + test_cookie(false); + test_biscotti(); +} diff --git a/rust/ql/test/query-tests/security/CWE-614/options.yml b/rust/ql/test/query-tests/security/CWE-614/options.yml new file mode 100644 index 00000000000..99b8e37e843 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/options.yml @@ -0,0 +1,4 @@ +qltest_cargo_check: true +qltest_dependencies: + - cookie = { version = "0.18.1", features = ["percent-encode", "signed", "private"] } + - biscotti = { version = "0.4.3" } From 7e75c1d24257c340e2ff8030c516c4820f5b254d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 11 Sep 2025 11:17:05 +0100 Subject: [PATCH 073/160] Rust: Add very basic query prototype. --- .../security/CWE-614/InsecureCookie.ql | 48 +++++++++++++++++++ .../security/CWE-614/InsecureCookie.expected | 6 +++ .../security/CWE-614/InsecureCookie.qlref | 4 ++ .../test/query-tests/security/CWE-614/main.rs | 2 +- 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 rust/ql/src/queries/security/CWE-614/InsecureCookie.ql create mode 100644 rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected create mode 100644 rust/ql/test/query-tests/security/CWE-614/InsecureCookie.qlref diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql new file mode 100644 index 00000000000..4d659d95a95 --- /dev/null +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -0,0 +1,48 @@ +/** + * @name 'Secure' attribute is not set to true + * @description Omitting the 'Secure' attribute allows data to be transmitted insecurely + * using HTTP. Always set 'Secure' to 'true' to ensure that HTTPS + * is used at all times. + * @kind problem + * @problem.severity error + * @precision high + * @id rust/insecure-cookie + * @tags security + * external/cwe/cwe-319 + * external/cwe/cwe-614 + */ + +import rust +import codeql.rust.dataflow.DataFlow +import codeql.rust.dataflow.TaintTracking +import InsecureCookieFlow::PathGraph + +/** + * A data flow configuration for tracking values representing cookies without the + * 'secure' flag set. + */ +module InsecureCookieConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { + // creation of a cookie with default settings (insecure) + exists(CallExprBase ce | + ce.getStaticTarget().getCanonicalPath() = "::build" and + node.asExpr().getExpr() = ce + ) + } + + predicate isSink(DataFlow::Node node) { + // qualifier of a call to `.build`. + exists(MethodCallExpr ce | + ce.getStaticTarget().getCanonicalPath() = "::build" and + node.asExpr().getExpr() = ce.getReceiver() + ) + } + + predicate observeDiffInformedIncrementalMode() { any() } +} + +module InsecureCookieFlow = TaintTracking::Global; + +from InsecureCookieFlow::PathNode sourceNode, InsecureCookieFlow::PathNode sinkNode +where InsecureCookieFlow::flowPath(sourceNode, sinkNode) +select sinkNode.getNode(), sourceNode, sinkNode, "Cookie attribute 'Secure' is not set to true." diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected new file mode 100644 index 00000000000..2f900fc34dc --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -0,0 +1,6 @@ +#select +| main.rs:16:19:16:50 | ...::build(...) | main.rs:16:19:16:50 | ...::build(...) | main.rs:16:19:16:50 | ...::build(...) | Cookie attribute 'Secure' is not set to true. | +edges +nodes +| main.rs:16:19:16:50 | ...::build(...) | semmle.label | ...::build(...) | +subpaths diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.qlref b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.qlref new file mode 100644 index 00000000000..36a9751434c --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.qlref @@ -0,0 +1,4 @@ +query: queries/security/CWE-614/InsecureCookie.ql +postprocess: + - utils/test/PrettyPrintModels.ql + - utils/test/InlineExpectationsTestQuery.ql diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index da11fa5e5bc..6ef4cc3c83b 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -13,7 +13,7 @@ fn test_cookie(sometimes: bool) { println!("cookie2 = '{}'", cookie2.to_string()); // secure left as default (which is `None`, equivalent here to `false`) - let cookie3 = Cookie::build(("name", "value")).build(); // $ MISSING: Alert[rust/insecure-cookie] + let cookie3 = Cookie::build(("name", "value")).build(); // $ Alert[rust/insecure-cookie] println!("cookie3 = '{}'", cookie3.to_string()); // secure setting varies (may be false) From d52b6681497071cb89cd27378a884f6ecc33cb87 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 11 Sep 2025 11:22:46 +0100 Subject: [PATCH 074/160] Rust: Add security-severity tag. --- rust/ql/src/queries/security/CWE-614/InsecureCookie.ql | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index 4d659d95a95..f14af7752fd 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -5,6 +5,7 @@ * is used at all times. * @kind problem * @problem.severity error + * @security-severity 7.5 * @precision high * @id rust/insecure-cookie * @tags security From eadf922280a7ddf7004fccf9802b1d07d66f8bae Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 15 Sep 2025 09:24:16 +0100 Subject: [PATCH 075/160] Rust: Use models-as-data, add source/sink/flow models. --- .../codeql/rust/frameworks/biscotti.model.yml | 25 + .../codeql/rust/frameworks/cookie.model.yml | 33 + .../security/CWE-614/InsecureCookie.ql | 19 +- .../security/CWE-614/InsecureCookie.expected | 636 +++++++++++++++++- .../test/query-tests/security/CWE-614/main.rs | 122 ++-- 5 files changed, 762 insertions(+), 73 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml b/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml index c99a2433348..b70a27f74d1 100644 --- a/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml @@ -1,7 +1,32 @@ # Models for the `biscotti` crate. extensions: + - addsTo: + pack: codeql/rust-all + extensible: sourceModel + data: + - ["::new", "ReturnValue", "cookie-create", "manual"] + - ["::from", "ReturnValue", "cookie-create", "manual"] - addsTo: pack: codeql/rust-all extensible: sinkModel data: + - ["::insert", "Argument[0]", "cookie-use", "manual"] - ["::from", "Argument[0]", "credentials-key", "manual"] + - addsTo: + pack: codeql/rust-all + extensible: summaryModel + data: + - ["::set_secure", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_name", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_value", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_http_only", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_same_site", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_max_age", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_path", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::unset_path", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_domain", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::unset_domain", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_expires", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::unset_expires", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::make_permanent", "Argument[self]", "ReturnValue", "taint", "manual"] diff --git a/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml b/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml index abbadd379e6..f9c8cd647c5 100644 --- a/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml @@ -1,7 +1,40 @@ # Models for the `cookie` crate. extensions: + - addsTo: + pack: codeql/rust-all + extensible: sourceModel + data: + - ["::build", "ReturnValue", "cookie-create", "manual"] + - ["::new", "ReturnValue", "cookie-create", "manual"] + - ["::new", "ReturnValue", "cookie-create", "manual"] + - ["::named", "ReturnValue", "cookie-create", "manual"] + - ["::from", "ReturnValue", "cookie-create", "manual"] - addsTo: pack: codeql/rust-all extensible: sinkModel data: + - ["::build", "Argument[self]", "cookie-use", "manual"] + - ["::finish", "Argument[self]", "cookie-use", "manual"] + - ["::add", "Argument[0]", "cookie-use", "manual"] + - ["::add_original", "Argument[0]", "cookie-use", "manual"] + - ["::add", "Argument[0]", "cookie-use", "manual"] + - ["::add_original", "Argument[0]", "cookie-use", "manual"] + - ["::add", "Argument[0]", "cookie-use", "manual"] + - ["::add_original", "Argument[0]", "cookie-use", "manual"] - ["::from", "Argument[0].Reference", "credentials-key", "manual"] + - addsTo: + pack: codeql/rust-all + extensible: summaryModel + data: + - ["::secure", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::expires", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::max_age", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::domain", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::path", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::http_only", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::same_site", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::permanent", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::removal", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_secure", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index f14af7752fd..69d11b85bef 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -16,7 +16,8 @@ import rust import codeql.rust.dataflow.DataFlow import codeql.rust.dataflow.TaintTracking -import InsecureCookieFlow::PathGraph +import codeql.rust.dataflow.FlowSource +import codeql.rust.dataflow.FlowSink /** * A data flow configuration for tracking values representing cookies without the @@ -24,19 +25,13 @@ import InsecureCookieFlow::PathGraph */ module InsecureCookieConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { - // creation of a cookie with default settings (insecure) - exists(CallExprBase ce | - ce.getStaticTarget().getCanonicalPath() = "::build" and - node.asExpr().getExpr() = ce - ) + // creation of a cookie or cookie configuration with default, insecure settings + sourceNode(node, "cookie-create") } predicate isSink(DataFlow::Node node) { - // qualifier of a call to `.build`. - exists(MethodCallExpr ce | - ce.getStaticTarget().getCanonicalPath() = "::build" and - node.asExpr().getExpr() = ce.getReceiver() - ) + // use of a cookie or cookie configuration + sinkNode(node, "cookie-use") } predicate observeDiffInformedIncrementalMode() { any() } @@ -44,6 +39,8 @@ module InsecureCookieConfig implements DataFlow::ConfigSig { module InsecureCookieFlow = TaintTracking::Global; +import InsecureCookieFlow::PathGraph + from InsecureCookieFlow::PathNode sourceNode, InsecureCookieFlow::PathNode sinkNode where InsecureCookieFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "Cookie attribute 'Secure' is not set to true." diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected index 2f900fc34dc..b4bd897ca6f 100644 --- a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -1,6 +1,640 @@ #select -| main.rs:16:19:16:50 | ...::build(...) | main.rs:16:19:16:50 | ...::build(...) | main.rs:16:19:16:50 | ...::build(...) | Cookie attribute 'Secure' is not set to true. | +| main.rs:8:66:8:70 | build | main.rs:8:19:8:31 | ...::build | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:12:65:12:69 | build | main.rs:12:19:12:31 | ...::build | main.rs:12:65:12:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:16:52:16:56 | build | main.rs:16:19:16:31 | ...::build | main.rs:16:52:16:56 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:20:56:20:60 | build | main.rs:20:5:20:17 | ...::build | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:21:57:21:61 | build | main.rs:21:5:21:17 | ...::build | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:24:53:24:57 | build | main.rs:24:5:24:17 | ...::build | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:25:54:25:58 | build | main.rs:25:5:25:17 | ...::build | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:26:52:26:56 | build | main.rs:26:5:26:17 | ...::build | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:27:53:27:57 | build | main.rs:27:5:27:17 | ...::build | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:28:62:28:66 | build | main.rs:28:5:28:17 | ...::build | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:29:62:29:66 | build | main.rs:29:5:29:17 | ...::build | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:33:60:33:64 | build | main.rs:33:9:33:21 | ...::build | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:35:60:35:64 | build | main.rs:35:9:35:21 | ...::build | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:39:55:39:59 | build | main.rs:39:5:39:22 | ...::new | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:40:66:40:70 | build | main.rs:40:5:40:17 | ...::build | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:41:95:41:99 | build | main.rs:41:5:41:17 | ...::build | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:42:74:42:78 | build | main.rs:42:5:42:17 | ...::build | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:43:62:43:66 | build | main.rs:43:5:43:17 | ...::build | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:44:68:44:72 | build | main.rs:44:5:44:17 | ...::build | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:45:88:45:92 | build | main.rs:45:5:45:17 | ...::build | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:46:64:46:68 | build | main.rs:46:5:46:17 | ...::build | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:47:62:47:66 | build | main.rs:47:5:47:17 | ...::build | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:48:52:48:57 | finish | main.rs:48:5:48:17 | ...::build | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | +| main.rs:49:41:49:45 | build | main.rs:49:5:49:17 | ...::build | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:50:56:50:60 | build | main.rs:50:5:50:17 | ...::build | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:53:65:53:69 | build | main.rs:53:5:53:17 | ...::build | main.rs:53:65:53:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:54:65:54:69 | build | main.rs:54:5:54:17 | ...::build | main.rs:54:65:54:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:59:9:59:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:59:9:59:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:60:9:60:20 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:60:9:60:20 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:62:9:62:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:62:9:62:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:64:9:64:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:64:9:64:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:69:16:69:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:69:16:69:18 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:70:16:70:27 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:70:16:70:27 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:72:16:72:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:72:16:72:18 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:74:16:74:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:74:16:74:18 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:78:17:78:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:78:17:78:19 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:79:17:79:28 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:79:17:79:28 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:83:17:83:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:83:17:83:19 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:85:17:85:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:85:17:85:19 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:88:9:88:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:88:9:88:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:94:9:94:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:94:9:94:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:114:56:114:60 | build | main.rs:114:5:114:17 | ...::build | main.rs:114:56:114:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:123:13:123:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:123:13:123:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:127:13:127:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:127:13:127:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:131:13:131:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:131:13:131:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:135:13:135:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:135:13:135:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:139:13:139:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:139:13:139:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:143:13:143:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:143:13:143:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:147:13:147:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:147:13:147:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:152:13:152:18 | insert | main.rs:151:13:151:42 | ...::from | main.rs:152:13:152:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:156:13:156:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:156:13:156:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:157:13:157:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:157:13:157:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:158:13:158:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:158:13:158:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:159:13:159:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:159:13:159:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:160:13:160:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:160:13:160:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:161:13:161:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:161:13:161:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:162:13:162:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:162:13:162:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:163:13:163:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:163:13:163:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:164:13:164:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:164:13:164:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:165:13:165:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:165:13:165:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:166:13:166:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:166:13:166:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:167:13:167:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:167:13:167:18 | insert | Cookie attribute 'Secure' is not set to true. | edges +| main.rs:8:19:8:31 | ...::build | main.rs:8:19:8:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:41 | +| main.rs:8:19:8:64 | ... .secure(...) | main.rs:8:66:8:70 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:12:19:12:31 | ...::build | main.rs:12:19:12:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:12:19:12:50 | ...::build(...) | main.rs:12:19:12:63 | ... .secure(...) | provenance | MaD:41 | +| main.rs:12:19:12:63 | ... .secure(...) | main.rs:12:65:12:69 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:16:19:16:31 | ...::build | main.rs:16:19:16:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:16:19:16:50 | ...::build(...) | main.rs:16:52:16:56 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:20:5:20:17 | ...::build | main.rs:20:5:20:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:20:5:20:36 | ...::build(...) | main.rs:20:5:20:54 | ... .secure(...) | provenance | MaD:41 | +| main.rs:20:5:20:54 | ... .secure(...) | main.rs:20:56:20:60 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:21:5:21:17 | ...::build | main.rs:21:5:21:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:41 | +| main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:24:5:24:17 | ...::build | main.rs:24:5:24:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:41 | +| main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:25:5:25:17 | ...::build | main.rs:25:5:25:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:41 | +| main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:26:5:26:17 | ...::build | main.rs:26:5:26:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:26:5:26:36 | ...::build(...) | main.rs:26:5:26:50 | ... .secure(...) | provenance | MaD:41 | +| main.rs:26:5:26:50 | ... .secure(...) | main.rs:26:52:26:56 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:27:5:27:17 | ...::build | main.rs:27:5:27:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:27:5:27:36 | ...::build(...) | main.rs:27:5:27:51 | ... .secure(...) | provenance | MaD:41 | +| main.rs:27:5:27:51 | ... .secure(...) | main.rs:27:53:27:57 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:28:5:28:17 | ...::build | main.rs:28:5:28:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:28:5:28:36 | ...::build(...) | main.rs:28:5:28:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:28:5:28:60 | ... .secure(...) | main.rs:28:62:28:66 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:29:5:29:17 | ...::build | main.rs:29:5:29:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:29:5:29:36 | ...::build(...) | main.rs:29:5:29:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:29:5:29:60 | ... .secure(...) | main.rs:29:62:29:66 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:33:9:33:21 | ...::build | main.rs:33:9:33:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:33:9:33:40 | ...::build(...) | main.rs:33:9:33:58 | ... .secure(...) | provenance | MaD:41 | +| main.rs:33:9:33:58 | ... .secure(...) | main.rs:33:60:33:64 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:35:9:35:21 | ...::build | main.rs:35:9:35:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:35:9:35:40 | ...::build(...) | main.rs:35:9:35:58 | ... .secure(...) | provenance | MaD:41 | +| main.rs:35:9:35:58 | ... .secure(...) | main.rs:35:60:35:64 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:39:5:39:22 | ...::new | main.rs:39:5:39:39 | ...::new(...) | provenance | Src:MaD:16 MaD:16 | +| main.rs:39:5:39:39 | ...::new(...) | main.rs:39:5:39:53 | ... .secure(...) | provenance | MaD:41 | +| main.rs:39:5:39:53 | ... .secure(...) | main.rs:39:55:39:59 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:40:5:40:17 | ...::build | main.rs:40:5:40:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:40:5:40:36 | ...::build(...) | main.rs:40:5:40:50 | ... .expires(...) | provenance | MaD:33 | +| main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:5:40:64 | ... .secure(...) | provenance | MaD:41 | +| main.rs:40:5:40:64 | ... .secure(...) | main.rs:40:66:40:70 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:41:5:41:17 | ...::build | main.rs:41:5:41:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:41:5:41:36 | ...::build(...) | main.rs:41:5:41:79 | ... .max_age(...) | provenance | MaD:35 | +| main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:5:41:93 | ... .secure(...) | provenance | MaD:41 | +| main.rs:41:5:41:93 | ... .secure(...) | main.rs:41:95:41:99 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:42:5:42:17 | ...::build | main.rs:42:5:42:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:42:5:42:36 | ...::build(...) | main.rs:42:5:42:58 | ... .domain(...) | provenance | MaD:32 | +| main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:5:42:72 | ... .secure(...) | provenance | MaD:41 | +| main.rs:42:5:42:72 | ... .secure(...) | main.rs:42:74:42:78 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:43:5:43:17 | ...::build | main.rs:43:5:43:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:43:5:43:36 | ...::build(...) | main.rs:43:5:43:46 | ... .path(...) | provenance | MaD:37 | +| main.rs:43:5:43:46 | ... .path(...) | main.rs:43:5:43:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:43:5:43:60 | ... .secure(...) | main.rs:43:62:43:66 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:44:5:44:17 | ...::build | main.rs:44:5:44:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:44:5:44:36 | ...::build(...) | main.rs:44:5:44:52 | ... .http_only(...) | provenance | MaD:34 | +| main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:5:44:66 | ... .secure(...) | provenance | MaD:41 | +| main.rs:44:5:44:66 | ... .secure(...) | main.rs:44:68:44:72 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:45:5:45:17 | ...::build | main.rs:45:5:45:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:45:5:45:36 | ...::build(...) | main.rs:45:5:45:72 | ... .same_site(...) | provenance | MaD:40 | +| main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:5:45:86 | ... .secure(...) | provenance | MaD:41 | +| main.rs:45:5:45:86 | ... .secure(...) | main.rs:45:88:45:92 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:46:5:46:17 | ...::build | main.rs:46:5:46:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:46:5:46:36 | ...::build(...) | main.rs:46:5:46:48 | ... .permanent() | provenance | MaD:38 | +| main.rs:46:5:46:48 | ... .permanent() | main.rs:46:5:46:62 | ... .secure(...) | provenance | MaD:41 | +| main.rs:46:5:46:62 | ... .secure(...) | main.rs:46:64:46:68 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:47:5:47:17 | ...::build | main.rs:47:5:47:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:47:5:47:36 | ...::build(...) | main.rs:47:5:47:46 | ... .removal() | provenance | MaD:39 | +| main.rs:47:5:47:46 | ... .removal() | main.rs:47:5:47:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:47:5:47:60 | ... .secure(...) | main.rs:47:62:47:66 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:48:5:48:17 | ...::build | main.rs:48:5:48:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:48:5:48:36 | ...::build(...) | main.rs:48:5:48:50 | ... .secure(...) | provenance | MaD:41 | +| main.rs:48:5:48:50 | ... .secure(...) | main.rs:48:52:48:57 | finish | provenance | MaD:3 Sink:MaD:3 | +| main.rs:49:5:49:17 | ...::build | main.rs:49:5:49:25 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:49:5:49:25 | ...::build(...) | main.rs:49:5:49:39 | ... .secure(...) | provenance | MaD:41 | +| main.rs:49:5:49:39 | ... .secure(...) | main.rs:49:41:49:45 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:50:5:50:17 | ...::build | main.rs:50:5:50:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:50:5:50:40 | ...::build(...) | main.rs:50:5:50:54 | ... .secure(...) | provenance | MaD:41 | +| main.rs:50:5:50:54 | ... .secure(...) | main.rs:50:56:50:60 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:53:5:53:17 | ...::build | main.rs:53:5:53:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:53:5:53:36 | ...::build(...) | main.rs:53:5:53:49 | ... .secure(...) | provenance | MaD:41 | +| main.rs:53:5:53:49 | ... .secure(...) | main.rs:53:5:53:63 | ... .secure(...) | provenance | MaD:41 | +| main.rs:53:5:53:63 | ... .secure(...) | main.rs:53:65:53:69 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:54:5:54:17 | ...::build | main.rs:54:5:54:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:54:5:54:36 | ...::build(...) | main.rs:54:5:54:50 | ... .secure(...) | provenance | MaD:41 | +| main.rs:54:5:54:50 | ... .secure(...) | main.rs:54:5:54:63 | ... .secure(...) | provenance | MaD:41 | +| main.rs:54:5:54:63 | ... .secure(...) | main.rs:54:65:54:69 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:58:9:58:13 | mut a | main.rs:59:13:59:13 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:59:13:59:21 | a.clone() | provenance | MaD:17 | +| main.rs:58:9:58:13 | mut a | main.rs:60:22:60:22 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:60:22:60:30 | a.clone() | provenance | MaD:17 | +| main.rs:58:9:58:13 | mut a | main.rs:62:13:62:13 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:62:13:62:21 | a.clone() | provenance | MaD:17 | +| main.rs:58:9:58:13 | mut a | main.rs:64:13:64:13 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | +| main.rs:58:9:58:13 | mut a | main.rs:70:29:70:29 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | +| main.rs:58:9:58:13 | mut a | main.rs:79:30:79:30 | a | provenance | | +| main.rs:58:9:58:13 | mut a | main.rs:79:30:79:38 | a.clone() | provenance | MaD:17 | +| main.rs:58:17:58:27 | ...::new | main.rs:58:17:58:44 | ...::new(...) | provenance | Src:MaD:15 MaD:15 | +| main.rs:58:17:58:44 | ...::new(...) | main.rs:58:9:58:13 | mut a | provenance | | +| main.rs:59:13:59:13 | a | main.rs:59:13:59:21 | a.clone() | provenance | MaD:17 | +| main.rs:59:13:59:21 | a.clone() | main.rs:59:9:59:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:60:22:60:22 | a | main.rs:60:22:60:30 | a.clone() | provenance | MaD:17 | +| main.rs:60:22:60:30 | a.clone() | main.rs:60:9:60:20 | add_original | provenance | MaD:5 Sink:MaD:5 | +| main.rs:62:13:62:13 | a | main.rs:62:13:62:21 | a.clone() | provenance | MaD:17 | +| main.rs:62:13:62:21 | a.clone() | main.rs:62:9:62:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:64:13:64:13 | a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | +| main.rs:64:13:64:21 | a.clone() | main.rs:64:9:64:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:68:9:68:13 | mut b | main.rs:69:20:69:20 | b | provenance | | +| main.rs:68:9:68:13 | mut b | main.rs:69:20:69:28 | b.clone() | provenance | MaD:17 | +| main.rs:68:9:68:13 | mut b | main.rs:72:20:72:20 | b | provenance | | +| main.rs:68:9:68:13 | mut b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | +| main.rs:68:9:68:13 | mut b | main.rs:74:20:74:20 | b | provenance | | +| main.rs:68:9:68:13 | mut b | main.rs:74:20:74:28 | b.clone() | provenance | MaD:17 | +| main.rs:68:17:68:29 | ...::named | main.rs:68:17:68:37 | ...::named(...) | provenance | Src:MaD:14 MaD:14 | +| main.rs:68:17:68:37 | ...::named(...) | main.rs:68:9:68:13 | mut b | provenance | | +| main.rs:69:20:69:20 | b | main.rs:69:20:69:28 | b.clone() | provenance | MaD:17 | +| main.rs:69:20:69:28 | b.clone() | main.rs:69:16:69:18 | add | provenance | MaD:8 Sink:MaD:8 | +| main.rs:70:29:70:29 | a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | +| main.rs:70:29:70:37 | a.clone() | main.rs:70:16:70:27 | add_original | provenance | MaD:9 Sink:MaD:9 | +| main.rs:72:20:72:20 | b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | +| main.rs:72:20:72:28 | b.clone() | main.rs:72:16:72:18 | add | provenance | MaD:8 Sink:MaD:8 | +| main.rs:74:20:74:20 | b | main.rs:74:20:74:28 | b.clone() | provenance | MaD:17 | +| main.rs:74:20:74:28 | b.clone() | main.rs:74:16:74:18 | add | provenance | MaD:8 Sink:MaD:8 | +| main.rs:77:9:77:13 | mut c | main.rs:78:21:78:21 | c | provenance | | +| main.rs:77:9:77:13 | mut c | main.rs:78:21:78:29 | c.clone() | provenance | MaD:17 | +| main.rs:77:9:77:13 | mut c | main.rs:83:21:83:21 | c | provenance | | +| main.rs:77:9:77:13 | mut c | main.rs:83:21:83:29 | c.clone() | provenance | MaD:17 | +| main.rs:77:9:77:13 | mut c | main.rs:85:21:85:21 | c | provenance | | +| main.rs:77:9:77:13 | mut c | main.rs:85:21:85:29 | c.clone() | provenance | MaD:17 | +| main.rs:77:17:77:28 | ...::from | main.rs:77:17:77:36 | ...::from(...) | provenance | Src:MaD:12 MaD:12 | +| main.rs:77:17:77:36 | ...::from(...) | main.rs:77:9:77:13 | mut c | provenance | | +| main.rs:78:21:78:21 | c | main.rs:78:21:78:29 | c.clone() | provenance | MaD:17 | +| main.rs:78:21:78:29 | c.clone() | main.rs:78:17:78:19 | add | provenance | MaD:6 Sink:MaD:6 | +| main.rs:79:30:79:30 | a | main.rs:79:30:79:38 | a.clone() | provenance | MaD:17 | +| main.rs:79:30:79:38 | a.clone() | main.rs:79:17:79:28 | add_original | provenance | MaD:7 Sink:MaD:7 | +| main.rs:83:21:83:21 | c | main.rs:83:21:83:29 | c.clone() | provenance | MaD:17 | +| main.rs:83:21:83:29 | c.clone() | main.rs:83:17:83:19 | add | provenance | MaD:6 Sink:MaD:6 | +| main.rs:85:21:85:21 | c | main.rs:85:21:85:29 | c.clone() | provenance | MaD:17 | +| main.rs:85:21:85:29 | c.clone() | main.rs:85:17:85:19 | add | provenance | MaD:6 Sink:MaD:6 | +| main.rs:87:9:87:13 | mut d | main.rs:88:13:88:13 | d | provenance | | +| main.rs:87:9:87:13 | mut d | main.rs:88:13:88:21 | d.clone() | provenance | MaD:17 | +| main.rs:87:9:87:13 | mut d | main.rs:94:13:94:13 | d | provenance | | +| main.rs:87:9:87:13 | mut d | main.rs:94:13:94:21 | d.clone() | provenance | MaD:17 | +| main.rs:87:17:87:28 | ...::from | main.rs:87:17:87:36 | ...::from(...) | provenance | Src:MaD:12 MaD:12 | +| main.rs:87:17:87:36 | ...::from(...) | main.rs:87:9:87:13 | mut d | provenance | | +| main.rs:88:13:88:13 | d | main.rs:88:13:88:21 | d.clone() | provenance | MaD:17 | +| main.rs:88:13:88:21 | d.clone() | main.rs:88:9:88:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:94:13:94:13 | d | main.rs:94:13:94:21 | d.clone() | provenance | MaD:17 | +| main.rs:94:13:94:21 | d.clone() | main.rs:94:9:94:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:114:5:114:17 | ...::build | main.rs:114:5:114:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:114:5:114:36 | ...::build(...) | main.rs:114:5:114:54 | ... .partitioned(...) | provenance | MaD:36 | +| main.rs:114:5:114:54 | ... .partitioned(...) | main.rs:114:56:114:60 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:122:9:122:9 | a | main.rs:123:20:123:20 | a | provenance | | +| main.rs:122:9:122:9 | a | main.rs:123:20:123:28 | a.clone() | provenance | MaD:17 | +| main.rs:122:9:122:9 | a | main.rs:126:13:126:30 | a.set_secure(...) | provenance | MaD:27 | +| main.rs:122:13:122:41 | ...::new | main.rs:122:13:122:58 | ...::new(...) | provenance | Src:MaD:11 MaD:11 | +| main.rs:122:13:122:58 | ...::new(...) | main.rs:122:9:122:9 | a | provenance | | +| main.rs:123:20:123:20 | a | main.rs:123:20:123:28 | a.clone() | provenance | MaD:17 | +| main.rs:123:20:123:28 | a.clone() | main.rs:123:13:123:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:126:9:126:9 | b | main.rs:127:20:127:20 | b | provenance | | +| main.rs:126:9:126:9 | b | main.rs:127:20:127:28 | b.clone() | provenance | MaD:17 | +| main.rs:126:9:126:9 | b | main.rs:130:13:130:31 | b.set_secure(...) | provenance | MaD:27 | +| main.rs:126:13:126:30 | a.set_secure(...) | main.rs:126:9:126:9 | b | provenance | | +| main.rs:127:20:127:20 | b | main.rs:127:20:127:28 | b.clone() | provenance | MaD:17 | +| main.rs:127:20:127:28 | b.clone() | main.rs:127:13:127:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:130:9:130:9 | c | main.rs:131:20:131:20 | c | provenance | | +| main.rs:130:9:130:9 | c | main.rs:131:20:131:28 | c.clone() | provenance | MaD:17 | +| main.rs:130:9:130:9 | c | main.rs:134:13:134:35 | c.set_partitioned(...) | provenance | MaD:24 | +| main.rs:130:13:130:31 | b.set_secure(...) | main.rs:130:9:130:9 | c | provenance | | +| main.rs:131:20:131:20 | c | main.rs:131:20:131:28 | c.clone() | provenance | MaD:17 | +| main.rs:131:20:131:28 | c.clone() | main.rs:131:13:131:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:134:9:134:9 | d | main.rs:135:20:135:20 | d | provenance | | +| main.rs:134:9:134:9 | d | main.rs:135:20:135:28 | d.clone() | provenance | MaD:17 | +| main.rs:134:9:134:9 | d | main.rs:138:13:138:30 | d.set_secure(...) | provenance | MaD:27 | +| main.rs:134:13:134:35 | c.set_partitioned(...) | main.rs:134:9:134:9 | d | provenance | | +| main.rs:135:20:135:20 | d | main.rs:135:20:135:28 | d.clone() | provenance | MaD:17 | +| main.rs:135:20:135:28 | d.clone() | main.rs:135:13:135:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:138:9:138:9 | e | main.rs:139:20:139:20 | e | provenance | | +| main.rs:138:9:138:9 | e | main.rs:139:20:139:28 | e.clone() | provenance | MaD:17 | +| main.rs:138:9:138:9 | e | main.rs:142:13:142:36 | e.set_partitioned(...) | provenance | MaD:24 | +| main.rs:138:13:138:30 | d.set_secure(...) | main.rs:138:9:138:9 | e | provenance | | +| main.rs:139:20:139:20 | e | main.rs:139:20:139:28 | e.clone() | provenance | MaD:17 | +| main.rs:139:20:139:28 | e.clone() | main.rs:139:13:139:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:142:9:142:9 | f | main.rs:143:20:143:20 | f | provenance | | +| main.rs:142:9:142:9 | f | main.rs:143:20:143:28 | f.clone() | provenance | MaD:17 | +| main.rs:142:9:142:9 | f | main.rs:146:13:146:31 | f.set_secure(...) | provenance | MaD:27 | +| main.rs:142:13:142:36 | e.set_partitioned(...) | main.rs:142:9:142:9 | f | provenance | | +| main.rs:143:20:143:20 | f | main.rs:143:20:143:28 | f.clone() | provenance | MaD:17 | +| main.rs:143:20:143:28 | f.clone() | main.rs:143:13:143:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:146:9:146:9 | g | main.rs:147:20:147:20 | g | provenance | | +| main.rs:146:9:146:9 | g | main.rs:147:20:147:28 | g.clone() | provenance | MaD:17 | +| main.rs:146:13:146:31 | f.set_secure(...) | main.rs:146:9:146:9 | g | provenance | | +| main.rs:147:20:147:20 | g | main.rs:147:20:147:28 | g.clone() | provenance | MaD:17 | +| main.rs:147:20:147:28 | g.clone() | main.rs:147:13:147:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:151:9:151:9 | h | main.rs:152:20:152:20 | h | provenance | | +| main.rs:151:13:151:42 | ...::from | main.rs:151:13:151:61 | ...::from(...) | provenance | Src:MaD:10 MaD:10 | +| main.rs:151:13:151:61 | ...::from(...) | main.rs:151:9:151:9 | h | provenance | | +| main.rs:152:20:152:20 | h | main.rs:152:13:152:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:155:9:155:9 | i | main.rs:156:20:156:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:156:20:156:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:157:20:157:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:157:20:157:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:158:20:158:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:158:20:158:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:159:20:159:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:159:20:159:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:160:20:160:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:160:20:160:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:161:20:161:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:161:20:161:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:162:20:162:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:162:20:162:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:163:20:163:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:163:20:163:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:164:20:164:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:164:20:164:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:165:20:165:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:165:20:165:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:166:20:166:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:166:20:166:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:9:155:9 | i | main.rs:167:20:167:20 | i | provenance | | +| main.rs:155:9:155:9 | i | main.rs:167:20:167:28 | i.clone() | provenance | MaD:17 | +| main.rs:155:13:155:41 | ...::new | main.rs:155:13:155:58 | ...::new(...) | provenance | Src:MaD:11 MaD:11 | +| main.rs:155:13:155:58 | ...::new(...) | main.rs:155:9:155:9 | i | provenance | | +| main.rs:156:20:156:20 | i | main.rs:156:20:156:28 | i.clone() | provenance | MaD:17 | +| main.rs:156:20:156:28 | i.clone() | main.rs:156:20:156:46 | ... .set_name(...) | provenance | MaD:23 | +| main.rs:156:20:156:46 | ... .set_name(...) | main.rs:156:13:156:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:157:20:157:20 | i | main.rs:157:20:157:28 | i.clone() | provenance | MaD:17 | +| main.rs:157:20:157:28 | i.clone() | main.rs:157:20:157:48 | ... .set_value(...) | provenance | MaD:28 | +| main.rs:157:20:157:48 | ... .set_value(...) | main.rs:157:13:157:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:158:20:158:20 | i | main.rs:158:20:158:28 | i.clone() | provenance | MaD:17 | +| main.rs:158:20:158:28 | i.clone() | main.rs:158:20:158:48 | ... .set_http_only(...) | provenance | MaD:21 | +| main.rs:158:20:158:48 | ... .set_http_only(...) | main.rs:158:13:158:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:159:20:159:20 | i | main.rs:159:20:159:28 | i.clone() | provenance | MaD:17 | +| main.rs:159:20:159:28 | i.clone() | main.rs:159:20:159:70 | ... .set_same_site(...) | provenance | MaD:26 | +| main.rs:159:20:159:70 | ... .set_same_site(...) | main.rs:159:13:159:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:160:20:160:20 | i | main.rs:160:20:160:28 | i.clone() | provenance | MaD:17 | +| main.rs:160:20:160:28 | i.clone() | main.rs:160:20:160:46 | ... .set_max_age(...) | provenance | MaD:22 | +| main.rs:160:20:160:46 | ... .set_max_age(...) | main.rs:160:13:160:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:161:20:161:20 | i | main.rs:161:20:161:28 | i.clone() | provenance | MaD:17 | +| main.rs:161:20:161:28 | i.clone() | main.rs:161:20:161:42 | ... .set_path(...) | provenance | MaD:25 | +| main.rs:161:20:161:42 | ... .set_path(...) | main.rs:161:13:161:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:162:20:162:20 | i | main.rs:162:20:162:28 | i.clone() | provenance | MaD:17 | +| main.rs:162:20:162:28 | i.clone() | main.rs:162:20:162:41 | ... .unset_path() | provenance | MaD:31 | +| main.rs:162:20:162:41 | ... .unset_path() | main.rs:162:13:162:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:163:20:163:20 | i | main.rs:163:20:163:28 | i.clone() | provenance | MaD:17 | +| main.rs:163:20:163:28 | i.clone() | main.rs:163:20:163:54 | ... .set_domain(...) | provenance | MaD:19 | +| main.rs:163:20:163:54 | ... .set_domain(...) | main.rs:163:13:163:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:164:20:164:20 | i | main.rs:164:20:164:28 | i.clone() | provenance | MaD:17 | +| main.rs:164:20:164:28 | i.clone() | main.rs:164:20:164:43 | ... .unset_domain() | provenance | MaD:29 | +| main.rs:164:20:164:43 | ... .unset_domain() | main.rs:164:13:164:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:165:20:165:20 | i | main.rs:165:20:165:28 | i.clone() | provenance | MaD:17 | +| main.rs:165:20:165:28 | i.clone() | main.rs:165:20:165:46 | ... .set_expires(...) | provenance | MaD:20 | +| main.rs:165:20:165:46 | ... .set_expires(...) | main.rs:165:13:165:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:166:20:166:20 | i | main.rs:166:20:166:28 | i.clone() | provenance | MaD:17 | +| main.rs:166:20:166:28 | i.clone() | main.rs:166:20:166:44 | ... .unset_expires() | provenance | MaD:30 | +| main.rs:166:20:166:44 | ... .unset_expires() | main.rs:166:13:166:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:167:20:167:20 | i | main.rs:167:20:167:28 | i.clone() | provenance | MaD:17 | +| main.rs:167:20:167:28 | i.clone() | main.rs:167:20:167:45 | ... .make_permanent() | provenance | MaD:18 | +| main.rs:167:20:167:45 | ... .make_permanent() | main.rs:167:13:167:18 | insert | provenance | MaD:1 Sink:MaD:1 | +models +| 1 | Sink: ::insert; Argument[0]; cookie-use | +| 2 | Sink: ::build; Argument[self]; cookie-use | +| 3 | Sink: ::finish; Argument[self]; cookie-use | +| 4 | Sink: ::add; Argument[0]; cookie-use | +| 5 | Sink: ::add_original; Argument[0]; cookie-use | +| 6 | Sink: ::add; Argument[0]; cookie-use | +| 7 | Sink: ::add_original; Argument[0]; cookie-use | +| 8 | Sink: ::add; Argument[0]; cookie-use | +| 9 | Sink: ::add_original; Argument[0]; cookie-use | +| 10 | Source: ::from; ReturnValue; cookie-create | +| 11 | Source: ::new; ReturnValue; cookie-create | +| 12 | Source: ::from; ReturnValue; cookie-create | +| 13 | Source: ::build; ReturnValue; cookie-create | +| 14 | Source: ::named; ReturnValue; cookie-create | +| 15 | Source: ::new; ReturnValue; cookie-create | +| 16 | Source: ::new; ReturnValue; cookie-create | +| 17 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value | +| 18 | Summary: ::make_permanent; Argument[self]; ReturnValue; taint | +| 19 | Summary: ::set_domain; Argument[self]; ReturnValue; taint | +| 20 | Summary: ::set_expires; Argument[self]; ReturnValue; taint | +| 21 | Summary: ::set_http_only; Argument[self]; ReturnValue; taint | +| 22 | Summary: ::set_max_age; Argument[self]; ReturnValue; taint | +| 23 | Summary: ::set_name; Argument[self]; ReturnValue; taint | +| 24 | Summary: ::set_partitioned; Argument[self]; ReturnValue; taint | +| 25 | Summary: ::set_path; Argument[self]; ReturnValue; taint | +| 26 | Summary: ::set_same_site; Argument[self]; ReturnValue; taint | +| 27 | Summary: ::set_secure; Argument[self]; ReturnValue; taint | +| 28 | Summary: ::set_value; Argument[self]; ReturnValue; taint | +| 29 | Summary: ::unset_domain; Argument[self]; ReturnValue; taint | +| 30 | Summary: ::unset_expires; Argument[self]; ReturnValue; taint | +| 31 | Summary: ::unset_path; Argument[self]; ReturnValue; taint | +| 32 | Summary: ::domain; Argument[self]; ReturnValue; taint | +| 33 | Summary: ::expires; Argument[self]; ReturnValue; taint | +| 34 | Summary: ::http_only; Argument[self]; ReturnValue; taint | +| 35 | Summary: ::max_age; Argument[self]; ReturnValue; taint | +| 36 | Summary: ::partitioned; Argument[self]; ReturnValue; taint | +| 37 | Summary: ::path; Argument[self]; ReturnValue; taint | +| 38 | Summary: ::permanent; Argument[self]; ReturnValue; taint | +| 39 | Summary: ::removal; Argument[self]; ReturnValue; taint | +| 40 | Summary: ::same_site; Argument[self]; ReturnValue; taint | +| 41 | Summary: ::secure; Argument[self]; ReturnValue; taint | nodes +| main.rs:8:19:8:31 | ...::build | semmle.label | ...::build | +| main.rs:8:19:8:50 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:8:19:8:64 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:8:66:8:70 | build | semmle.label | build | +| main.rs:12:19:12:31 | ...::build | semmle.label | ...::build | +| main.rs:12:19:12:50 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:12:19:12:63 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:12:65:12:69 | build | semmle.label | build | +| main.rs:16:19:16:31 | ...::build | semmle.label | ...::build | | main.rs:16:19:16:50 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:16:52:16:56 | build | semmle.label | build | +| main.rs:20:5:20:17 | ...::build | semmle.label | ...::build | +| main.rs:20:5:20:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:20:5:20:54 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:20:56:20:60 | build | semmle.label | build | +| main.rs:21:5:21:17 | ...::build | semmle.label | ...::build | +| main.rs:21:5:21:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:21:5:21:55 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:21:57:21:61 | build | semmle.label | build | +| main.rs:24:5:24:17 | ...::build | semmle.label | ...::build | +| main.rs:24:5:24:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:24:5:24:51 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:24:53:24:57 | build | semmle.label | build | +| main.rs:25:5:25:17 | ...::build | semmle.label | ...::build | +| main.rs:25:5:25:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:25:5:25:52 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:25:54:25:58 | build | semmle.label | build | +| main.rs:26:5:26:17 | ...::build | semmle.label | ...::build | +| main.rs:26:5:26:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:26:5:26:50 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:26:52:26:56 | build | semmle.label | build | +| main.rs:27:5:27:17 | ...::build | semmle.label | ...::build | +| main.rs:27:5:27:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:27:5:27:51 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:27:53:27:57 | build | semmle.label | build | +| main.rs:28:5:28:17 | ...::build | semmle.label | ...::build | +| main.rs:28:5:28:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:28:5:28:60 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:28:62:28:66 | build | semmle.label | build | +| main.rs:29:5:29:17 | ...::build | semmle.label | ...::build | +| main.rs:29:5:29:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:29:5:29:60 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:29:62:29:66 | build | semmle.label | build | +| main.rs:33:9:33:21 | ...::build | semmle.label | ...::build | +| main.rs:33:9:33:40 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:33:9:33:58 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:33:60:33:64 | build | semmle.label | build | +| main.rs:35:9:35:21 | ...::build | semmle.label | ...::build | +| main.rs:35:9:35:40 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:35:9:35:58 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:35:60:35:64 | build | semmle.label | build | +| main.rs:39:5:39:22 | ...::new | semmle.label | ...::new | +| main.rs:39:5:39:39 | ...::new(...) | semmle.label | ...::new(...) | +| main.rs:39:5:39:53 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:39:55:39:59 | build | semmle.label | build | +| main.rs:40:5:40:17 | ...::build | semmle.label | ...::build | +| main.rs:40:5:40:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:40:5:40:50 | ... .expires(...) | semmle.label | ... .expires(...) | +| main.rs:40:5:40:64 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:40:66:40:70 | build | semmle.label | build | +| main.rs:41:5:41:17 | ...::build | semmle.label | ...::build | +| main.rs:41:5:41:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:41:5:41:79 | ... .max_age(...) | semmle.label | ... .max_age(...) | +| main.rs:41:5:41:93 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:41:95:41:99 | build | semmle.label | build | +| main.rs:42:5:42:17 | ...::build | semmle.label | ...::build | +| main.rs:42:5:42:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:42:5:42:58 | ... .domain(...) | semmle.label | ... .domain(...) | +| main.rs:42:5:42:72 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:42:74:42:78 | build | semmle.label | build | +| main.rs:43:5:43:17 | ...::build | semmle.label | ...::build | +| main.rs:43:5:43:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:43:5:43:46 | ... .path(...) | semmle.label | ... .path(...) | +| main.rs:43:5:43:60 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:43:62:43:66 | build | semmle.label | build | +| main.rs:44:5:44:17 | ...::build | semmle.label | ...::build | +| main.rs:44:5:44:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:44:5:44:52 | ... .http_only(...) | semmle.label | ... .http_only(...) | +| main.rs:44:5:44:66 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:44:68:44:72 | build | semmle.label | build | +| main.rs:45:5:45:17 | ...::build | semmle.label | ...::build | +| main.rs:45:5:45:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:45:5:45:72 | ... .same_site(...) | semmle.label | ... .same_site(...) | +| main.rs:45:5:45:86 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:45:88:45:92 | build | semmle.label | build | +| main.rs:46:5:46:17 | ...::build | semmle.label | ...::build | +| main.rs:46:5:46:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:46:5:46:48 | ... .permanent() | semmle.label | ... .permanent() | +| main.rs:46:5:46:62 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:46:64:46:68 | build | semmle.label | build | +| main.rs:47:5:47:17 | ...::build | semmle.label | ...::build | +| main.rs:47:5:47:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:47:5:47:46 | ... .removal() | semmle.label | ... .removal() | +| main.rs:47:5:47:60 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:47:62:47:66 | build | semmle.label | build | +| main.rs:48:5:48:17 | ...::build | semmle.label | ...::build | +| main.rs:48:5:48:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:48:5:48:50 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:48:52:48:57 | finish | semmle.label | finish | +| main.rs:49:5:49:17 | ...::build | semmle.label | ...::build | +| main.rs:49:5:49:25 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:49:5:49:39 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:49:41:49:45 | build | semmle.label | build | +| main.rs:50:5:50:17 | ...::build | semmle.label | ...::build | +| main.rs:50:5:50:40 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:50:5:50:54 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:50:56:50:60 | build | semmle.label | build | +| main.rs:53:5:53:17 | ...::build | semmle.label | ...::build | +| main.rs:53:5:53:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:53:5:53:49 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:53:5:53:63 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:53:65:53:69 | build | semmle.label | build | +| main.rs:54:5:54:17 | ...::build | semmle.label | ...::build | +| main.rs:54:5:54:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:54:5:54:50 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:54:5:54:63 | ... .secure(...) | semmle.label | ... .secure(...) | +| main.rs:54:65:54:69 | build | semmle.label | build | +| main.rs:58:9:58:13 | mut a | semmle.label | mut a | +| main.rs:58:17:58:27 | ...::new | semmle.label | ...::new | +| main.rs:58:17:58:44 | ...::new(...) | semmle.label | ...::new(...) | +| main.rs:59:9:59:11 | add | semmle.label | add | +| main.rs:59:13:59:13 | a | semmle.label | a | +| main.rs:59:13:59:21 | a.clone() | semmle.label | a.clone() | +| main.rs:60:9:60:20 | add_original | semmle.label | add_original | +| main.rs:60:22:60:22 | a | semmle.label | a | +| main.rs:60:22:60:30 | a.clone() | semmle.label | a.clone() | +| main.rs:62:9:62:11 | add | semmle.label | add | +| main.rs:62:13:62:13 | a | semmle.label | a | +| main.rs:62:13:62:21 | a.clone() | semmle.label | a.clone() | +| main.rs:64:9:64:11 | add | semmle.label | add | +| main.rs:64:13:64:13 | a | semmle.label | a | +| main.rs:64:13:64:21 | a.clone() | semmle.label | a.clone() | +| main.rs:68:9:68:13 | mut b | semmle.label | mut b | +| main.rs:68:17:68:29 | ...::named | semmle.label | ...::named | +| main.rs:68:17:68:37 | ...::named(...) | semmle.label | ...::named(...) | +| main.rs:69:16:69:18 | add | semmle.label | add | +| main.rs:69:20:69:20 | b | semmle.label | b | +| main.rs:69:20:69:28 | b.clone() | semmle.label | b.clone() | +| main.rs:70:16:70:27 | add_original | semmle.label | add_original | +| main.rs:70:29:70:29 | a | semmle.label | a | +| main.rs:70:29:70:37 | a.clone() | semmle.label | a.clone() | +| main.rs:72:16:72:18 | add | semmle.label | add | +| main.rs:72:20:72:20 | b | semmle.label | b | +| main.rs:72:20:72:28 | b.clone() | semmle.label | b.clone() | +| main.rs:74:16:74:18 | add | semmle.label | add | +| main.rs:74:20:74:20 | b | semmle.label | b | +| main.rs:74:20:74:28 | b.clone() | semmle.label | b.clone() | +| main.rs:77:9:77:13 | mut c | semmle.label | mut c | +| main.rs:77:17:77:28 | ...::from | semmle.label | ...::from | +| main.rs:77:17:77:36 | ...::from(...) | semmle.label | ...::from(...) | +| main.rs:78:17:78:19 | add | semmle.label | add | +| main.rs:78:21:78:21 | c | semmle.label | c | +| main.rs:78:21:78:29 | c.clone() | semmle.label | c.clone() | +| main.rs:79:17:79:28 | add_original | semmle.label | add_original | +| main.rs:79:30:79:30 | a | semmle.label | a | +| main.rs:79:30:79:38 | a.clone() | semmle.label | a.clone() | +| main.rs:83:17:83:19 | add | semmle.label | add | +| main.rs:83:21:83:21 | c | semmle.label | c | +| main.rs:83:21:83:29 | c.clone() | semmle.label | c.clone() | +| main.rs:85:17:85:19 | add | semmle.label | add | +| main.rs:85:21:85:21 | c | semmle.label | c | +| main.rs:85:21:85:29 | c.clone() | semmle.label | c.clone() | +| main.rs:87:9:87:13 | mut d | semmle.label | mut d | +| main.rs:87:17:87:28 | ...::from | semmle.label | ...::from | +| main.rs:87:17:87:36 | ...::from(...) | semmle.label | ...::from(...) | +| main.rs:88:9:88:11 | add | semmle.label | add | +| main.rs:88:13:88:13 | d | semmle.label | d | +| main.rs:88:13:88:21 | d.clone() | semmle.label | d.clone() | +| main.rs:94:9:94:11 | add | semmle.label | add | +| main.rs:94:13:94:13 | d | semmle.label | d | +| main.rs:94:13:94:21 | d.clone() | semmle.label | d.clone() | +| main.rs:114:5:114:17 | ...::build | semmle.label | ...::build | +| main.rs:114:5:114:36 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:114:5:114:54 | ... .partitioned(...) | semmle.label | ... .partitioned(...) | +| main.rs:114:56:114:60 | build | semmle.label | build | +| main.rs:122:9:122:9 | a | semmle.label | a | +| main.rs:122:13:122:41 | ...::new | semmle.label | ...::new | +| main.rs:122:13:122:58 | ...::new(...) | semmle.label | ...::new(...) | +| main.rs:123:13:123:18 | insert | semmle.label | insert | +| main.rs:123:20:123:20 | a | semmle.label | a | +| main.rs:123:20:123:28 | a.clone() | semmle.label | a.clone() | +| main.rs:126:9:126:9 | b | semmle.label | b | +| main.rs:126:13:126:30 | a.set_secure(...) | semmle.label | a.set_secure(...) | +| main.rs:127:13:127:18 | insert | semmle.label | insert | +| main.rs:127:20:127:20 | b | semmle.label | b | +| main.rs:127:20:127:28 | b.clone() | semmle.label | b.clone() | +| main.rs:130:9:130:9 | c | semmle.label | c | +| main.rs:130:13:130:31 | b.set_secure(...) | semmle.label | b.set_secure(...) | +| main.rs:131:13:131:18 | insert | semmle.label | insert | +| main.rs:131:20:131:20 | c | semmle.label | c | +| main.rs:131:20:131:28 | c.clone() | semmle.label | c.clone() | +| main.rs:134:9:134:9 | d | semmle.label | d | +| main.rs:134:13:134:35 | c.set_partitioned(...) | semmle.label | c.set_partitioned(...) | +| main.rs:135:13:135:18 | insert | semmle.label | insert | +| main.rs:135:20:135:20 | d | semmle.label | d | +| main.rs:135:20:135:28 | d.clone() | semmle.label | d.clone() | +| main.rs:138:9:138:9 | e | semmle.label | e | +| main.rs:138:13:138:30 | d.set_secure(...) | semmle.label | d.set_secure(...) | +| main.rs:139:13:139:18 | insert | semmle.label | insert | +| main.rs:139:20:139:20 | e | semmle.label | e | +| main.rs:139:20:139:28 | e.clone() | semmle.label | e.clone() | +| main.rs:142:9:142:9 | f | semmle.label | f | +| main.rs:142:13:142:36 | e.set_partitioned(...) | semmle.label | e.set_partitioned(...) | +| main.rs:143:13:143:18 | insert | semmle.label | insert | +| main.rs:143:20:143:20 | f | semmle.label | f | +| main.rs:143:20:143:28 | f.clone() | semmle.label | f.clone() | +| main.rs:146:9:146:9 | g | semmle.label | g | +| main.rs:146:13:146:31 | f.set_secure(...) | semmle.label | f.set_secure(...) | +| main.rs:147:13:147:18 | insert | semmle.label | insert | +| main.rs:147:20:147:20 | g | semmle.label | g | +| main.rs:147:20:147:28 | g.clone() | semmle.label | g.clone() | +| main.rs:151:9:151:9 | h | semmle.label | h | +| main.rs:151:13:151:42 | ...::from | semmle.label | ...::from | +| main.rs:151:13:151:61 | ...::from(...) | semmle.label | ...::from(...) | +| main.rs:152:13:152:18 | insert | semmle.label | insert | +| main.rs:152:20:152:20 | h | semmle.label | h | +| main.rs:155:9:155:9 | i | semmle.label | i | +| main.rs:155:13:155:41 | ...::new | semmle.label | ...::new | +| main.rs:155:13:155:58 | ...::new(...) | semmle.label | ...::new(...) | +| main.rs:156:13:156:18 | insert | semmle.label | insert | +| main.rs:156:20:156:20 | i | semmle.label | i | +| main.rs:156:20:156:28 | i.clone() | semmle.label | i.clone() | +| main.rs:156:20:156:46 | ... .set_name(...) | semmle.label | ... .set_name(...) | +| main.rs:157:13:157:18 | insert | semmle.label | insert | +| main.rs:157:20:157:20 | i | semmle.label | i | +| main.rs:157:20:157:28 | i.clone() | semmle.label | i.clone() | +| main.rs:157:20:157:48 | ... .set_value(...) | semmle.label | ... .set_value(...) | +| main.rs:158:13:158:18 | insert | semmle.label | insert | +| main.rs:158:20:158:20 | i | semmle.label | i | +| main.rs:158:20:158:28 | i.clone() | semmle.label | i.clone() | +| main.rs:158:20:158:48 | ... .set_http_only(...) | semmle.label | ... .set_http_only(...) | +| main.rs:159:13:159:18 | insert | semmle.label | insert | +| main.rs:159:20:159:20 | i | semmle.label | i | +| main.rs:159:20:159:28 | i.clone() | semmle.label | i.clone() | +| main.rs:159:20:159:70 | ... .set_same_site(...) | semmle.label | ... .set_same_site(...) | +| main.rs:160:13:160:18 | insert | semmle.label | insert | +| main.rs:160:20:160:20 | i | semmle.label | i | +| main.rs:160:20:160:28 | i.clone() | semmle.label | i.clone() | +| main.rs:160:20:160:46 | ... .set_max_age(...) | semmle.label | ... .set_max_age(...) | +| main.rs:161:13:161:18 | insert | semmle.label | insert | +| main.rs:161:20:161:20 | i | semmle.label | i | +| main.rs:161:20:161:28 | i.clone() | semmle.label | i.clone() | +| main.rs:161:20:161:42 | ... .set_path(...) | semmle.label | ... .set_path(...) | +| main.rs:162:13:162:18 | insert | semmle.label | insert | +| main.rs:162:20:162:20 | i | semmle.label | i | +| main.rs:162:20:162:28 | i.clone() | semmle.label | i.clone() | +| main.rs:162:20:162:41 | ... .unset_path() | semmle.label | ... .unset_path() | +| main.rs:163:13:163:18 | insert | semmle.label | insert | +| main.rs:163:20:163:20 | i | semmle.label | i | +| main.rs:163:20:163:28 | i.clone() | semmle.label | i.clone() | +| main.rs:163:20:163:54 | ... .set_domain(...) | semmle.label | ... .set_domain(...) | +| main.rs:164:13:164:18 | insert | semmle.label | insert | +| main.rs:164:20:164:20 | i | semmle.label | i | +| main.rs:164:20:164:28 | i.clone() | semmle.label | i.clone() | +| main.rs:164:20:164:43 | ... .unset_domain() | semmle.label | ... .unset_domain() | +| main.rs:165:13:165:18 | insert | semmle.label | insert | +| main.rs:165:20:165:20 | i | semmle.label | i | +| main.rs:165:20:165:28 | i.clone() | semmle.label | i.clone() | +| main.rs:165:20:165:46 | ... .set_expires(...) | semmle.label | ... .set_expires(...) | +| main.rs:166:13:166:18 | insert | semmle.label | insert | +| main.rs:166:20:166:20 | i | semmle.label | i | +| main.rs:166:20:166:28 | i.clone() | semmle.label | i.clone() | +| main.rs:166:20:166:44 | ... .unset_expires() | semmle.label | ... .unset_expires() | +| main.rs:167:13:167:18 | insert | semmle.label | insert | +| main.rs:167:20:167:20 | i | semmle.label | i | +| main.rs:167:20:167:28 | i.clone() | semmle.label | i.clone() | +| main.rs:167:20:167:45 | ... .make_permanent() | semmle.label | ... .make_permanent() | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 6ef4cc3c83b..0f0f929fd14 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -5,11 +5,11 @@ fn test_cookie(sometimes: bool) { let never = false; // secure set to false - let cookie1 = Cookie::build(("name", "value")).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + let cookie1 = Cookie::build(("name", "value")).secure(false).build(); // $ Alert[rust/insecure-cookie] println!("cookie1 = '{}'", cookie1.to_string()); // secure set to true - let cookie2 = Cookie::build(("name", "value")).secure(true).build(); // good + let cookie2 = Cookie::build(("name", "value")).secure(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] println!("cookie2 = '{}'", cookie2.to_string()); // secure left as default (which is `None`, equivalent here to `false`) @@ -17,81 +17,81 @@ fn test_cookie(sometimes: bool) { println!("cookie3 = '{}'", cookie3.to_string()); // secure setting varies (may be false) - Cookie::build(("name", "value")).secure(sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(!sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(sometimes).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(!sometimes).build(); // $ Alert[rust/insecure-cookie] // with data flow on the "secure" value - Cookie::build(("name", "value")).secure(always).build(); // good - Cookie::build(("name", "value")).secure(!always).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(never).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(!never).build(); // good - Cookie::build(("name", "value")).secure(always && never).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(always || never).build(); // good + Cookie::build(("name", "value")).secure(always).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(!always).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(never).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(!never).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(always && never).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(always || never).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] // with guards if sometimes { - Cookie::build(("name", "value")).secure(sometimes).build(); // good + Cookie::build(("name", "value")).secure(sometimes).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] } else { - Cookie::build(("name", "value")).secure(sometimes).build(); // $ MISSING: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(sometimes).build(); // $ Alert[rust/insecure-cookie] } // variant uses (all insecure) - CookieBuilder::new("name", "value").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).expires(None).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).max_age(cookie::time::Duration::hours(12)).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).domain("example.com").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).path("/").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).http_only(true).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).same_site(cookie::SameSite::Strict).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).permanent().secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).removal().secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(false).finish(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build("name").secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(Cookie::build("name")).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] + CookieBuilder::new("name", "value").secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).expires(None).secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).max_age(cookie::time::Duration::hours(12)).secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).domain("example.com").secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).path("/").secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).http_only(true).secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).same_site(cookie::SameSite::Strict).secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).permanent().secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).removal().secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(false).finish(); // $ Alert[rust/insecure-cookie] + Cookie::build("name").secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(Cookie::build("name")).secure(false).build(); // $ Alert[rust/insecure-cookie] // edge cases - Cookie::build(("name", "value")).secure(true).secure(false).build(); // $ MISSING: Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(false).secure(true).build(); // good + Cookie::build(("name", "value")).secure(true).secure(false).build(); // $ Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(false).secure(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] // mutable cookie let mut jar = CookieJar::new(); let mut a = Cookie::new("name", "value"); - jar.add(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] - jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add(a.clone()); // $ Alert[rust/insecure-cookie] + jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] a.set_secure(true); - jar.add(a.clone()); // good + jar.add(a.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] a.set_secure(false); - jar.add(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add(a.clone()); // $ Alert[rust/insecure-cookie] let key = Key::generate(); let mut signed_jar = jar.signed_mut(&key); let mut b = Cookie::named("name"); - signed_jar.add(b.clone()); // $ MISSING: Alert[rust/insecure-cookie] - signed_jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + signed_jar.add(b.clone()); // $ Alert[rust/insecure-cookie] + signed_jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] b.set_secure(sometimes); - signed_jar.add(b.clone()); // $ MISSING: Alert[rust/insecure-cookie] + signed_jar.add(b.clone()); // $ Alert[rust/insecure-cookie] b.set_secure(true); - signed_jar.add(b.clone()); // good + signed_jar.add(b.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] let mut private_jar = jar.private_mut(&key); let mut c = Cookie::from("name"); - private_jar.add(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] - private_jar.add_original(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + private_jar.add(c.clone()); // $ Alert[rust/insecure-cookie] + private_jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] if sometimes { c.set_secure(true); } - private_jar.add(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] + private_jar.add(c.clone()); // $ Alert[rust/insecure-cookie] c.set_secure(true); - private_jar.add(c.clone()); // good + private_jar.add(c.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] let mut d = Cookie::from("name"); - jar.add(d.clone()); // $ MISSING: Alert[rust/insecure-cookie] + jar.add(d.clone()); // $ Alert[rust/insecure-cookie] if sometimes { c.set_secure(true); } else { c.set_partitioned(true); } - jar.add(d.clone()); // good + jar.add(d.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] // parse jar.add(Cookie::parse("name=value; HttpOnly").unwrap()); // $ MISSING: Alert[rust/insecure-cookie] @@ -111,7 +111,7 @@ fn test_cookie(sometimes: bool) { } // partitioned (implies secure) - Cookie::build(("name", "value")).partitioned(true).build(); // good + Cookie::build(("name", "value")).partitioned(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] } fn test_biscotti() { @@ -120,51 +120,51 @@ fn test_biscotti() { // test set_secure, set_partitioned let a = biscotti::ResponseCookie::new("name", "value"); - cookies.insert(a.clone()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(a.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti1 = {}", a.to_string()); let b = a.set_secure(true); - cookies.insert(b.clone()); // good (secure) + cookies.insert(b.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] println!("biscotti2 = {}", b.to_string()); let c = b.set_secure(false); - cookies.insert(c.clone()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(c.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti3 = {}", c.to_string()); let d = c.set_partitioned(true); // (implies secure) - cookies.insert(d.clone()); // good (partitioned) + cookies.insert(d.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] println!("biscotti4 = {}", d.to_string()); let e = d.set_secure(true); - cookies.insert(e.clone()); // good (partitioned + secure) + cookies.insert(e.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] println!("biscotti5 = {}", e.to_string()); let f = e.set_partitioned(false); - cookies.insert(f.clone()); // good (secure) + cookies.insert(f.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] println!("biscotti6 = {}", f.to_string()); let g = f.set_secure(false); - cookies.insert(g.clone()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(g.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti7 = {}", g.to_string()); // variant creation (insecure) let h = biscotti::ResponseCookie::from(("name", "value")); - cookies.insert(h); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(h); // $ Alert[rust/insecure-cookie] // variant uses (all insecure) let i = biscotti::ResponseCookie::new("name", "value"); - cookies.insert(i.clone().set_name("name2")); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_value("value2")); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_http_only(true)); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_same_site(biscotti::SameSite::Strict)); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_max_age(None)); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_path("/")); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().unset_path()); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_domain("example.com")); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().unset_domain()); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().set_expires(None)); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().unset_expires()); // $ MISSING: Alert[rust/insecure-cookie] - cookies.insert(i.clone().make_permanent()); // $ MISSING: Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_name("name2")); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_value("value2")); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_http_only(true)); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_same_site(biscotti::SameSite::Strict)); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_max_age(None)); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_path("/")); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_path()); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_domain("example.com")); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_domain()); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().set_expires(None)); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().unset_expires()); // $ Alert[rust/insecure-cookie] + cookies.insert(i.clone().make_permanent()); // $ Alert[rust/insecure-cookie] } fn main() { From 257a1b0179255d987a7cc5d4a9584ff9fcdd3376 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:55:45 +0100 Subject: [PATCH 076/160] Rust: Refactor sources, sinks into an extensions source file. --- .../security/InsecureCookieExtensions.qll | 49 +++++++++++++++++++ .../security/CWE-614/InsecureCookie.ql | 18 ++++--- rust/ql/src/queries/summary/Stats.qll | 5 +- 3 files changed, 64 insertions(+), 8 deletions(-) create mode 100644 rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll new file mode 100644 index 00000000000..47baa46440c --- /dev/null +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -0,0 +1,49 @@ +/** + * Provides classes and predicates for reasoning about insecure cookie + * vulnerabilities. + */ + +import rust +private import codeql.rust.dataflow.DataFlow +private import codeql.rust.dataflow.FlowSource +private import codeql.rust.dataflow.FlowSink +private import codeql.rust.Concepts +private import codeql.rust.dataflow.internal.DataFlowImpl as DataflowImpl +private import codeql.rust.dataflow.internal.Node + +/** + * Provides default sources, sinks and barriers for detecting insecure + * cookie vulnerabilities, as well as extension points for adding your own. + */ +module InsecureCookie { + /** + * A data flow source for insecure cookie vulnerabilities. + */ + abstract class Source extends DataFlow::Node { } + + /** + * A data flow sink for insecure cookie vulnerabilities. + */ + abstract class Sink extends QuerySink::Range { + override string getSinkType() { result = "InsecureCookie" } + } + + /** + * A barrier for insecure cookie vulnerabilities. + */ + abstract class Barrier extends DataFlow::Node { } + + /** + * A source for insecure cookie vulnerabilities from model data. + */ + private class ModelsAsDataSource extends Source { + ModelsAsDataSource() { sourceNode(this, "cookie-create") } + } + + /** + * A sink for insecure cookie vulnerabilities from model data. + */ + private class ModelsAsDataSink extends Sink { + ModelsAsDataSink() { sinkNode(this, "cookie-use") } + } +} diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index 69d11b85bef..66ef6db7b0b 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -16,22 +16,27 @@ import rust import codeql.rust.dataflow.DataFlow import codeql.rust.dataflow.TaintTracking -import codeql.rust.dataflow.FlowSource -import codeql.rust.dataflow.FlowSink +import codeql.rust.security.InsecureCookieExtensions /** * A data flow configuration for tracking values representing cookies without the - * 'secure' flag set. + * 'secure' attribute set. */ module InsecureCookieConfig implements DataFlow::ConfigSig { + import InsecureCookie + predicate isSource(DataFlow::Node node) { // creation of a cookie or cookie configuration with default, insecure settings - sourceNode(node, "cookie-create") + node instanceof Source } predicate isSink(DataFlow::Node node) { // use of a cookie or cookie configuration - sinkNode(node, "cookie-use") + node instanceof Sink + } + + predicate isBarrier(DataFlow::Node node) { + node instanceof Barrier } predicate observeDiffInformedIncrementalMode() { any() } @@ -42,5 +47,6 @@ module InsecureCookieFlow = TaintTracking::Global; import InsecureCookieFlow::PathGraph from InsecureCookieFlow::PathNode sourceNode, InsecureCookieFlow::PathNode sinkNode -where InsecureCookieFlow::flowPath(sourceNode, sinkNode) +where + InsecureCookieFlow::flowPath(sourceNode, sinkNode) select sinkNode.getNode(), sourceNode, sinkNode, "Cookie attribute 'Secure' is not set to true." diff --git a/rust/ql/src/queries/summary/Stats.qll b/rust/ql/src/queries/summary/Stats.qll index 7a1de4f1314..662bcc26774 100644 --- a/rust/ql/src/queries/summary/Stats.qll +++ b/rust/ql/src/queries/summary/Stats.qll @@ -22,13 +22,14 @@ private import codeql.rust.security.AccessInvalidPointerExtensions private import codeql.rust.security.CleartextLoggingExtensions private import codeql.rust.security.CleartextStorageDatabaseExtensions private import codeql.rust.security.CleartextTransmissionExtensions -private import codeql.rust.security.RequestForgeryExtensions +private import codeql.rust.security.HardcodedCryptographicValueExtensions +private import codeql.rust.security.InsecureCookieExtensions private import codeql.rust.security.LogInjectionExtensions +private import codeql.rust.security.RequestForgeryExtensions private import codeql.rust.security.SqlInjectionExtensions private import codeql.rust.security.TaintedPathExtensions private import codeql.rust.security.UncontrolledAllocationSizeExtensions private import codeql.rust.security.WeakSensitiveDataHashingExtensions -private import codeql.rust.security.HardcodedCryptographicValueExtensions /** * Gets a count of the total number of lines of code in the database. From 2654affeee2a5ade67a28eac8efdee108e4328df Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 Sep 2025 12:39:50 +0100 Subject: [PATCH 077/160] Rust: Account for the 'secure' and 'partitioned' attributes. --- .../codeql/rust/frameworks/biscotti.model.yml | 4 +- .../codeql/rust/frameworks/cookie.model.yml | 8 +- .../security/InsecureCookieExtensions.qll | 32 +++ .../security/CWE-614/InsecureCookie.ql | 42 +++- .../security/CWE-614/CookieSet.expected | 44 ++++ .../query-tests/security/CWE-614/CookieSet.ql | 7 + .../security/CWE-614/InsecureCookie.expected | 196 +++++++----------- .../test/query-tests/security/CWE-614/main.rs | 14 +- 8 files changed, 213 insertions(+), 134 deletions(-) create mode 100644 rust/ql/test/query-tests/security/CWE-614/CookieSet.expected create mode 100644 rust/ql/test/query-tests/security/CWE-614/CookieSet.ql diff --git a/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml b/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml index b70a27f74d1..2e9b1213ed7 100644 --- a/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/biscotti.model.yml @@ -16,8 +16,8 @@ extensions: pack: codeql/rust-all extensible: summaryModel data: - - ["::set_secure", "Argument[self]", "ReturnValue", "taint", "manual"] - - ["::set_partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_secure", "Argument[self].OptionalBarrier[cookie-secure-arg0]", "ReturnValue", "taint", "manual"] + - ["::set_partitioned", "Argument[self].OptionalBarrier[cookie-partitioned-arg0]", "ReturnValue", "taint", "manual"] - ["::set_name", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::set_value", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::set_http_only", "Argument[self]", "ReturnValue", "taint", "manual"] diff --git a/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml b/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml index f9c8cd647c5..e40fd8ecf71 100644 --- a/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/cookie.model.yml @@ -26,8 +26,8 @@ extensions: pack: codeql/rust-all extensible: summaryModel data: - - ["::secure", "Argument[self]", "ReturnValue", "taint", "manual"] - - ["::partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::secure", "Argument[self].OptionalBarrier[cookie-secure-arg0]", "ReturnValue", "taint", "manual"] + - ["::partitioned", "Argument[self].OptionalBarrier[cookie-partitioned-arg0]", "ReturnValue", "taint", "manual"] - ["::expires", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::max_age", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::domain", "Argument[self]", "ReturnValue", "taint", "manual"] @@ -36,5 +36,5 @@ extensions: - ["::same_site", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::permanent", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::removal", "Argument[self]", "ReturnValue", "taint", "manual"] - - ["::set_secure", "Argument[self]", "ReturnValue", "taint", "manual"] - - ["::set_partitioned", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::set_secure", "Argument[self].OptionalBarrier[cookie-secure-arg0]", "ReturnValue", "taint", "manual"] + - ["::set_partitioned", "Argument[self].OptionalBarrier[cookie-partitioned-arg0]", "ReturnValue", "taint", "manual"] diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 47baa46440c..aa534a9c1ea 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -46,4 +46,36 @@ module InsecureCookie { private class ModelsAsDataSink extends Sink { ModelsAsDataSink() { sinkNode(this, "cookie-use") } } + + /** + * Holds if cookie attribute `attrib` (`secure` or `partitioned`) is set to `value` (`true` or `false`) at `node`. + * A value that cannot be determined is treated as `false`. + * + * This references models-as-data optional barrier nodes, for example `OptionalBarrier[cookie-secure-arg0]`. + */ + predicate cookieSetNode(DataFlow::Node node, string attrib, boolean value) { + exists( + FlowSummaryNode summaryNode, string barrierName, CallExprBase ce, int arg, + DataFlow::Node argNode + | + // decode a `cookie-`... optional barrier + DataflowImpl::optionalBarrier(summaryNode, barrierName) and + attrib = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 1) and + arg = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 2).toInt() and + // find a call and arg referenced by this optional barrier + ce.getStaticTarget() = summaryNode.getSummarizedCallable() and + ce.getArg(arg) = argNode.asExpr().getExpr() and + // check if the argument is always `true` + ( + if + forex(DataFlow::Node argSourceNode | DataFlow::localFlow(argSourceNode, argNode) | + argSourceNode.asExpr().getExpr().(BooleanLiteralExpr).getTextValue() = "true" + ) + then value = true // `true` flow to here + else value = false // `false` or unknown + ) and + // and the node `node` where this happens + node.asExpr().getExpr() = ce + ) + } } diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index 66ef6db7b0b..987940a2f0a 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -20,7 +20,8 @@ import codeql.rust.security.InsecureCookieExtensions /** * A data flow configuration for tracking values representing cookies without the - * 'secure' attribute set. + * 'secure' attribute set. This is the primary data flow configurationn for this + * query. */ module InsecureCookieConfig implements DataFlow::ConfigSig { import InsecureCookie @@ -28,6 +29,9 @@ module InsecureCookieConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { // creation of a cookie or cookie configuration with default, insecure settings node instanceof Source + or + // setting the 'secure' attribute to false (or an unknown value) + cookieSetNode(node, "secure", false) } predicate isSink(DataFlow::Node node) { @@ -36,6 +40,37 @@ module InsecureCookieConfig implements DataFlow::ConfigSig { } predicate isBarrier(DataFlow::Node node) { + // setting the 'secure' attribute to true + cookieSetNode(node, "secure", true) + or + node instanceof Barrier + } + + predicate observeDiffInformedIncrementalMode() { any() } +} + +/** + * A data flow configuration for tracking values representing cookies with the + * 'partitioned' attribute set. This is a secondary data flow configuration used + * to filter out unwanted results. + */ +module PartitionedCookieConfig implements DataFlow::ConfigSig { + import InsecureCookie + + predicate isSource(DataFlow::Node node) { + // setting the 'partitioned' attribute to true + cookieSetNode(node, "partitioned", true) + } + + predicate isSink(DataFlow::Node node) { + // use of a cookie or cookie configuration + node instanceof Sink + } + + predicate isBarrier(DataFlow::Node node) { + // setting the 'partitioned' attribute to false (or an unknown value) + cookieSetNode(node, "partitioned", false) + or node instanceof Barrier } @@ -44,9 +79,12 @@ module InsecureCookieConfig implements DataFlow::ConfigSig { module InsecureCookieFlow = TaintTracking::Global; +module PartitionedCookieFlow = TaintTracking::Global; + import InsecureCookieFlow::PathGraph from InsecureCookieFlow::PathNode sourceNode, InsecureCookieFlow::PathNode sinkNode where - InsecureCookieFlow::flowPath(sourceNode, sinkNode) + InsecureCookieFlow::flowPath(sourceNode, sinkNode) and + not PartitionedCookieFlow::flow(_, sinkNode.getNode()) select sinkNode.getNode(), sourceNode, sinkNode, "Cookie attribute 'Secure' is not set to true." diff --git a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected new file mode 100644 index 00000000000..eccdbaec90a --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected @@ -0,0 +1,44 @@ +| main.rs:8:19:8:64 | ... .secure(...) | secure | false | +| main.rs:12:19:12:63 | ... .secure(...) | secure | true | +| main.rs:20:5:20:54 | ... .secure(...) | secure | false | +| main.rs:21:5:21:55 | ... .secure(...) | secure | false | +| main.rs:24:5:24:51 | ... .secure(...) | secure | false | +| main.rs:25:5:25:52 | ... .secure(...) | secure | false | +| main.rs:26:5:26:50 | ... .secure(...) | secure | false | +| main.rs:27:5:27:51 | ... .secure(...) | secure | false | +| main.rs:28:5:28:60 | ... .secure(...) | secure | false | +| main.rs:29:5:29:60 | ... .secure(...) | secure | false | +| main.rs:33:9:33:58 | ... .secure(...) | secure | false | +| main.rs:35:9:35:58 | ... .secure(...) | secure | false | +| main.rs:39:5:39:53 | ... .secure(...) | secure | false | +| main.rs:40:5:40:64 | ... .secure(...) | secure | false | +| main.rs:41:5:41:93 | ... .secure(...) | secure | false | +| main.rs:42:5:42:72 | ... .secure(...) | secure | false | +| main.rs:43:5:43:60 | ... .secure(...) | secure | false | +| main.rs:44:5:44:66 | ... .secure(...) | secure | false | +| main.rs:45:5:45:86 | ... .secure(...) | secure | false | +| main.rs:46:5:46:62 | ... .secure(...) | secure | false | +| main.rs:47:5:47:60 | ... .secure(...) | secure | false | +| main.rs:48:5:48:50 | ... .secure(...) | secure | false | +| main.rs:49:5:49:39 | ... .secure(...) | secure | false | +| main.rs:50:5:50:54 | ... .secure(...) | secure | false | +| main.rs:53:5:53:49 | ... .secure(...) | secure | true | +| main.rs:53:5:53:63 | ... .secure(...) | secure | false | +| main.rs:54:5:54:50 | ... .secure(...) | secure | false | +| main.rs:54:5:54:63 | ... .secure(...) | secure | true | +| main.rs:61:5:61:22 | a.set_secure(...) | secure | true | +| main.rs:63:5:63:23 | a.set_secure(...) | secure | false | +| main.rs:71:5:71:27 | b.set_secure(...) | secure | false | +| main.rs:73:5:73:22 | b.set_secure(...) | secure | true | +| main.rs:81:9:81:26 | c.set_secure(...) | secure | true | +| main.rs:84:5:84:22 | c.set_secure(...) | secure | true | +| main.rs:90:9:90:26 | c.set_secure(...) | secure | true | +| main.rs:92:9:92:31 | c.set_partitioned(...) | partitioned | true | +| main.rs:109:9:109:26 | e.set_secure(...) | secure | true | +| main.rs:114:5:114:54 | ... .partitioned(...) | partitioned | true | +| main.rs:126:13:126:30 | a.set_secure(...) | secure | true | +| main.rs:130:13:130:31 | b.set_secure(...) | secure | false | +| main.rs:134:13:134:35 | c.set_partitioned(...) | partitioned | true | +| main.rs:138:13:138:30 | d.set_secure(...) | secure | true | +| main.rs:142:13:142:36 | e.set_partitioned(...) | partitioned | false | +| main.rs:146:13:146:31 | f.set_secure(...) | secure | false | diff --git a/rust/ql/test/query-tests/security/CWE-614/CookieSet.ql b/rust/ql/test/query-tests/security/CWE-614/CookieSet.ql new file mode 100644 index 00000000000..c038e6de44b --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-614/CookieSet.ql @@ -0,0 +1,7 @@ +import rust +import codeql.rust.dataflow.DataFlow +import codeql.rust.security.InsecureCookieExtensions + +from DataFlow::Node node, string state, boolean value +where InsecureCookie::cookieSetNode(node, state, value) +select node, state, value diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected index b4bd897ca6f..9d9975a1a36 100644 --- a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -1,31 +1,52 @@ #select | main.rs:8:66:8:70 | build | main.rs:8:19:8:31 | ...::build | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:12:65:12:69 | build | main.rs:12:19:12:31 | ...::build | main.rs:12:65:12:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:8:66:8:70 | build | main.rs:8:19:8:64 | ... .secure(...) | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:16:52:16:56 | build | main.rs:16:19:16:31 | ...::build | main.rs:16:52:16:56 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:20:56:20:60 | build | main.rs:20:5:20:17 | ...::build | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:20:56:20:60 | build | main.rs:20:5:20:54 | ... .secure(...) | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:21:57:21:61 | build | main.rs:21:5:21:17 | ...::build | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:21:57:21:61 | build | main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:24:53:24:57 | build | main.rs:24:5:24:17 | ...::build | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:24:53:24:57 | build | main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:25:54:25:58 | build | main.rs:25:5:25:17 | ...::build | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:25:54:25:58 | build | main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:26:52:26:56 | build | main.rs:26:5:26:17 | ...::build | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:26:52:26:56 | build | main.rs:26:5:26:50 | ... .secure(...) | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:27:53:27:57 | build | main.rs:27:5:27:17 | ...::build | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:27:53:27:57 | build | main.rs:27:5:27:51 | ... .secure(...) | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:28:62:28:66 | build | main.rs:28:5:28:17 | ...::build | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:28:62:28:66 | build | main.rs:28:5:28:60 | ... .secure(...) | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:29:62:29:66 | build | main.rs:29:5:29:17 | ...::build | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:29:62:29:66 | build | main.rs:29:5:29:60 | ... .secure(...) | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:33:60:33:64 | build | main.rs:33:9:33:21 | ...::build | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:33:60:33:64 | build | main.rs:33:9:33:58 | ... .secure(...) | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:35:60:35:64 | build | main.rs:35:9:35:21 | ...::build | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:35:60:35:64 | build | main.rs:35:9:35:58 | ... .secure(...) | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:39:55:39:59 | build | main.rs:39:5:39:22 | ...::new | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:39:55:39:59 | build | main.rs:39:5:39:53 | ... .secure(...) | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:40:66:40:70 | build | main.rs:40:5:40:17 | ...::build | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:40:66:40:70 | build | main.rs:40:5:40:64 | ... .secure(...) | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:41:95:41:99 | build | main.rs:41:5:41:17 | ...::build | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:41:95:41:99 | build | main.rs:41:5:41:93 | ... .secure(...) | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:42:74:42:78 | build | main.rs:42:5:42:17 | ...::build | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:42:74:42:78 | build | main.rs:42:5:42:72 | ... .secure(...) | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:43:62:43:66 | build | main.rs:43:5:43:17 | ...::build | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:43:62:43:66 | build | main.rs:43:5:43:60 | ... .secure(...) | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:44:68:44:72 | build | main.rs:44:5:44:17 | ...::build | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:44:68:44:72 | build | main.rs:44:5:44:66 | ... .secure(...) | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:45:88:45:92 | build | main.rs:45:5:45:17 | ...::build | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:45:88:45:92 | build | main.rs:45:5:45:86 | ... .secure(...) | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:46:64:46:68 | build | main.rs:46:5:46:17 | ...::build | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:46:64:46:68 | build | main.rs:46:5:46:62 | ... .secure(...) | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:47:62:47:66 | build | main.rs:47:5:47:17 | ...::build | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:47:62:47:66 | build | main.rs:47:5:47:60 | ... .secure(...) | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:48:52:48:57 | finish | main.rs:48:5:48:17 | ...::build | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | +| main.rs:48:52:48:57 | finish | main.rs:48:5:48:50 | ... .secure(...) | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | | main.rs:49:41:49:45 | build | main.rs:49:5:49:17 | ...::build | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:49:41:49:45 | build | main.rs:49:5:49:39 | ... .secure(...) | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:50:56:50:60 | build | main.rs:50:5:50:17 | ...::build | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:53:65:53:69 | build | main.rs:53:5:53:17 | ...::build | main.rs:53:65:53:69 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:54:65:54:69 | build | main.rs:54:5:54:17 | ...::build | main.rs:54:65:54:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:50:56:50:60 | build | main.rs:50:5:50:54 | ... .secure(...) | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:53:65:53:69 | build | main.rs:53:5:53:63 | ... .secure(...) | main.rs:53:65:53:69 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:59:9:59:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:59:9:59:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:60:9:60:20 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:60:9:60:20 | add_original | Cookie attribute 'Secure' is not set to true. | | main.rs:62:9:62:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:62:9:62:11 | add | Cookie attribute 'Secure' is not set to true. | @@ -40,14 +61,9 @@ | main.rs:85:17:85:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:85:17:85:19 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:88:9:88:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:88:9:88:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:94:9:94:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:94:9:94:11 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:114:56:114:60 | build | main.rs:114:5:114:17 | ...::build | main.rs:114:56:114:60 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:123:13:123:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:123:13:123:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:127:13:127:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:127:13:127:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:131:13:131:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:131:13:131:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:135:13:135:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:135:13:135:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:139:13:139:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:139:13:139:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:143:13:143:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:143:13:143:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:147:13:147:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:147:13:147:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:131:13:131:18 | insert | main.rs:130:13:130:31 | b.set_secure(...) | main.rs:131:13:131:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:147:13:147:18 | insert | main.rs:146:13:146:31 | f.set_secure(...) | main.rs:147:13:147:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:152:13:152:18 | insert | main.rs:151:13:151:42 | ...::from | main.rs:152:13:152:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:156:13:156:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:156:13:156:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:157:13:157:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:157:13:157:18 | insert | Cookie attribute 'Secure' is not set to true. | @@ -63,95 +79,85 @@ | main.rs:167:13:167:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:167:13:167:18 | insert | Cookie attribute 'Secure' is not set to true. | edges | main.rs:8:19:8:31 | ...::build | main.rs:8:19:8:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:41 | +| main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:40 | | main.rs:8:19:8:64 | ... .secure(...) | main.rs:8:66:8:70 | build | provenance | MaD:2 Sink:MaD:2 | -| main.rs:12:19:12:31 | ...::build | main.rs:12:19:12:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:12:19:12:50 | ...::build(...) | main.rs:12:19:12:63 | ... .secure(...) | provenance | MaD:41 | -| main.rs:12:19:12:63 | ... .secure(...) | main.rs:12:65:12:69 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:16:19:16:31 | ...::build | main.rs:16:19:16:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | | main.rs:16:19:16:50 | ...::build(...) | main.rs:16:52:16:56 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:20:5:20:17 | ...::build | main.rs:20:5:20:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:20:5:20:36 | ...::build(...) | main.rs:20:5:20:54 | ... .secure(...) | provenance | MaD:41 | +| main.rs:20:5:20:36 | ...::build(...) | main.rs:20:5:20:54 | ... .secure(...) | provenance | MaD:40 | | main.rs:20:5:20:54 | ... .secure(...) | main.rs:20:56:20:60 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:21:5:21:17 | ...::build | main.rs:21:5:21:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:41 | +| main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:40 | | main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:24:5:24:17 | ...::build | main.rs:24:5:24:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:41 | +| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:40 | | main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:25:5:25:17 | ...::build | main.rs:25:5:25:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:41 | +| main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:40 | | main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:26:5:26:17 | ...::build | main.rs:26:5:26:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:26:5:26:36 | ...::build(...) | main.rs:26:5:26:50 | ... .secure(...) | provenance | MaD:41 | +| main.rs:26:5:26:36 | ...::build(...) | main.rs:26:5:26:50 | ... .secure(...) | provenance | MaD:40 | | main.rs:26:5:26:50 | ... .secure(...) | main.rs:26:52:26:56 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:27:5:27:17 | ...::build | main.rs:27:5:27:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:27:5:27:36 | ...::build(...) | main.rs:27:5:27:51 | ... .secure(...) | provenance | MaD:41 | +| main.rs:27:5:27:36 | ...::build(...) | main.rs:27:5:27:51 | ... .secure(...) | provenance | MaD:40 | | main.rs:27:5:27:51 | ... .secure(...) | main.rs:27:53:27:57 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:28:5:28:17 | ...::build | main.rs:28:5:28:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:28:5:28:36 | ...::build(...) | main.rs:28:5:28:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:28:5:28:36 | ...::build(...) | main.rs:28:5:28:60 | ... .secure(...) | provenance | MaD:40 | | main.rs:28:5:28:60 | ... .secure(...) | main.rs:28:62:28:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:29:5:29:17 | ...::build | main.rs:29:5:29:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:29:5:29:36 | ...::build(...) | main.rs:29:5:29:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:29:5:29:36 | ...::build(...) | main.rs:29:5:29:60 | ... .secure(...) | provenance | MaD:40 | | main.rs:29:5:29:60 | ... .secure(...) | main.rs:29:62:29:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:33:9:33:21 | ...::build | main.rs:33:9:33:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:33:9:33:40 | ...::build(...) | main.rs:33:9:33:58 | ... .secure(...) | provenance | MaD:41 | +| main.rs:33:9:33:40 | ...::build(...) | main.rs:33:9:33:58 | ... .secure(...) | provenance | MaD:40 | | main.rs:33:9:33:58 | ... .secure(...) | main.rs:33:60:33:64 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:35:9:35:21 | ...::build | main.rs:35:9:35:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:35:9:35:40 | ...::build(...) | main.rs:35:9:35:58 | ... .secure(...) | provenance | MaD:41 | +| main.rs:35:9:35:40 | ...::build(...) | main.rs:35:9:35:58 | ... .secure(...) | provenance | MaD:40 | | main.rs:35:9:35:58 | ... .secure(...) | main.rs:35:60:35:64 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:39:5:39:22 | ...::new | main.rs:39:5:39:39 | ...::new(...) | provenance | Src:MaD:16 MaD:16 | -| main.rs:39:5:39:39 | ...::new(...) | main.rs:39:5:39:53 | ... .secure(...) | provenance | MaD:41 | +| main.rs:39:5:39:39 | ...::new(...) | main.rs:39:5:39:53 | ... .secure(...) | provenance | MaD:40 | | main.rs:39:5:39:53 | ... .secure(...) | main.rs:39:55:39:59 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:40:5:40:17 | ...::build | main.rs:40:5:40:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:40:5:40:36 | ...::build(...) | main.rs:40:5:40:50 | ... .expires(...) | provenance | MaD:33 | -| main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:5:40:64 | ... .secure(...) | provenance | MaD:41 | +| main.rs:40:5:40:36 | ...::build(...) | main.rs:40:5:40:50 | ... .expires(...) | provenance | MaD:32 | +| main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:5:40:64 | ... .secure(...) | provenance | MaD:40 | | main.rs:40:5:40:64 | ... .secure(...) | main.rs:40:66:40:70 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:41:5:41:17 | ...::build | main.rs:41:5:41:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:41:5:41:36 | ...::build(...) | main.rs:41:5:41:79 | ... .max_age(...) | provenance | MaD:35 | -| main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:5:41:93 | ... .secure(...) | provenance | MaD:41 | +| main.rs:41:5:41:36 | ...::build(...) | main.rs:41:5:41:79 | ... .max_age(...) | provenance | MaD:34 | +| main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:5:41:93 | ... .secure(...) | provenance | MaD:40 | | main.rs:41:5:41:93 | ... .secure(...) | main.rs:41:95:41:99 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:42:5:42:17 | ...::build | main.rs:42:5:42:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:42:5:42:36 | ...::build(...) | main.rs:42:5:42:58 | ... .domain(...) | provenance | MaD:32 | -| main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:5:42:72 | ... .secure(...) | provenance | MaD:41 | +| main.rs:42:5:42:36 | ...::build(...) | main.rs:42:5:42:58 | ... .domain(...) | provenance | MaD:31 | +| main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:5:42:72 | ... .secure(...) | provenance | MaD:40 | | main.rs:42:5:42:72 | ... .secure(...) | main.rs:42:74:42:78 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:43:5:43:17 | ...::build | main.rs:43:5:43:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:43:5:43:36 | ...::build(...) | main.rs:43:5:43:46 | ... .path(...) | provenance | MaD:37 | -| main.rs:43:5:43:46 | ... .path(...) | main.rs:43:5:43:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:43:5:43:36 | ...::build(...) | main.rs:43:5:43:46 | ... .path(...) | provenance | MaD:36 | +| main.rs:43:5:43:46 | ... .path(...) | main.rs:43:5:43:60 | ... .secure(...) | provenance | MaD:40 | | main.rs:43:5:43:60 | ... .secure(...) | main.rs:43:62:43:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:44:5:44:17 | ...::build | main.rs:44:5:44:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:44:5:44:36 | ...::build(...) | main.rs:44:5:44:52 | ... .http_only(...) | provenance | MaD:34 | -| main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:5:44:66 | ... .secure(...) | provenance | MaD:41 | +| main.rs:44:5:44:36 | ...::build(...) | main.rs:44:5:44:52 | ... .http_only(...) | provenance | MaD:33 | +| main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:5:44:66 | ... .secure(...) | provenance | MaD:40 | | main.rs:44:5:44:66 | ... .secure(...) | main.rs:44:68:44:72 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:45:5:45:17 | ...::build | main.rs:45:5:45:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:45:5:45:36 | ...::build(...) | main.rs:45:5:45:72 | ... .same_site(...) | provenance | MaD:40 | -| main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:5:45:86 | ... .secure(...) | provenance | MaD:41 | +| main.rs:45:5:45:36 | ...::build(...) | main.rs:45:5:45:72 | ... .same_site(...) | provenance | MaD:39 | +| main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:5:45:86 | ... .secure(...) | provenance | MaD:40 | | main.rs:45:5:45:86 | ... .secure(...) | main.rs:45:88:45:92 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:46:5:46:17 | ...::build | main.rs:46:5:46:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:46:5:46:36 | ...::build(...) | main.rs:46:5:46:48 | ... .permanent() | provenance | MaD:38 | -| main.rs:46:5:46:48 | ... .permanent() | main.rs:46:5:46:62 | ... .secure(...) | provenance | MaD:41 | +| main.rs:46:5:46:36 | ...::build(...) | main.rs:46:5:46:48 | ... .permanent() | provenance | MaD:37 | +| main.rs:46:5:46:48 | ... .permanent() | main.rs:46:5:46:62 | ... .secure(...) | provenance | MaD:40 | | main.rs:46:5:46:62 | ... .secure(...) | main.rs:46:64:46:68 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:47:5:47:17 | ...::build | main.rs:47:5:47:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:47:5:47:36 | ...::build(...) | main.rs:47:5:47:46 | ... .removal() | provenance | MaD:39 | -| main.rs:47:5:47:46 | ... .removal() | main.rs:47:5:47:60 | ... .secure(...) | provenance | MaD:41 | +| main.rs:47:5:47:36 | ...::build(...) | main.rs:47:5:47:46 | ... .removal() | provenance | MaD:38 | +| main.rs:47:5:47:46 | ... .removal() | main.rs:47:5:47:60 | ... .secure(...) | provenance | MaD:40 | | main.rs:47:5:47:60 | ... .secure(...) | main.rs:47:62:47:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:48:5:48:17 | ...::build | main.rs:48:5:48:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:48:5:48:36 | ...::build(...) | main.rs:48:5:48:50 | ... .secure(...) | provenance | MaD:41 | +| main.rs:48:5:48:36 | ...::build(...) | main.rs:48:5:48:50 | ... .secure(...) | provenance | MaD:40 | | main.rs:48:5:48:50 | ... .secure(...) | main.rs:48:52:48:57 | finish | provenance | MaD:3 Sink:MaD:3 | | main.rs:49:5:49:17 | ...::build | main.rs:49:5:49:25 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:49:5:49:25 | ...::build(...) | main.rs:49:5:49:39 | ... .secure(...) | provenance | MaD:41 | +| main.rs:49:5:49:25 | ...::build(...) | main.rs:49:5:49:39 | ... .secure(...) | provenance | MaD:40 | | main.rs:49:5:49:39 | ... .secure(...) | main.rs:49:41:49:45 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:50:5:50:17 | ...::build | main.rs:50:5:50:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:50:5:50:40 | ...::build(...) | main.rs:50:5:50:54 | ... .secure(...) | provenance | MaD:41 | +| main.rs:50:5:50:40 | ...::build(...) | main.rs:50:5:50:54 | ... .secure(...) | provenance | MaD:40 | | main.rs:50:5:50:54 | ... .secure(...) | main.rs:50:56:50:60 | build | provenance | MaD:2 Sink:MaD:2 | -| main.rs:53:5:53:17 | ...::build | main.rs:53:5:53:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:53:5:53:36 | ...::build(...) | main.rs:53:5:53:49 | ... .secure(...) | provenance | MaD:41 | -| main.rs:53:5:53:49 | ... .secure(...) | main.rs:53:5:53:63 | ... .secure(...) | provenance | MaD:41 | | main.rs:53:5:53:63 | ... .secure(...) | main.rs:53:65:53:69 | build | provenance | MaD:2 Sink:MaD:2 | -| main.rs:54:5:54:17 | ...::build | main.rs:54:5:54:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:54:5:54:36 | ...::build(...) | main.rs:54:5:54:50 | ... .secure(...) | provenance | MaD:41 | -| main.rs:54:5:54:50 | ... .secure(...) | main.rs:54:5:54:63 | ... .secure(...) | provenance | MaD:41 | -| main.rs:54:5:54:63 | ... .secure(...) | main.rs:54:65:54:69 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:58:9:58:13 | mut a | main.rs:59:13:59:13 | a | provenance | | | main.rs:58:9:58:13 | mut a | main.rs:59:13:59:21 | a.clone() | provenance | MaD:17 | | main.rs:58:9:58:13 | mut a | main.rs:60:22:60:22 | a | provenance | | @@ -217,21 +223,14 @@ edges | main.rs:94:13:94:13 | d | main.rs:94:13:94:21 | d.clone() | provenance | MaD:17 | | main.rs:94:13:94:21 | d.clone() | main.rs:94:9:94:11 | add | provenance | MaD:4 Sink:MaD:4 | | main.rs:114:5:114:17 | ...::build | main.rs:114:5:114:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:114:5:114:36 | ...::build(...) | main.rs:114:5:114:54 | ... .partitioned(...) | provenance | MaD:36 | +| main.rs:114:5:114:36 | ...::build(...) | main.rs:114:5:114:54 | ... .partitioned(...) | provenance | MaD:35 | | main.rs:114:5:114:54 | ... .partitioned(...) | main.rs:114:56:114:60 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:122:9:122:9 | a | main.rs:123:20:123:20 | a | provenance | | | main.rs:122:9:122:9 | a | main.rs:123:20:123:28 | a.clone() | provenance | MaD:17 | -| main.rs:122:9:122:9 | a | main.rs:126:13:126:30 | a.set_secure(...) | provenance | MaD:27 | | main.rs:122:13:122:41 | ...::new | main.rs:122:13:122:58 | ...::new(...) | provenance | Src:MaD:11 MaD:11 | | main.rs:122:13:122:58 | ...::new(...) | main.rs:122:9:122:9 | a | provenance | | | main.rs:123:20:123:20 | a | main.rs:123:20:123:28 | a.clone() | provenance | MaD:17 | | main.rs:123:20:123:28 | a.clone() | main.rs:123:13:123:18 | insert | provenance | MaD:1 Sink:MaD:1 | -| main.rs:126:9:126:9 | b | main.rs:127:20:127:20 | b | provenance | | -| main.rs:126:9:126:9 | b | main.rs:127:20:127:28 | b.clone() | provenance | MaD:17 | -| main.rs:126:9:126:9 | b | main.rs:130:13:130:31 | b.set_secure(...) | provenance | MaD:27 | -| main.rs:126:13:126:30 | a.set_secure(...) | main.rs:126:9:126:9 | b | provenance | | -| main.rs:127:20:127:20 | b | main.rs:127:20:127:28 | b.clone() | provenance | MaD:17 | -| main.rs:127:20:127:28 | b.clone() | main.rs:127:13:127:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:130:9:130:9 | c | main.rs:131:20:131:20 | c | provenance | | | main.rs:130:9:130:9 | c | main.rs:131:20:131:28 | c.clone() | provenance | MaD:17 | | main.rs:130:9:130:9 | c | main.rs:134:13:134:35 | c.set_partitioned(...) | provenance | MaD:24 | @@ -240,22 +239,9 @@ edges | main.rs:131:20:131:28 | c.clone() | main.rs:131:13:131:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:134:9:134:9 | d | main.rs:135:20:135:20 | d | provenance | | | main.rs:134:9:134:9 | d | main.rs:135:20:135:28 | d.clone() | provenance | MaD:17 | -| main.rs:134:9:134:9 | d | main.rs:138:13:138:30 | d.set_secure(...) | provenance | MaD:27 | | main.rs:134:13:134:35 | c.set_partitioned(...) | main.rs:134:9:134:9 | d | provenance | | | main.rs:135:20:135:20 | d | main.rs:135:20:135:28 | d.clone() | provenance | MaD:17 | | main.rs:135:20:135:28 | d.clone() | main.rs:135:13:135:18 | insert | provenance | MaD:1 Sink:MaD:1 | -| main.rs:138:9:138:9 | e | main.rs:139:20:139:20 | e | provenance | | -| main.rs:138:9:138:9 | e | main.rs:139:20:139:28 | e.clone() | provenance | MaD:17 | -| main.rs:138:9:138:9 | e | main.rs:142:13:142:36 | e.set_partitioned(...) | provenance | MaD:24 | -| main.rs:138:13:138:30 | d.set_secure(...) | main.rs:138:9:138:9 | e | provenance | | -| main.rs:139:20:139:20 | e | main.rs:139:20:139:28 | e.clone() | provenance | MaD:17 | -| main.rs:139:20:139:28 | e.clone() | main.rs:139:13:139:18 | insert | provenance | MaD:1 Sink:MaD:1 | -| main.rs:142:9:142:9 | f | main.rs:143:20:143:20 | f | provenance | | -| main.rs:142:9:142:9 | f | main.rs:143:20:143:28 | f.clone() | provenance | MaD:17 | -| main.rs:142:9:142:9 | f | main.rs:146:13:146:31 | f.set_secure(...) | provenance | MaD:27 | -| main.rs:142:13:142:36 | e.set_partitioned(...) | main.rs:142:9:142:9 | f | provenance | | -| main.rs:143:20:143:20 | f | main.rs:143:20:143:28 | f.clone() | provenance | MaD:17 | -| main.rs:143:20:143:28 | f.clone() | main.rs:143:13:143:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:146:9:146:9 | g | main.rs:147:20:147:20 | g | provenance | | | main.rs:146:9:146:9 | g | main.rs:147:20:147:28 | g.clone() | provenance | MaD:17 | | main.rs:146:13:146:31 | f.set_secure(...) | main.rs:146:9:146:9 | g | provenance | | @@ -295,7 +281,7 @@ edges | main.rs:156:20:156:28 | i.clone() | main.rs:156:20:156:46 | ... .set_name(...) | provenance | MaD:23 | | main.rs:156:20:156:46 | ... .set_name(...) | main.rs:156:13:156:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:157:20:157:20 | i | main.rs:157:20:157:28 | i.clone() | provenance | MaD:17 | -| main.rs:157:20:157:28 | i.clone() | main.rs:157:20:157:48 | ... .set_value(...) | provenance | MaD:28 | +| main.rs:157:20:157:28 | i.clone() | main.rs:157:20:157:48 | ... .set_value(...) | provenance | MaD:27 | | main.rs:157:20:157:48 | ... .set_value(...) | main.rs:157:13:157:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:158:20:158:20 | i | main.rs:158:20:158:28 | i.clone() | provenance | MaD:17 | | main.rs:158:20:158:28 | i.clone() | main.rs:158:20:158:48 | ... .set_http_only(...) | provenance | MaD:21 | @@ -310,19 +296,19 @@ edges | main.rs:161:20:161:28 | i.clone() | main.rs:161:20:161:42 | ... .set_path(...) | provenance | MaD:25 | | main.rs:161:20:161:42 | ... .set_path(...) | main.rs:161:13:161:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:162:20:162:20 | i | main.rs:162:20:162:28 | i.clone() | provenance | MaD:17 | -| main.rs:162:20:162:28 | i.clone() | main.rs:162:20:162:41 | ... .unset_path() | provenance | MaD:31 | +| main.rs:162:20:162:28 | i.clone() | main.rs:162:20:162:41 | ... .unset_path() | provenance | MaD:30 | | main.rs:162:20:162:41 | ... .unset_path() | main.rs:162:13:162:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:163:20:163:20 | i | main.rs:163:20:163:28 | i.clone() | provenance | MaD:17 | | main.rs:163:20:163:28 | i.clone() | main.rs:163:20:163:54 | ... .set_domain(...) | provenance | MaD:19 | | main.rs:163:20:163:54 | ... .set_domain(...) | main.rs:163:13:163:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:164:20:164:20 | i | main.rs:164:20:164:28 | i.clone() | provenance | MaD:17 | -| main.rs:164:20:164:28 | i.clone() | main.rs:164:20:164:43 | ... .unset_domain() | provenance | MaD:29 | +| main.rs:164:20:164:28 | i.clone() | main.rs:164:20:164:43 | ... .unset_domain() | provenance | MaD:28 | | main.rs:164:20:164:43 | ... .unset_domain() | main.rs:164:13:164:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:165:20:165:20 | i | main.rs:165:20:165:28 | i.clone() | provenance | MaD:17 | | main.rs:165:20:165:28 | i.clone() | main.rs:165:20:165:46 | ... .set_expires(...) | provenance | MaD:20 | | main.rs:165:20:165:46 | ... .set_expires(...) | main.rs:165:13:165:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:166:20:166:20 | i | main.rs:166:20:166:28 | i.clone() | provenance | MaD:17 | -| main.rs:166:20:166:28 | i.clone() | main.rs:166:20:166:44 | ... .unset_expires() | provenance | MaD:30 | +| main.rs:166:20:166:28 | i.clone() | main.rs:166:20:166:44 | ... .unset_expires() | provenance | MaD:29 | | main.rs:166:20:166:44 | ... .unset_expires() | main.rs:166:13:166:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:167:20:167:20 | i | main.rs:167:20:167:28 | i.clone() | provenance | MaD:17 | | main.rs:167:20:167:28 | i.clone() | main.rs:167:20:167:45 | ... .make_permanent() | provenance | MaD:18 | @@ -351,33 +337,28 @@ models | 21 | Summary: ::set_http_only; Argument[self]; ReturnValue; taint | | 22 | Summary: ::set_max_age; Argument[self]; ReturnValue; taint | | 23 | Summary: ::set_name; Argument[self]; ReturnValue; taint | -| 24 | Summary: ::set_partitioned; Argument[self]; ReturnValue; taint | +| 24 | Summary: ::set_partitioned; Argument[self].OptionalBarrier[cookie-partitioned-arg0]; ReturnValue; taint | | 25 | Summary: ::set_path; Argument[self]; ReturnValue; taint | | 26 | Summary: ::set_same_site; Argument[self]; ReturnValue; taint | -| 27 | Summary: ::set_secure; Argument[self]; ReturnValue; taint | -| 28 | Summary: ::set_value; Argument[self]; ReturnValue; taint | -| 29 | Summary: ::unset_domain; Argument[self]; ReturnValue; taint | -| 30 | Summary: ::unset_expires; Argument[self]; ReturnValue; taint | -| 31 | Summary: ::unset_path; Argument[self]; ReturnValue; taint | -| 32 | Summary: ::domain; Argument[self]; ReturnValue; taint | -| 33 | Summary: ::expires; Argument[self]; ReturnValue; taint | -| 34 | Summary: ::http_only; Argument[self]; ReturnValue; taint | -| 35 | Summary: ::max_age; Argument[self]; ReturnValue; taint | -| 36 | Summary: ::partitioned; Argument[self]; ReturnValue; taint | -| 37 | Summary: ::path; Argument[self]; ReturnValue; taint | -| 38 | Summary: ::permanent; Argument[self]; ReturnValue; taint | -| 39 | Summary: ::removal; Argument[self]; ReturnValue; taint | -| 40 | Summary: ::same_site; Argument[self]; ReturnValue; taint | -| 41 | Summary: ::secure; Argument[self]; ReturnValue; taint | +| 27 | Summary: ::set_value; Argument[self]; ReturnValue; taint | +| 28 | Summary: ::unset_domain; Argument[self]; ReturnValue; taint | +| 29 | Summary: ::unset_expires; Argument[self]; ReturnValue; taint | +| 30 | Summary: ::unset_path; Argument[self]; ReturnValue; taint | +| 31 | Summary: ::domain; Argument[self]; ReturnValue; taint | +| 32 | Summary: ::expires; Argument[self]; ReturnValue; taint | +| 33 | Summary: ::http_only; Argument[self]; ReturnValue; taint | +| 34 | Summary: ::max_age; Argument[self]; ReturnValue; taint | +| 35 | Summary: ::partitioned; Argument[self].OptionalBarrier[cookie-partitioned-arg0]; ReturnValue; taint | +| 36 | Summary: ::path; Argument[self]; ReturnValue; taint | +| 37 | Summary: ::permanent; Argument[self]; ReturnValue; taint | +| 38 | Summary: ::removal; Argument[self]; ReturnValue; taint | +| 39 | Summary: ::same_site; Argument[self]; ReturnValue; taint | +| 40 | Summary: ::secure; Argument[self].OptionalBarrier[cookie-secure-arg0]; ReturnValue; taint | nodes | main.rs:8:19:8:31 | ...::build | semmle.label | ...::build | | main.rs:8:19:8:50 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:8:19:8:64 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:8:66:8:70 | build | semmle.label | build | -| main.rs:12:19:12:31 | ...::build | semmle.label | ...::build | -| main.rs:12:19:12:50 | ...::build(...) | semmle.label | ...::build(...) | -| main.rs:12:19:12:63 | ... .secure(...) | semmle.label | ... .secure(...) | -| main.rs:12:65:12:69 | build | semmle.label | build | | main.rs:16:19:16:31 | ...::build | semmle.label | ...::build | | main.rs:16:19:16:50 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:16:52:16:56 | build | semmle.label | build | @@ -477,16 +458,8 @@ nodes | main.rs:50:5:50:40 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:50:5:50:54 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:50:56:50:60 | build | semmle.label | build | -| main.rs:53:5:53:17 | ...::build | semmle.label | ...::build | -| main.rs:53:5:53:36 | ...::build(...) | semmle.label | ...::build(...) | -| main.rs:53:5:53:49 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:53:5:53:63 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:53:65:53:69 | build | semmle.label | build | -| main.rs:54:5:54:17 | ...::build | semmle.label | ...::build | -| main.rs:54:5:54:36 | ...::build(...) | semmle.label | ...::build(...) | -| main.rs:54:5:54:50 | ... .secure(...) | semmle.label | ... .secure(...) | -| main.rs:54:5:54:63 | ... .secure(...) | semmle.label | ... .secure(...) | -| main.rs:54:65:54:69 | build | semmle.label | build | | main.rs:58:9:58:13 | mut a | semmle.label | mut a | | main.rs:58:17:58:27 | ...::new | semmle.label | ...::new | | main.rs:58:17:58:44 | ...::new(...) | semmle.label | ...::new(...) | @@ -551,11 +524,6 @@ nodes | main.rs:123:13:123:18 | insert | semmle.label | insert | | main.rs:123:20:123:20 | a | semmle.label | a | | main.rs:123:20:123:28 | a.clone() | semmle.label | a.clone() | -| main.rs:126:9:126:9 | b | semmle.label | b | -| main.rs:126:13:126:30 | a.set_secure(...) | semmle.label | a.set_secure(...) | -| main.rs:127:13:127:18 | insert | semmle.label | insert | -| main.rs:127:20:127:20 | b | semmle.label | b | -| main.rs:127:20:127:28 | b.clone() | semmle.label | b.clone() | | main.rs:130:9:130:9 | c | semmle.label | c | | main.rs:130:13:130:31 | b.set_secure(...) | semmle.label | b.set_secure(...) | | main.rs:131:13:131:18 | insert | semmle.label | insert | @@ -566,16 +534,6 @@ nodes | main.rs:135:13:135:18 | insert | semmle.label | insert | | main.rs:135:20:135:20 | d | semmle.label | d | | main.rs:135:20:135:28 | d.clone() | semmle.label | d.clone() | -| main.rs:138:9:138:9 | e | semmle.label | e | -| main.rs:138:13:138:30 | d.set_secure(...) | semmle.label | d.set_secure(...) | -| main.rs:139:13:139:18 | insert | semmle.label | insert | -| main.rs:139:20:139:20 | e | semmle.label | e | -| main.rs:139:20:139:28 | e.clone() | semmle.label | e.clone() | -| main.rs:142:9:142:9 | f | semmle.label | f | -| main.rs:142:13:142:36 | e.set_partitioned(...) | semmle.label | e.set_partitioned(...) | -| main.rs:143:13:143:18 | insert | semmle.label | insert | -| main.rs:143:20:143:20 | f | semmle.label | f | -| main.rs:143:20:143:28 | f.clone() | semmle.label | f.clone() | | main.rs:146:9:146:9 | g | semmle.label | g | | main.rs:146:13:146:31 | f.set_secure(...) | semmle.label | f.set_secure(...) | | main.rs:147:13:147:18 | insert | semmle.label | insert | diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 0f0f929fd14..6cbb786cea5 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -9,7 +9,7 @@ fn test_cookie(sometimes: bool) { println!("cookie1 = '{}'", cookie1.to_string()); // secure set to true - let cookie2 = Cookie::build(("name", "value")).secure(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + let cookie2 = Cookie::build(("name", "value")).secure(true).build(); // good println!("cookie2 = '{}'", cookie2.to_string()); // secure left as default (which is `None`, equivalent here to `false`) @@ -51,7 +51,7 @@ fn test_cookie(sometimes: bool) { // edge cases Cookie::build(("name", "value")).secure(true).secure(false).build(); // $ Alert[rust/insecure-cookie] - Cookie::build(("name", "value")).secure(false).secure(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(false).secure(true).build(); // good // mutable cookie let mut jar = CookieJar::new(); @@ -111,7 +111,7 @@ fn test_cookie(sometimes: bool) { } // partitioned (implies secure) - Cookie::build(("name", "value")).partitioned(true).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).partitioned(true).build(); // good } fn test_biscotti() { @@ -124,7 +124,7 @@ fn test_biscotti() { println!("biscotti1 = {}", a.to_string()); let b = a.set_secure(true); - cookies.insert(b.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + cookies.insert(b.clone()); // good println!("biscotti2 = {}", b.to_string()); let c = b.set_secure(false); @@ -132,15 +132,15 @@ fn test_biscotti() { println!("biscotti3 = {}", c.to_string()); let d = c.set_partitioned(true); // (implies secure) - cookies.insert(d.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + cookies.insert(d.clone()); // good println!("biscotti4 = {}", d.to_string()); let e = d.set_secure(true); - cookies.insert(e.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + cookies.insert(e.clone()); // good println!("biscotti5 = {}", e.to_string()); let f = e.set_partitioned(false); - cookies.insert(f.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + cookies.insert(f.clone()); // good println!("biscotti6 = {}", f.to_string()); let g = f.set_secure(false); From a3ed83bfff14a295405609ba6058f41bf10fd984 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 Sep 2025 19:47:18 +0100 Subject: [PATCH 078/160] Rust: Make state transition / barrier nodes more reliable. --- .../security/InsecureCookieExtensions.qll | 13 +- .../security/CWE-614/CookieSet.expected | 95 ++++---- .../security/CWE-614/InsecureCookie.expected | 220 +++++++++--------- .../test/query-tests/security/CWE-614/main.rs | 6 +- 4 files changed, 176 insertions(+), 158 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index aa534a9c1ea..93406f91452 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -10,6 +10,7 @@ private import codeql.rust.dataflow.FlowSink private import codeql.rust.Concepts private import codeql.rust.dataflow.internal.DataFlowImpl as DataflowImpl private import codeql.rust.dataflow.internal.Node +private import codeql.rust.controlflow.BasicBlocks /** * Provides default sources, sinks and barriers for detecting insecure @@ -74,8 +75,16 @@ module InsecureCookie { then value = true // `true` flow to here else value = false // `false` or unknown ) and - // and the node `node` where this happens - node.asExpr().getExpr() = ce + // and find the node where this happens + ( + node.asExpr().getExpr() = ce.(MethodCallExpr).getReceiver() // e.g. `a` in `a.set_secure(true)` + or + exists(BasicBlock bb, int i | + // associated SSA node + node.(SsaNode).asDefinition().definesAt(_, bb, i) and + ce.(MethodCallExpr).getReceiver() = bb.getNode(i).getAstNode() + ) + ) ) } } diff --git a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected index eccdbaec90a..eacadaa722d 100644 --- a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected +++ b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected @@ -1,44 +1,51 @@ -| main.rs:8:19:8:64 | ... .secure(...) | secure | false | -| main.rs:12:19:12:63 | ... .secure(...) | secure | true | -| main.rs:20:5:20:54 | ... .secure(...) | secure | false | -| main.rs:21:5:21:55 | ... .secure(...) | secure | false | -| main.rs:24:5:24:51 | ... .secure(...) | secure | false | -| main.rs:25:5:25:52 | ... .secure(...) | secure | false | -| main.rs:26:5:26:50 | ... .secure(...) | secure | false | -| main.rs:27:5:27:51 | ... .secure(...) | secure | false | -| main.rs:28:5:28:60 | ... .secure(...) | secure | false | -| main.rs:29:5:29:60 | ... .secure(...) | secure | false | -| main.rs:33:9:33:58 | ... .secure(...) | secure | false | -| main.rs:35:9:35:58 | ... .secure(...) | secure | false | -| main.rs:39:5:39:53 | ... .secure(...) | secure | false | -| main.rs:40:5:40:64 | ... .secure(...) | secure | false | -| main.rs:41:5:41:93 | ... .secure(...) | secure | false | -| main.rs:42:5:42:72 | ... .secure(...) | secure | false | -| main.rs:43:5:43:60 | ... .secure(...) | secure | false | -| main.rs:44:5:44:66 | ... .secure(...) | secure | false | -| main.rs:45:5:45:86 | ... .secure(...) | secure | false | -| main.rs:46:5:46:62 | ... .secure(...) | secure | false | -| main.rs:47:5:47:60 | ... .secure(...) | secure | false | -| main.rs:48:5:48:50 | ... .secure(...) | secure | false | -| main.rs:49:5:49:39 | ... .secure(...) | secure | false | -| main.rs:50:5:50:54 | ... .secure(...) | secure | false | -| main.rs:53:5:53:49 | ... .secure(...) | secure | true | -| main.rs:53:5:53:63 | ... .secure(...) | secure | false | -| main.rs:54:5:54:50 | ... .secure(...) | secure | false | -| main.rs:54:5:54:63 | ... .secure(...) | secure | true | -| main.rs:61:5:61:22 | a.set_secure(...) | secure | true | -| main.rs:63:5:63:23 | a.set_secure(...) | secure | false | -| main.rs:71:5:71:27 | b.set_secure(...) | secure | false | -| main.rs:73:5:73:22 | b.set_secure(...) | secure | true | -| main.rs:81:9:81:26 | c.set_secure(...) | secure | true | -| main.rs:84:5:84:22 | c.set_secure(...) | secure | true | -| main.rs:90:9:90:26 | c.set_secure(...) | secure | true | -| main.rs:92:9:92:31 | c.set_partitioned(...) | partitioned | true | -| main.rs:109:9:109:26 | e.set_secure(...) | secure | true | -| main.rs:114:5:114:54 | ... .partitioned(...) | partitioned | true | -| main.rs:126:13:126:30 | a.set_secure(...) | secure | true | -| main.rs:130:13:130:31 | b.set_secure(...) | secure | false | -| main.rs:134:13:134:35 | c.set_partitioned(...) | partitioned | true | -| main.rs:138:13:138:30 | d.set_secure(...) | secure | true | -| main.rs:142:13:142:36 | e.set_partitioned(...) | partitioned | false | -| main.rs:146:13:146:31 | f.set_secure(...) | secure | false | +| main.rs:8:19:8:50 | ...::build(...) | secure | false | +| main.rs:12:19:12:50 | ...::build(...) | secure | true | +| main.rs:20:5:20:36 | ...::build(...) | secure | false | +| main.rs:21:5:21:36 | ...::build(...) | secure | false | +| main.rs:24:5:24:36 | ...::build(...) | secure | false | +| main.rs:25:5:25:36 | ...::build(...) | secure | false | +| main.rs:26:5:26:36 | ...::build(...) | secure | false | +| main.rs:27:5:27:36 | ...::build(...) | secure | false | +| main.rs:28:5:28:36 | ...::build(...) | secure | false | +| main.rs:29:5:29:36 | ...::build(...) | secure | false | +| main.rs:33:9:33:40 | ...::build(...) | secure | false | +| main.rs:35:9:35:40 | ...::build(...) | secure | false | +| main.rs:39:5:39:39 | ...::new(...) | secure | false | +| main.rs:40:5:40:50 | ... .expires(...) | secure | false | +| main.rs:41:5:41:79 | ... .max_age(...) | secure | false | +| main.rs:42:5:42:58 | ... .domain(...) | secure | false | +| main.rs:43:5:43:46 | ... .path(...) | secure | false | +| main.rs:44:5:44:52 | ... .http_only(...) | secure | false | +| main.rs:45:5:45:72 | ... .same_site(...) | secure | false | +| main.rs:46:5:46:48 | ... .permanent() | secure | false | +| main.rs:47:5:47:46 | ... .removal() | secure | false | +| main.rs:48:5:48:36 | ...::build(...) | secure | false | +| main.rs:49:5:49:25 | ...::build(...) | secure | false | +| main.rs:50:5:50:40 | ...::build(...) | secure | false | +| main.rs:53:5:53:36 | ...::build(...) | secure | true | +| main.rs:53:5:53:49 | ... .secure(...) | secure | false | +| main.rs:54:5:54:36 | ...::build(...) | secure | false | +| main.rs:54:5:54:50 | ... .secure(...) | secure | true | +| main.rs:61:5:61:5 | [SSA] a | secure | true | +| main.rs:61:5:61:5 | a | secure | true | +| main.rs:63:5:63:5 | [SSA] a | secure | false | +| main.rs:63:5:63:5 | a | secure | false | +| main.rs:71:5:71:5 | [SSA] b | secure | false | +| main.rs:71:5:71:5 | b | secure | false | +| main.rs:73:5:73:5 | [SSA] b | secure | true | +| main.rs:73:5:73:5 | b | secure | true | +| main.rs:81:9:81:9 | [SSA] c | secure | true | +| main.rs:81:9:81:9 | c | secure | true | +| main.rs:84:5:84:5 | [SSA] c | secure | true | +| main.rs:84:5:84:5 | c | secure | true | +| main.rs:90:9:90:9 | c | secure | true | +| main.rs:92:9:92:9 | c | partitioned | true | +| main.rs:109:9:109:9 | [SSA] e | secure | true | +| main.rs:109:9:109:9 | e | secure | true | +| main.rs:114:5:114:36 | ...::build(...) | partitioned | true | +| main.rs:126:13:126:13 | a | secure | true | +| main.rs:130:13:130:13 | b | secure | false | +| main.rs:134:13:134:13 | c | partitioned | true | +| main.rs:138:13:138:13 | d | secure | true | +| main.rs:142:13:142:13 | e | partitioned | false | +| main.rs:146:13:146:13 | f | secure | false | diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected index 9d9975a1a36..880262e9bd4 100644 --- a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -1,69 +1,71 @@ #select | main.rs:8:66:8:70 | build | main.rs:8:19:8:31 | ...::build | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:8:66:8:70 | build | main.rs:8:19:8:64 | ... .secure(...) | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:8:66:8:70 | build | main.rs:8:19:8:50 | ...::build(...) | main.rs:8:66:8:70 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:16:52:16:56 | build | main.rs:16:19:16:31 | ...::build | main.rs:16:52:16:56 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:20:56:20:60 | build | main.rs:20:5:20:17 | ...::build | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:20:56:20:60 | build | main.rs:20:5:20:54 | ... .secure(...) | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:20:56:20:60 | build | main.rs:20:5:20:36 | ...::build(...) | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:21:57:21:61 | build | main.rs:21:5:21:17 | ...::build | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:21:57:21:61 | build | main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:21:57:21:61 | build | main.rs:21:5:21:36 | ...::build(...) | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:24:53:24:57 | build | main.rs:24:5:24:17 | ...::build | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:24:53:24:57 | build | main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:24:53:24:57 | build | main.rs:24:5:24:36 | ...::build(...) | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:25:54:25:58 | build | main.rs:25:5:25:17 | ...::build | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:25:54:25:58 | build | main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:25:54:25:58 | build | main.rs:25:5:25:36 | ...::build(...) | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:26:52:26:56 | build | main.rs:26:5:26:17 | ...::build | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:26:52:26:56 | build | main.rs:26:5:26:50 | ... .secure(...) | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:26:52:26:56 | build | main.rs:26:5:26:36 | ...::build(...) | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:27:53:27:57 | build | main.rs:27:5:27:17 | ...::build | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:27:53:27:57 | build | main.rs:27:5:27:51 | ... .secure(...) | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:27:53:27:57 | build | main.rs:27:5:27:36 | ...::build(...) | main.rs:27:53:27:57 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:28:62:28:66 | build | main.rs:28:5:28:17 | ...::build | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:28:62:28:66 | build | main.rs:28:5:28:60 | ... .secure(...) | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:28:62:28:66 | build | main.rs:28:5:28:36 | ...::build(...) | main.rs:28:62:28:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:29:62:29:66 | build | main.rs:29:5:29:17 | ...::build | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:29:62:29:66 | build | main.rs:29:5:29:60 | ... .secure(...) | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:29:62:29:66 | build | main.rs:29:5:29:36 | ...::build(...) | main.rs:29:62:29:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:33:60:33:64 | build | main.rs:33:9:33:21 | ...::build | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:33:60:33:64 | build | main.rs:33:9:33:58 | ... .secure(...) | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:33:60:33:64 | build | main.rs:33:9:33:40 | ...::build(...) | main.rs:33:60:33:64 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:35:60:35:64 | build | main.rs:35:9:35:21 | ...::build | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:35:60:35:64 | build | main.rs:35:9:35:58 | ... .secure(...) | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:35:60:35:64 | build | main.rs:35:9:35:40 | ...::build(...) | main.rs:35:60:35:64 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:39:55:39:59 | build | main.rs:39:5:39:22 | ...::new | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:39:55:39:59 | build | main.rs:39:5:39:53 | ... .secure(...) | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:39:55:39:59 | build | main.rs:39:5:39:39 | ...::new(...) | main.rs:39:55:39:59 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:40:66:40:70 | build | main.rs:40:5:40:17 | ...::build | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:40:66:40:70 | build | main.rs:40:5:40:64 | ... .secure(...) | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:40:66:40:70 | build | main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:66:40:70 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:41:95:41:99 | build | main.rs:41:5:41:17 | ...::build | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:41:95:41:99 | build | main.rs:41:5:41:93 | ... .secure(...) | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:41:95:41:99 | build | main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:95:41:99 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:42:74:42:78 | build | main.rs:42:5:42:17 | ...::build | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:42:74:42:78 | build | main.rs:42:5:42:72 | ... .secure(...) | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:42:74:42:78 | build | main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:74:42:78 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:43:62:43:66 | build | main.rs:43:5:43:17 | ...::build | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:43:62:43:66 | build | main.rs:43:5:43:60 | ... .secure(...) | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:43:62:43:66 | build | main.rs:43:5:43:46 | ... .path(...) | main.rs:43:62:43:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:44:68:44:72 | build | main.rs:44:5:44:17 | ...::build | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:44:68:44:72 | build | main.rs:44:5:44:66 | ... .secure(...) | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:44:68:44:72 | build | main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:68:44:72 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:45:88:45:92 | build | main.rs:45:5:45:17 | ...::build | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:45:88:45:92 | build | main.rs:45:5:45:86 | ... .secure(...) | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:45:88:45:92 | build | main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:88:45:92 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:46:64:46:68 | build | main.rs:46:5:46:17 | ...::build | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:46:64:46:68 | build | main.rs:46:5:46:62 | ... .secure(...) | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:46:64:46:68 | build | main.rs:46:5:46:48 | ... .permanent() | main.rs:46:64:46:68 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:47:62:47:66 | build | main.rs:47:5:47:17 | ...::build | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:47:62:47:66 | build | main.rs:47:5:47:60 | ... .secure(...) | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:47:62:47:66 | build | main.rs:47:5:47:46 | ... .removal() | main.rs:47:62:47:66 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:48:52:48:57 | finish | main.rs:48:5:48:17 | ...::build | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | -| main.rs:48:52:48:57 | finish | main.rs:48:5:48:50 | ... .secure(...) | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | +| main.rs:48:52:48:57 | finish | main.rs:48:5:48:36 | ...::build(...) | main.rs:48:52:48:57 | finish | Cookie attribute 'Secure' is not set to true. | | main.rs:49:41:49:45 | build | main.rs:49:5:49:17 | ...::build | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:49:41:49:45 | build | main.rs:49:5:49:39 | ... .secure(...) | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:49:41:49:45 | build | main.rs:49:5:49:25 | ...::build(...) | main.rs:49:41:49:45 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:50:56:50:60 | build | main.rs:50:5:50:17 | ...::build | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:50:56:50:60 | build | main.rs:50:5:50:54 | ... .secure(...) | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:53:65:53:69 | build | main.rs:53:5:53:63 | ... .secure(...) | main.rs:53:65:53:69 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:50:56:50:60 | build | main.rs:50:5:50:40 | ...::build(...) | main.rs:50:56:50:60 | build | Cookie attribute 'Secure' is not set to true. | +| main.rs:53:65:53:69 | build | main.rs:53:5:53:49 | ... .secure(...) | main.rs:53:65:53:69 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:59:9:59:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:59:9:59:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:60:9:60:20 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:60:9:60:20 | add_original | Cookie attribute 'Secure' is not set to true. | -| main.rs:62:9:62:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:62:9:62:11 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:64:9:64:11 | add | main.rs:58:17:58:27 | ...::new | main.rs:64:9:64:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:64:9:64:11 | add | main.rs:63:5:63:5 | [SSA] a | main.rs:64:9:64:11 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:64:9:64:11 | add | main.rs:63:5:63:5 | a | main.rs:64:9:64:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:69:16:69:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:69:16:69:18 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:70:16:70:27 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:70:16:70:27 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:70:16:70:27 | add_original | main.rs:63:5:63:5 | [SSA] a | main.rs:70:16:70:27 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:70:16:70:27 | add_original | main.rs:63:5:63:5 | a | main.rs:70:16:70:27 | add_original | Cookie attribute 'Secure' is not set to true. | | main.rs:72:16:72:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:72:16:72:18 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:74:16:74:18 | add | main.rs:68:17:68:29 | ...::named | main.rs:74:16:74:18 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:72:16:72:18 | add | main.rs:71:5:71:5 | [SSA] b | main.rs:72:16:72:18 | add | Cookie attribute 'Secure' is not set to true. | +| main.rs:72:16:72:18 | add | main.rs:71:5:71:5 | b | main.rs:72:16:72:18 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:78:17:78:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:78:17:78:19 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:79:17:79:28 | add_original | main.rs:58:17:58:27 | ...::new | main.rs:79:17:79:28 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:79:17:79:28 | add_original | main.rs:63:5:63:5 | [SSA] a | main.rs:79:17:79:28 | add_original | Cookie attribute 'Secure' is not set to true. | +| main.rs:79:17:79:28 | add_original | main.rs:63:5:63:5 | a | main.rs:79:17:79:28 | add_original | Cookie attribute 'Secure' is not set to true. | | main.rs:83:17:83:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:83:17:83:19 | add | Cookie attribute 'Secure' is not set to true. | -| main.rs:85:17:85:19 | add | main.rs:77:17:77:28 | ...::from | main.rs:85:17:85:19 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:88:9:88:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:88:9:88:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:94:9:94:11 | add | main.rs:87:17:87:28 | ...::from | main.rs:94:9:94:11 | add | Cookie attribute 'Secure' is not set to true. | | main.rs:123:13:123:18 | insert | main.rs:122:13:122:41 | ...::new | main.rs:123:13:123:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:131:13:131:18 | insert | main.rs:130:13:130:31 | b.set_secure(...) | main.rs:131:13:131:18 | insert | Cookie attribute 'Secure' is not set to true. | -| main.rs:147:13:147:18 | insert | main.rs:146:13:146:31 | f.set_secure(...) | main.rs:147:13:147:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:131:13:131:18 | insert | main.rs:130:13:130:13 | b | main.rs:131:13:131:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:147:13:147:18 | insert | main.rs:146:13:146:13 | f | main.rs:147:13:147:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:152:13:152:18 | insert | main.rs:151:13:151:42 | ...::from | main.rs:152:13:152:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:156:13:156:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:156:13:156:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:157:13:157:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:157:13:157:18 | insert | Cookie attribute 'Secure' is not set to true. | @@ -79,129 +81,130 @@ | main.rs:167:13:167:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:167:13:167:18 | insert | Cookie attribute 'Secure' is not set to true. | edges | main.rs:8:19:8:31 | ...::build | main.rs:8:19:8:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:40 | +| main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:41 | | main.rs:8:19:8:64 | ... .secure(...) | main.rs:8:66:8:70 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:16:19:16:31 | ...::build | main.rs:16:19:16:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | | main.rs:16:19:16:50 | ...::build(...) | main.rs:16:52:16:56 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:20:5:20:17 | ...::build | main.rs:20:5:20:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:20:5:20:36 | ...::build(...) | main.rs:20:5:20:54 | ... .secure(...) | provenance | MaD:40 | +| main.rs:20:5:20:36 | ...::build(...) | main.rs:20:5:20:54 | ... .secure(...) | provenance | MaD:41 | | main.rs:20:5:20:54 | ... .secure(...) | main.rs:20:56:20:60 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:21:5:21:17 | ...::build | main.rs:21:5:21:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:40 | +| main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:41 | | main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:24:5:24:17 | ...::build | main.rs:24:5:24:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:40 | +| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:41 | | main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:25:5:25:17 | ...::build | main.rs:25:5:25:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:40 | +| main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:41 | | main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:26:5:26:17 | ...::build | main.rs:26:5:26:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:26:5:26:36 | ...::build(...) | main.rs:26:5:26:50 | ... .secure(...) | provenance | MaD:40 | +| main.rs:26:5:26:36 | ...::build(...) | main.rs:26:5:26:50 | ... .secure(...) | provenance | MaD:41 | | main.rs:26:5:26:50 | ... .secure(...) | main.rs:26:52:26:56 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:27:5:27:17 | ...::build | main.rs:27:5:27:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:27:5:27:36 | ...::build(...) | main.rs:27:5:27:51 | ... .secure(...) | provenance | MaD:40 | +| main.rs:27:5:27:36 | ...::build(...) | main.rs:27:5:27:51 | ... .secure(...) | provenance | MaD:41 | | main.rs:27:5:27:51 | ... .secure(...) | main.rs:27:53:27:57 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:28:5:28:17 | ...::build | main.rs:28:5:28:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:28:5:28:36 | ...::build(...) | main.rs:28:5:28:60 | ... .secure(...) | provenance | MaD:40 | +| main.rs:28:5:28:36 | ...::build(...) | main.rs:28:5:28:60 | ... .secure(...) | provenance | MaD:41 | | main.rs:28:5:28:60 | ... .secure(...) | main.rs:28:62:28:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:29:5:29:17 | ...::build | main.rs:29:5:29:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:29:5:29:36 | ...::build(...) | main.rs:29:5:29:60 | ... .secure(...) | provenance | MaD:40 | +| main.rs:29:5:29:36 | ...::build(...) | main.rs:29:5:29:60 | ... .secure(...) | provenance | MaD:41 | | main.rs:29:5:29:60 | ... .secure(...) | main.rs:29:62:29:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:33:9:33:21 | ...::build | main.rs:33:9:33:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:33:9:33:40 | ...::build(...) | main.rs:33:9:33:58 | ... .secure(...) | provenance | MaD:40 | +| main.rs:33:9:33:40 | ...::build(...) | main.rs:33:9:33:58 | ... .secure(...) | provenance | MaD:41 | | main.rs:33:9:33:58 | ... .secure(...) | main.rs:33:60:33:64 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:35:9:35:21 | ...::build | main.rs:35:9:35:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:35:9:35:40 | ...::build(...) | main.rs:35:9:35:58 | ... .secure(...) | provenance | MaD:40 | +| main.rs:35:9:35:40 | ...::build(...) | main.rs:35:9:35:58 | ... .secure(...) | provenance | MaD:41 | | main.rs:35:9:35:58 | ... .secure(...) | main.rs:35:60:35:64 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:39:5:39:22 | ...::new | main.rs:39:5:39:39 | ...::new(...) | provenance | Src:MaD:16 MaD:16 | -| main.rs:39:5:39:39 | ...::new(...) | main.rs:39:5:39:53 | ... .secure(...) | provenance | MaD:40 | +| main.rs:39:5:39:39 | ...::new(...) | main.rs:39:5:39:53 | ... .secure(...) | provenance | MaD:41 | | main.rs:39:5:39:53 | ... .secure(...) | main.rs:39:55:39:59 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:40:5:40:17 | ...::build | main.rs:40:5:40:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:40:5:40:36 | ...::build(...) | main.rs:40:5:40:50 | ... .expires(...) | provenance | MaD:32 | -| main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:5:40:64 | ... .secure(...) | provenance | MaD:40 | +| main.rs:40:5:40:36 | ...::build(...) | main.rs:40:5:40:50 | ... .expires(...) | provenance | MaD:33 | +| main.rs:40:5:40:50 | ... .expires(...) | main.rs:40:5:40:64 | ... .secure(...) | provenance | MaD:41 | | main.rs:40:5:40:64 | ... .secure(...) | main.rs:40:66:40:70 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:41:5:41:17 | ...::build | main.rs:41:5:41:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:41:5:41:36 | ...::build(...) | main.rs:41:5:41:79 | ... .max_age(...) | provenance | MaD:34 | -| main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:5:41:93 | ... .secure(...) | provenance | MaD:40 | +| main.rs:41:5:41:36 | ...::build(...) | main.rs:41:5:41:79 | ... .max_age(...) | provenance | MaD:35 | +| main.rs:41:5:41:79 | ... .max_age(...) | main.rs:41:5:41:93 | ... .secure(...) | provenance | MaD:41 | | main.rs:41:5:41:93 | ... .secure(...) | main.rs:41:95:41:99 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:42:5:42:17 | ...::build | main.rs:42:5:42:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:42:5:42:36 | ...::build(...) | main.rs:42:5:42:58 | ... .domain(...) | provenance | MaD:31 | -| main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:5:42:72 | ... .secure(...) | provenance | MaD:40 | +| main.rs:42:5:42:36 | ...::build(...) | main.rs:42:5:42:58 | ... .domain(...) | provenance | MaD:32 | +| main.rs:42:5:42:58 | ... .domain(...) | main.rs:42:5:42:72 | ... .secure(...) | provenance | MaD:41 | | main.rs:42:5:42:72 | ... .secure(...) | main.rs:42:74:42:78 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:43:5:43:17 | ...::build | main.rs:43:5:43:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:43:5:43:36 | ...::build(...) | main.rs:43:5:43:46 | ... .path(...) | provenance | MaD:36 | -| main.rs:43:5:43:46 | ... .path(...) | main.rs:43:5:43:60 | ... .secure(...) | provenance | MaD:40 | +| main.rs:43:5:43:36 | ...::build(...) | main.rs:43:5:43:46 | ... .path(...) | provenance | MaD:37 | +| main.rs:43:5:43:46 | ... .path(...) | main.rs:43:5:43:60 | ... .secure(...) | provenance | MaD:41 | | main.rs:43:5:43:60 | ... .secure(...) | main.rs:43:62:43:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:44:5:44:17 | ...::build | main.rs:44:5:44:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:44:5:44:36 | ...::build(...) | main.rs:44:5:44:52 | ... .http_only(...) | provenance | MaD:33 | -| main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:5:44:66 | ... .secure(...) | provenance | MaD:40 | +| main.rs:44:5:44:36 | ...::build(...) | main.rs:44:5:44:52 | ... .http_only(...) | provenance | MaD:34 | +| main.rs:44:5:44:52 | ... .http_only(...) | main.rs:44:5:44:66 | ... .secure(...) | provenance | MaD:41 | | main.rs:44:5:44:66 | ... .secure(...) | main.rs:44:68:44:72 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:45:5:45:17 | ...::build | main.rs:45:5:45:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:45:5:45:36 | ...::build(...) | main.rs:45:5:45:72 | ... .same_site(...) | provenance | MaD:39 | -| main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:5:45:86 | ... .secure(...) | provenance | MaD:40 | +| main.rs:45:5:45:36 | ...::build(...) | main.rs:45:5:45:72 | ... .same_site(...) | provenance | MaD:40 | +| main.rs:45:5:45:72 | ... .same_site(...) | main.rs:45:5:45:86 | ... .secure(...) | provenance | MaD:41 | | main.rs:45:5:45:86 | ... .secure(...) | main.rs:45:88:45:92 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:46:5:46:17 | ...::build | main.rs:46:5:46:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:46:5:46:36 | ...::build(...) | main.rs:46:5:46:48 | ... .permanent() | provenance | MaD:37 | -| main.rs:46:5:46:48 | ... .permanent() | main.rs:46:5:46:62 | ... .secure(...) | provenance | MaD:40 | +| main.rs:46:5:46:36 | ...::build(...) | main.rs:46:5:46:48 | ... .permanent() | provenance | MaD:38 | +| main.rs:46:5:46:48 | ... .permanent() | main.rs:46:5:46:62 | ... .secure(...) | provenance | MaD:41 | | main.rs:46:5:46:62 | ... .secure(...) | main.rs:46:64:46:68 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:47:5:47:17 | ...::build | main.rs:47:5:47:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:47:5:47:36 | ...::build(...) | main.rs:47:5:47:46 | ... .removal() | provenance | MaD:38 | -| main.rs:47:5:47:46 | ... .removal() | main.rs:47:5:47:60 | ... .secure(...) | provenance | MaD:40 | +| main.rs:47:5:47:36 | ...::build(...) | main.rs:47:5:47:46 | ... .removal() | provenance | MaD:39 | +| main.rs:47:5:47:46 | ... .removal() | main.rs:47:5:47:60 | ... .secure(...) | provenance | MaD:41 | | main.rs:47:5:47:60 | ... .secure(...) | main.rs:47:62:47:66 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:48:5:48:17 | ...::build | main.rs:48:5:48:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:48:5:48:36 | ...::build(...) | main.rs:48:5:48:50 | ... .secure(...) | provenance | MaD:40 | +| main.rs:48:5:48:36 | ...::build(...) | main.rs:48:5:48:50 | ... .secure(...) | provenance | MaD:41 | | main.rs:48:5:48:50 | ... .secure(...) | main.rs:48:52:48:57 | finish | provenance | MaD:3 Sink:MaD:3 | | main.rs:49:5:49:17 | ...::build | main.rs:49:5:49:25 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:49:5:49:25 | ...::build(...) | main.rs:49:5:49:39 | ... .secure(...) | provenance | MaD:40 | +| main.rs:49:5:49:25 | ...::build(...) | main.rs:49:5:49:39 | ... .secure(...) | provenance | MaD:41 | | main.rs:49:5:49:39 | ... .secure(...) | main.rs:49:41:49:45 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:50:5:50:17 | ...::build | main.rs:50:5:50:40 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:50:5:50:40 | ...::build(...) | main.rs:50:5:50:54 | ... .secure(...) | provenance | MaD:40 | +| main.rs:50:5:50:40 | ...::build(...) | main.rs:50:5:50:54 | ... .secure(...) | provenance | MaD:41 | | main.rs:50:5:50:54 | ... .secure(...) | main.rs:50:56:50:60 | build | provenance | MaD:2 Sink:MaD:2 | +| main.rs:53:5:53:49 | ... .secure(...) | main.rs:53:5:53:63 | ... .secure(...) | provenance | MaD:41 | | main.rs:53:5:53:63 | ... .secure(...) | main.rs:53:65:53:69 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:58:9:58:13 | mut a | main.rs:59:13:59:13 | a | provenance | | | main.rs:58:9:58:13 | mut a | main.rs:59:13:59:21 | a.clone() | provenance | MaD:17 | | main.rs:58:9:58:13 | mut a | main.rs:60:22:60:22 | a | provenance | | | main.rs:58:9:58:13 | mut a | main.rs:60:22:60:30 | a.clone() | provenance | MaD:17 | -| main.rs:58:9:58:13 | mut a | main.rs:62:13:62:13 | a | provenance | | -| main.rs:58:9:58:13 | mut a | main.rs:62:13:62:21 | a.clone() | provenance | MaD:17 | -| main.rs:58:9:58:13 | mut a | main.rs:64:13:64:13 | a | provenance | | -| main.rs:58:9:58:13 | mut a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | -| main.rs:58:9:58:13 | mut a | main.rs:70:29:70:29 | a | provenance | | -| main.rs:58:9:58:13 | mut a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | -| main.rs:58:9:58:13 | mut a | main.rs:79:30:79:30 | a | provenance | | -| main.rs:58:9:58:13 | mut a | main.rs:79:30:79:38 | a.clone() | provenance | MaD:17 | | main.rs:58:17:58:27 | ...::new | main.rs:58:17:58:44 | ...::new(...) | provenance | Src:MaD:15 MaD:15 | | main.rs:58:17:58:44 | ...::new(...) | main.rs:58:9:58:13 | mut a | provenance | | | main.rs:59:13:59:13 | a | main.rs:59:13:59:21 | a.clone() | provenance | MaD:17 | | main.rs:59:13:59:21 | a.clone() | main.rs:59:9:59:11 | add | provenance | MaD:4 Sink:MaD:4 | | main.rs:60:22:60:22 | a | main.rs:60:22:60:30 | a.clone() | provenance | MaD:17 | | main.rs:60:22:60:30 | a.clone() | main.rs:60:9:60:20 | add_original | provenance | MaD:5 Sink:MaD:5 | -| main.rs:62:13:62:13 | a | main.rs:62:13:62:21 | a.clone() | provenance | MaD:17 | -| main.rs:62:13:62:21 | a.clone() | main.rs:62:9:62:11 | add | provenance | MaD:4 Sink:MaD:4 | +| main.rs:63:5:63:5 | [SSA] a | main.rs:64:13:64:13 | a | provenance | | +| main.rs:63:5:63:5 | [SSA] a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | +| main.rs:63:5:63:5 | [SSA] a | main.rs:70:29:70:29 | a | provenance | | +| main.rs:63:5:63:5 | [SSA] a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | +| main.rs:63:5:63:5 | [SSA] a | main.rs:79:30:79:30 | a | provenance | | +| main.rs:63:5:63:5 | [SSA] a | main.rs:79:30:79:38 | a.clone() | provenance | MaD:17 | +| main.rs:63:5:63:5 | a | main.rs:64:13:64:13 | a | provenance | | +| main.rs:63:5:63:5 | a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | +| main.rs:63:5:63:5 | a | main.rs:70:29:70:29 | a | provenance | | +| main.rs:63:5:63:5 | a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | +| main.rs:63:5:63:5 | a | main.rs:79:30:79:30 | a | provenance | | +| main.rs:63:5:63:5 | a | main.rs:79:30:79:38 | a.clone() | provenance | MaD:17 | | main.rs:64:13:64:13 | a | main.rs:64:13:64:21 | a.clone() | provenance | MaD:17 | | main.rs:64:13:64:21 | a.clone() | main.rs:64:9:64:11 | add | provenance | MaD:4 Sink:MaD:4 | | main.rs:68:9:68:13 | mut b | main.rs:69:20:69:20 | b | provenance | | | main.rs:68:9:68:13 | mut b | main.rs:69:20:69:28 | b.clone() | provenance | MaD:17 | | main.rs:68:9:68:13 | mut b | main.rs:72:20:72:20 | b | provenance | | | main.rs:68:9:68:13 | mut b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | -| main.rs:68:9:68:13 | mut b | main.rs:74:20:74:20 | b | provenance | | -| main.rs:68:9:68:13 | mut b | main.rs:74:20:74:28 | b.clone() | provenance | MaD:17 | | main.rs:68:17:68:29 | ...::named | main.rs:68:17:68:37 | ...::named(...) | provenance | Src:MaD:14 MaD:14 | | main.rs:68:17:68:37 | ...::named(...) | main.rs:68:9:68:13 | mut b | provenance | | | main.rs:69:20:69:20 | b | main.rs:69:20:69:28 | b.clone() | provenance | MaD:17 | | main.rs:69:20:69:28 | b.clone() | main.rs:69:16:69:18 | add | provenance | MaD:8 Sink:MaD:8 | | main.rs:70:29:70:29 | a | main.rs:70:29:70:37 | a.clone() | provenance | MaD:17 | | main.rs:70:29:70:37 | a.clone() | main.rs:70:16:70:27 | add_original | provenance | MaD:9 Sink:MaD:9 | +| main.rs:71:5:71:5 | [SSA] b | main.rs:72:20:72:20 | b | provenance | | +| main.rs:71:5:71:5 | [SSA] b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | +| main.rs:71:5:71:5 | b | main.rs:72:20:72:20 | b | provenance | | +| main.rs:71:5:71:5 | b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | | main.rs:72:20:72:20 | b | main.rs:72:20:72:28 | b.clone() | provenance | MaD:17 | | main.rs:72:20:72:28 | b.clone() | main.rs:72:16:72:18 | add | provenance | MaD:8 Sink:MaD:8 | -| main.rs:74:20:74:20 | b | main.rs:74:20:74:28 | b.clone() | provenance | MaD:17 | -| main.rs:74:20:74:28 | b.clone() | main.rs:74:16:74:18 | add | provenance | MaD:8 Sink:MaD:8 | | main.rs:77:9:77:13 | mut c | main.rs:78:21:78:21 | c | provenance | | | main.rs:77:9:77:13 | mut c | main.rs:78:21:78:29 | c.clone() | provenance | MaD:17 | | main.rs:77:9:77:13 | mut c | main.rs:83:21:83:21 | c | provenance | | | main.rs:77:9:77:13 | mut c | main.rs:83:21:83:29 | c.clone() | provenance | MaD:17 | -| main.rs:77:9:77:13 | mut c | main.rs:85:21:85:21 | c | provenance | | -| main.rs:77:9:77:13 | mut c | main.rs:85:21:85:29 | c.clone() | provenance | MaD:17 | | main.rs:77:17:77:28 | ...::from | main.rs:77:17:77:36 | ...::from(...) | provenance | Src:MaD:12 MaD:12 | | main.rs:77:17:77:36 | ...::from(...) | main.rs:77:9:77:13 | mut c | provenance | | | main.rs:78:21:78:21 | c | main.rs:78:21:78:29 | c.clone() | provenance | MaD:17 | @@ -210,8 +213,6 @@ edges | main.rs:79:30:79:38 | a.clone() | main.rs:79:17:79:28 | add_original | provenance | MaD:7 Sink:MaD:7 | | main.rs:83:21:83:21 | c | main.rs:83:21:83:29 | c.clone() | provenance | MaD:17 | | main.rs:83:21:83:29 | c.clone() | main.rs:83:17:83:19 | add | provenance | MaD:6 Sink:MaD:6 | -| main.rs:85:21:85:21 | c | main.rs:85:21:85:29 | c.clone() | provenance | MaD:17 | -| main.rs:85:21:85:29 | c.clone() | main.rs:85:17:85:19 | add | provenance | MaD:6 Sink:MaD:6 | | main.rs:87:9:87:13 | mut d | main.rs:88:13:88:13 | d | provenance | | | main.rs:87:9:87:13 | mut d | main.rs:88:13:88:21 | d.clone() | provenance | MaD:17 | | main.rs:87:9:87:13 | mut d | main.rs:94:13:94:13 | d | provenance | | @@ -223,7 +224,7 @@ edges | main.rs:94:13:94:13 | d | main.rs:94:13:94:21 | d.clone() | provenance | MaD:17 | | main.rs:94:13:94:21 | d.clone() | main.rs:94:9:94:11 | add | provenance | MaD:4 Sink:MaD:4 | | main.rs:114:5:114:17 | ...::build | main.rs:114:5:114:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:114:5:114:36 | ...::build(...) | main.rs:114:5:114:54 | ... .partitioned(...) | provenance | MaD:35 | +| main.rs:114:5:114:36 | ...::build(...) | main.rs:114:5:114:54 | ... .partitioned(...) | provenance | MaD:36 | | main.rs:114:5:114:54 | ... .partitioned(...) | main.rs:114:56:114:60 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:122:9:122:9 | a | main.rs:123:20:123:20 | a | provenance | | | main.rs:122:9:122:9 | a | main.rs:123:20:123:28 | a.clone() | provenance | MaD:17 | @@ -234,6 +235,7 @@ edges | main.rs:130:9:130:9 | c | main.rs:131:20:131:20 | c | provenance | | | main.rs:130:9:130:9 | c | main.rs:131:20:131:28 | c.clone() | provenance | MaD:17 | | main.rs:130:9:130:9 | c | main.rs:134:13:134:35 | c.set_partitioned(...) | provenance | MaD:24 | +| main.rs:130:13:130:13 | b | main.rs:130:13:130:31 | b.set_secure(...) | provenance | MaD:27 | | main.rs:130:13:130:31 | b.set_secure(...) | main.rs:130:9:130:9 | c | provenance | | | main.rs:131:20:131:20 | c | main.rs:131:20:131:28 | c.clone() | provenance | MaD:17 | | main.rs:131:20:131:28 | c.clone() | main.rs:131:13:131:18 | insert | provenance | MaD:1 Sink:MaD:1 | @@ -244,6 +246,7 @@ edges | main.rs:135:20:135:28 | d.clone() | main.rs:135:13:135:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:146:9:146:9 | g | main.rs:147:20:147:20 | g | provenance | | | main.rs:146:9:146:9 | g | main.rs:147:20:147:28 | g.clone() | provenance | MaD:17 | +| main.rs:146:13:146:13 | f | main.rs:146:13:146:31 | f.set_secure(...) | provenance | MaD:27 | | main.rs:146:13:146:31 | f.set_secure(...) | main.rs:146:9:146:9 | g | provenance | | | main.rs:147:20:147:20 | g | main.rs:147:20:147:28 | g.clone() | provenance | MaD:17 | | main.rs:147:20:147:28 | g.clone() | main.rs:147:13:147:18 | insert | provenance | MaD:1 Sink:MaD:1 | @@ -281,7 +284,7 @@ edges | main.rs:156:20:156:28 | i.clone() | main.rs:156:20:156:46 | ... .set_name(...) | provenance | MaD:23 | | main.rs:156:20:156:46 | ... .set_name(...) | main.rs:156:13:156:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:157:20:157:20 | i | main.rs:157:20:157:28 | i.clone() | provenance | MaD:17 | -| main.rs:157:20:157:28 | i.clone() | main.rs:157:20:157:48 | ... .set_value(...) | provenance | MaD:27 | +| main.rs:157:20:157:28 | i.clone() | main.rs:157:20:157:48 | ... .set_value(...) | provenance | MaD:28 | | main.rs:157:20:157:48 | ... .set_value(...) | main.rs:157:13:157:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:158:20:158:20 | i | main.rs:158:20:158:28 | i.clone() | provenance | MaD:17 | | main.rs:158:20:158:28 | i.clone() | main.rs:158:20:158:48 | ... .set_http_only(...) | provenance | MaD:21 | @@ -296,19 +299,19 @@ edges | main.rs:161:20:161:28 | i.clone() | main.rs:161:20:161:42 | ... .set_path(...) | provenance | MaD:25 | | main.rs:161:20:161:42 | ... .set_path(...) | main.rs:161:13:161:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:162:20:162:20 | i | main.rs:162:20:162:28 | i.clone() | provenance | MaD:17 | -| main.rs:162:20:162:28 | i.clone() | main.rs:162:20:162:41 | ... .unset_path() | provenance | MaD:30 | +| main.rs:162:20:162:28 | i.clone() | main.rs:162:20:162:41 | ... .unset_path() | provenance | MaD:31 | | main.rs:162:20:162:41 | ... .unset_path() | main.rs:162:13:162:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:163:20:163:20 | i | main.rs:163:20:163:28 | i.clone() | provenance | MaD:17 | | main.rs:163:20:163:28 | i.clone() | main.rs:163:20:163:54 | ... .set_domain(...) | provenance | MaD:19 | | main.rs:163:20:163:54 | ... .set_domain(...) | main.rs:163:13:163:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:164:20:164:20 | i | main.rs:164:20:164:28 | i.clone() | provenance | MaD:17 | -| main.rs:164:20:164:28 | i.clone() | main.rs:164:20:164:43 | ... .unset_domain() | provenance | MaD:28 | +| main.rs:164:20:164:28 | i.clone() | main.rs:164:20:164:43 | ... .unset_domain() | provenance | MaD:29 | | main.rs:164:20:164:43 | ... .unset_domain() | main.rs:164:13:164:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:165:20:165:20 | i | main.rs:165:20:165:28 | i.clone() | provenance | MaD:17 | | main.rs:165:20:165:28 | i.clone() | main.rs:165:20:165:46 | ... .set_expires(...) | provenance | MaD:20 | | main.rs:165:20:165:46 | ... .set_expires(...) | main.rs:165:13:165:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:166:20:166:20 | i | main.rs:166:20:166:28 | i.clone() | provenance | MaD:17 | -| main.rs:166:20:166:28 | i.clone() | main.rs:166:20:166:44 | ... .unset_expires() | provenance | MaD:29 | +| main.rs:166:20:166:28 | i.clone() | main.rs:166:20:166:44 | ... .unset_expires() | provenance | MaD:30 | | main.rs:166:20:166:44 | ... .unset_expires() | main.rs:166:13:166:18 | insert | provenance | MaD:1 Sink:MaD:1 | | main.rs:167:20:167:20 | i | main.rs:167:20:167:28 | i.clone() | provenance | MaD:17 | | main.rs:167:20:167:28 | i.clone() | main.rs:167:20:167:45 | ... .make_permanent() | provenance | MaD:18 | @@ -340,20 +343,21 @@ models | 24 | Summary: ::set_partitioned; Argument[self].OptionalBarrier[cookie-partitioned-arg0]; ReturnValue; taint | | 25 | Summary: ::set_path; Argument[self]; ReturnValue; taint | | 26 | Summary: ::set_same_site; Argument[self]; ReturnValue; taint | -| 27 | Summary: ::set_value; Argument[self]; ReturnValue; taint | -| 28 | Summary: ::unset_domain; Argument[self]; ReturnValue; taint | -| 29 | Summary: ::unset_expires; Argument[self]; ReturnValue; taint | -| 30 | Summary: ::unset_path; Argument[self]; ReturnValue; taint | -| 31 | Summary: ::domain; Argument[self]; ReturnValue; taint | -| 32 | Summary: ::expires; Argument[self]; ReturnValue; taint | -| 33 | Summary: ::http_only; Argument[self]; ReturnValue; taint | -| 34 | Summary: ::max_age; Argument[self]; ReturnValue; taint | -| 35 | Summary: ::partitioned; Argument[self].OptionalBarrier[cookie-partitioned-arg0]; ReturnValue; taint | -| 36 | Summary: ::path; Argument[self]; ReturnValue; taint | -| 37 | Summary: ::permanent; Argument[self]; ReturnValue; taint | -| 38 | Summary: ::removal; Argument[self]; ReturnValue; taint | -| 39 | Summary: ::same_site; Argument[self]; ReturnValue; taint | -| 40 | Summary: ::secure; Argument[self].OptionalBarrier[cookie-secure-arg0]; ReturnValue; taint | +| 27 | Summary: ::set_secure; Argument[self].OptionalBarrier[cookie-secure-arg0]; ReturnValue; taint | +| 28 | Summary: ::set_value; Argument[self]; ReturnValue; taint | +| 29 | Summary: ::unset_domain; Argument[self]; ReturnValue; taint | +| 30 | Summary: ::unset_expires; Argument[self]; ReturnValue; taint | +| 31 | Summary: ::unset_path; Argument[self]; ReturnValue; taint | +| 32 | Summary: ::domain; Argument[self]; ReturnValue; taint | +| 33 | Summary: ::expires; Argument[self]; ReturnValue; taint | +| 34 | Summary: ::http_only; Argument[self]; ReturnValue; taint | +| 35 | Summary: ::max_age; Argument[self]; ReturnValue; taint | +| 36 | Summary: ::partitioned; Argument[self].OptionalBarrier[cookie-partitioned-arg0]; ReturnValue; taint | +| 37 | Summary: ::path; Argument[self]; ReturnValue; taint | +| 38 | Summary: ::permanent; Argument[self]; ReturnValue; taint | +| 39 | Summary: ::removal; Argument[self]; ReturnValue; taint | +| 40 | Summary: ::same_site; Argument[self]; ReturnValue; taint | +| 41 | Summary: ::secure; Argument[self].OptionalBarrier[cookie-secure-arg0]; ReturnValue; taint | nodes | main.rs:8:19:8:31 | ...::build | semmle.label | ...::build | | main.rs:8:19:8:50 | ...::build(...) | semmle.label | ...::build(...) | @@ -458,6 +462,7 @@ nodes | main.rs:50:5:50:40 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:50:5:50:54 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:50:56:50:60 | build | semmle.label | build | +| main.rs:53:5:53:49 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:53:5:53:63 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:53:65:53:69 | build | semmle.label | build | | main.rs:58:9:58:13 | mut a | semmle.label | mut a | @@ -469,9 +474,8 @@ nodes | main.rs:60:9:60:20 | add_original | semmle.label | add_original | | main.rs:60:22:60:22 | a | semmle.label | a | | main.rs:60:22:60:30 | a.clone() | semmle.label | a.clone() | -| main.rs:62:9:62:11 | add | semmle.label | add | -| main.rs:62:13:62:13 | a | semmle.label | a | -| main.rs:62:13:62:21 | a.clone() | semmle.label | a.clone() | +| main.rs:63:5:63:5 | [SSA] a | semmle.label | [SSA] a | +| main.rs:63:5:63:5 | a | semmle.label | a | | main.rs:64:9:64:11 | add | semmle.label | add | | main.rs:64:13:64:13 | a | semmle.label | a | | main.rs:64:13:64:21 | a.clone() | semmle.label | a.clone() | @@ -484,12 +488,11 @@ nodes | main.rs:70:16:70:27 | add_original | semmle.label | add_original | | main.rs:70:29:70:29 | a | semmle.label | a | | main.rs:70:29:70:37 | a.clone() | semmle.label | a.clone() | +| main.rs:71:5:71:5 | [SSA] b | semmle.label | [SSA] b | +| main.rs:71:5:71:5 | b | semmle.label | b | | main.rs:72:16:72:18 | add | semmle.label | add | | main.rs:72:20:72:20 | b | semmle.label | b | | main.rs:72:20:72:28 | b.clone() | semmle.label | b.clone() | -| main.rs:74:16:74:18 | add | semmle.label | add | -| main.rs:74:20:74:20 | b | semmle.label | b | -| main.rs:74:20:74:28 | b.clone() | semmle.label | b.clone() | | main.rs:77:9:77:13 | mut c | semmle.label | mut c | | main.rs:77:17:77:28 | ...::from | semmle.label | ...::from | | main.rs:77:17:77:36 | ...::from(...) | semmle.label | ...::from(...) | @@ -502,9 +505,6 @@ nodes | main.rs:83:17:83:19 | add | semmle.label | add | | main.rs:83:21:83:21 | c | semmle.label | c | | main.rs:83:21:83:29 | c.clone() | semmle.label | c.clone() | -| main.rs:85:17:85:19 | add | semmle.label | add | -| main.rs:85:21:85:21 | c | semmle.label | c | -| main.rs:85:21:85:29 | c.clone() | semmle.label | c.clone() | | main.rs:87:9:87:13 | mut d | semmle.label | mut d | | main.rs:87:17:87:28 | ...::from | semmle.label | ...::from | | main.rs:87:17:87:36 | ...::from(...) | semmle.label | ...::from(...) | @@ -525,6 +525,7 @@ nodes | main.rs:123:20:123:20 | a | semmle.label | a | | main.rs:123:20:123:28 | a.clone() | semmle.label | a.clone() | | main.rs:130:9:130:9 | c | semmle.label | c | +| main.rs:130:13:130:13 | b | semmle.label | b | | main.rs:130:13:130:31 | b.set_secure(...) | semmle.label | b.set_secure(...) | | main.rs:131:13:131:18 | insert | semmle.label | insert | | main.rs:131:20:131:20 | c | semmle.label | c | @@ -535,6 +536,7 @@ nodes | main.rs:135:20:135:20 | d | semmle.label | d | | main.rs:135:20:135:28 | d.clone() | semmle.label | d.clone() | | main.rs:146:9:146:9 | g | semmle.label | g | +| main.rs:146:13:146:13 | f | semmle.label | f | | main.rs:146:13:146:31 | f.set_secure(...) | semmle.label | f.set_secure(...) | | main.rs:147:13:147:18 | insert | semmle.label | insert | | main.rs:147:20:147:20 | g | semmle.label | g | diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 6cbb786cea5..4cd35ac9314 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -59,7 +59,7 @@ fn test_cookie(sometimes: bool) { jar.add(a.clone()); // $ Alert[rust/insecure-cookie] jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] a.set_secure(true); - jar.add(a.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + jar.add(a.clone()); // good a.set_secure(false); jar.add(a.clone()); // $ Alert[rust/insecure-cookie] @@ -71,7 +71,7 @@ fn test_cookie(sometimes: bool) { b.set_secure(sometimes); signed_jar.add(b.clone()); // $ Alert[rust/insecure-cookie] b.set_secure(true); - signed_jar.add(b.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + signed_jar.add(b.clone()); // good let mut private_jar = jar.private_mut(&key); let mut c = Cookie::from("name"); @@ -82,7 +82,7 @@ fn test_cookie(sometimes: bool) { } private_jar.add(c.clone()); // $ Alert[rust/insecure-cookie] c.set_secure(true); - private_jar.add(c.clone()); // $ SPURIOUS: Alert[rust/insecure-cookie] + private_jar.add(c.clone()); // $ good let mut d = Cookie::from("name"); jar.add(d.clone()); // $ Alert[rust/insecure-cookie] From 94afc82304b202e74c9114ab56810216a24e545a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 14:50:46 +0100 Subject: [PATCH 079/160] Rust: Fix an issue with the local flow. --- .../codeql/rust/security/InsecureCookieExtensions.qll | 10 ++++++---- .../query-tests/security/CWE-614/CookieSet.expected | 2 +- .../security/CWE-614/InsecureCookie.expected | 9 --------- rust/ql/test/query-tests/security/CWE-614/main.rs | 2 +- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 93406f91452..30a033ba155 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -69,11 +69,13 @@ module InsecureCookie { // check if the argument is always `true` ( if - forex(DataFlow::Node argSourceNode | DataFlow::localFlow(argSourceNode, argNode) | - argSourceNode.asExpr().getExpr().(BooleanLiteralExpr).getTextValue() = "true" + forex(DataFlow::Node argSourceNode, BooleanLiteralExpr argSourceValue | + DataFlow::localFlow(argSourceNode, argNode) and + argSourceValue = argSourceNode.asExpr().getExpr() | + argSourceValue.getTextValue() = "true" ) - then value = true // `true` flow to here - else value = false // `false` or unknown + then value = true // `true` flows to here + else value = false // `false`, unknown, or multiple values ) and // and find the node where this happens ( diff --git a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected index eacadaa722d..44f5ff01fbd 100644 --- a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected +++ b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected @@ -2,7 +2,7 @@ | main.rs:12:19:12:50 | ...::build(...) | secure | true | | main.rs:20:5:20:36 | ...::build(...) | secure | false | | main.rs:21:5:21:36 | ...::build(...) | secure | false | -| main.rs:24:5:24:36 | ...::build(...) | secure | false | +| main.rs:24:5:24:36 | ...::build(...) | secure | true | | main.rs:25:5:25:36 | ...::build(...) | secure | false | | main.rs:26:5:26:36 | ...::build(...) | secure | false | | main.rs:27:5:27:36 | ...::build(...) | secure | false | diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected index 880262e9bd4..701f90c0f34 100644 --- a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -6,8 +6,6 @@ | main.rs:20:56:20:60 | build | main.rs:20:5:20:36 | ...::build(...) | main.rs:20:56:20:60 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:21:57:21:61 | build | main.rs:21:5:21:17 | ...::build | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:21:57:21:61 | build | main.rs:21:5:21:36 | ...::build(...) | main.rs:21:57:21:61 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:24:53:24:57 | build | main.rs:24:5:24:17 | ...::build | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | -| main.rs:24:53:24:57 | build | main.rs:24:5:24:36 | ...::build(...) | main.rs:24:53:24:57 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:25:54:25:58 | build | main.rs:25:5:25:17 | ...::build | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:25:54:25:58 | build | main.rs:25:5:25:36 | ...::build(...) | main.rs:25:54:25:58 | build | Cookie attribute 'Secure' is not set to true. | | main.rs:26:52:26:56 | build | main.rs:26:5:26:17 | ...::build | main.rs:26:52:26:56 | build | Cookie attribute 'Secure' is not set to true. | @@ -91,9 +89,6 @@ edges | main.rs:21:5:21:17 | ...::build | main.rs:21:5:21:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | | main.rs:21:5:21:36 | ...::build(...) | main.rs:21:5:21:55 | ... .secure(...) | provenance | MaD:41 | | main.rs:21:5:21:55 | ... .secure(...) | main.rs:21:57:21:61 | build | provenance | MaD:2 Sink:MaD:2 | -| main.rs:24:5:24:17 | ...::build | main.rs:24:5:24:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | -| main.rs:24:5:24:36 | ...::build(...) | main.rs:24:5:24:51 | ... .secure(...) | provenance | MaD:41 | -| main.rs:24:5:24:51 | ... .secure(...) | main.rs:24:53:24:57 | build | provenance | MaD:2 Sink:MaD:2 | | main.rs:25:5:25:17 | ...::build | main.rs:25:5:25:36 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | | main.rs:25:5:25:36 | ...::build(...) | main.rs:25:5:25:52 | ... .secure(...) | provenance | MaD:41 | | main.rs:25:5:25:52 | ... .secure(...) | main.rs:25:54:25:58 | build | provenance | MaD:2 Sink:MaD:2 | @@ -374,10 +369,6 @@ nodes | main.rs:21:5:21:36 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:21:5:21:55 | ... .secure(...) | semmle.label | ... .secure(...) | | main.rs:21:57:21:61 | build | semmle.label | build | -| main.rs:24:5:24:17 | ...::build | semmle.label | ...::build | -| main.rs:24:5:24:36 | ...::build(...) | semmle.label | ...::build(...) | -| main.rs:24:5:24:51 | ... .secure(...) | semmle.label | ... .secure(...) | -| main.rs:24:53:24:57 | build | semmle.label | build | | main.rs:25:5:25:17 | ...::build | semmle.label | ...::build | | main.rs:25:5:25:36 | ...::build(...) | semmle.label | ...::build(...) | | main.rs:25:5:25:52 | ... .secure(...) | semmle.label | ... .secure(...) | diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 4cd35ac9314..48671b737a6 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -21,7 +21,7 @@ fn test_cookie(sometimes: bool) { Cookie::build(("name", "value")).secure(!sometimes).build(); // $ Alert[rust/insecure-cookie] // with data flow on the "secure" value - Cookie::build(("name", "value")).secure(always).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] + Cookie::build(("name", "value")).secure(always).build(); // good Cookie::build(("name", "value")).secure(!always).build(); // $ Alert[rust/insecure-cookie] Cookie::build(("name", "value")).secure(never).build(); // $ Alert[rust/insecure-cookie] Cookie::build(("name", "value")).secure(!never).build(); // $ SPURIOUS: Alert[rust/insecure-cookie] From bd07350bc3999ca549a31a9e0a3ca01ffa94adb5 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 Sep 2025 10:05:11 +0100 Subject: [PATCH 080/160] Rust: Add qhelp and examples. --- .../security/CWE-614/InsecureCookie.qhelp | 33 +++++++++++++++++++ .../security/CWE-614/InsecureCookieBad.rs | 6 ++++ .../security/CWE-614/InsecureCookieGood.rs | 11 +++++++ 3 files changed, 50 insertions(+) create mode 100644 rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp create mode 100644 rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs create mode 100644 rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp new file mode 100644 index 00000000000..ef08ff27b9c --- /dev/null +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp @@ -0,0 +1,33 @@ + + + + +

    Failing to set the 'Secure' attribute on a cookie allows it to be transmitted over an unencrypted (HTTP) connection. If an attacker can observe a user's network traffic (for example over an insecure Wi‑Fi network), they can access sensitive information in the cookie and potentially use it to impersonate the user.

    + +
    + + +

    Always set the cookie 'Secure' attribute so that the browser only sends the cookie over HTTPS.

    + +
    + + +

    The following example creates a cookie using the cookie crate without the 'Secure' attribute:

    + + + +

    In the fixed example, we either call secure(true) on the CookieBuilder or set_secure(true) on the Cookie itself:

    + + + +
    + + +
  • MDN Web Docs: Using HTTP cookies.
  • +
  • OWASP Cheat Sheet Series: Session Management Cheat Sheet - Transport Layer Security.
  • +
  • MDN Web Docs: Set-Cookie header - Secure.
  • + + +
    diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs b/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs new file mode 100644 index 00000000000..239776e99de --- /dev/null +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs @@ -0,0 +1,6 @@ +use cookie::Cookie; + +// BAD: creating a cookie without specifying the `secure` attribute +let cookie = Cookie::build("session", "abcd1234").build(); +let mut jar = cookie::CookieJar::new(); +jar.add(cookie.clone()); diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs b/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs new file mode 100644 index 00000000000..81971552d0f --- /dev/null +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs @@ -0,0 +1,11 @@ +use cookie::Cookie; + +// GOOD: set the `CookieBuilder` 'Secure' attribute so that the cookie is only sent over HTTPS +let secure_cookie = Cookie::build("session", "abcd1234").secure(true).build(); +let mut jar = cookie::CookieJar::new(); +jar.add(secure_cookie.clone()); + +// GOOD: alternatively, set the 'Secure' attribute on an existing `Cookie` +let mut secure_cookie2 = Cookie::new("session", "abcd1234"); +secure_cookie2.set_secure(true); +jar.add(secure_cookie2); From 4662e42584d13987d8d5a09c7edaef137db8c325 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 15:00:14 +0100 Subject: [PATCH 081/160] Rust: Add examples as tests (and fix them). --- .../security/CWE-614/InsecureCookieBad.rs | 2 +- .../security/CWE-614/InsecureCookieGood.rs | 2 +- .../security/CWE-614/CookieSet.expected | 3 +++ .../security/CWE-614/InsecureCookie.expected | 6 +++++ .../test/query-tests/security/CWE-614/main.rs | 22 +++++++++++++++++++ 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs b/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs index 239776e99de..e4939f6d5c8 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookieBad.rs @@ -1,6 +1,6 @@ use cookie::Cookie; // BAD: creating a cookie without specifying the `secure` attribute -let cookie = Cookie::build("session", "abcd1234").build(); +let cookie = Cookie::build(("session", "abcd1234")).build(); let mut jar = cookie::CookieJar::new(); jar.add(cookie.clone()); diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs b/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs index 81971552d0f..886d969604c 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookieGood.rs @@ -1,7 +1,7 @@ use cookie::Cookie; // GOOD: set the `CookieBuilder` 'Secure' attribute so that the cookie is only sent over HTTPS -let secure_cookie = Cookie::build("session", "abcd1234").secure(true).build(); +let secure_cookie = Cookie::build(("session", "abcd1234")).secure(true).build(); let mut jar = cookie::CookieJar::new(); jar.add(secure_cookie.clone()); diff --git a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected index 44f5ff01fbd..959648d37ed 100644 --- a/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected +++ b/rust/ql/test/query-tests/security/CWE-614/CookieSet.expected @@ -49,3 +49,6 @@ | main.rs:138:13:138:13 | d | secure | true | | main.rs:142:13:142:13 | e | partitioned | false | | main.rs:146:13:146:13 | f | secure | false | +| main.rs:180:29:180:66 | ...::build(...) | secure | true | +| main.rs:186:9:186:22 | [SSA] secure_cookie2 | secure | true | +| main.rs:186:9:186:22 | secure_cookie2 | secure | true | diff --git a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected index 701f90c0f34..e514828c3a0 100644 --- a/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected +++ b/rust/ql/test/query-tests/security/CWE-614/InsecureCookie.expected @@ -77,6 +77,7 @@ | main.rs:165:13:165:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:165:13:165:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:166:13:166:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:166:13:166:18 | insert | Cookie attribute 'Secure' is not set to true. | | main.rs:167:13:167:18 | insert | main.rs:155:13:155:41 | ...::new | main.rs:167:13:167:18 | insert | Cookie attribute 'Secure' is not set to true. | +| main.rs:173:61:173:65 | build | main.rs:173:22:173:34 | ...::build | main.rs:173:61:173:65 | build | Cookie attribute 'Secure' is not set to true. | edges | main.rs:8:19:8:31 | ...::build | main.rs:8:19:8:50 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | | main.rs:8:19:8:50 | ...::build(...) | main.rs:8:19:8:64 | ... .secure(...) | provenance | MaD:41 | @@ -311,6 +312,8 @@ edges | main.rs:167:20:167:20 | i | main.rs:167:20:167:28 | i.clone() | provenance | MaD:17 | | main.rs:167:20:167:28 | i.clone() | main.rs:167:20:167:45 | ... .make_permanent() | provenance | MaD:18 | | main.rs:167:20:167:45 | ... .make_permanent() | main.rs:167:13:167:18 | insert | provenance | MaD:1 Sink:MaD:1 | +| main.rs:173:22:173:34 | ...::build | main.rs:173:22:173:59 | ...::build(...) | provenance | Src:MaD:13 MaD:13 | +| main.rs:173:22:173:59 | ...::build(...) | main.rs:173:61:173:65 | build | provenance | MaD:2 Sink:MaD:2 | models | 1 | Sink: ::insert; Argument[0]; cookie-use | | 2 | Sink: ::build; Argument[self]; cookie-use | @@ -588,4 +591,7 @@ nodes | main.rs:167:20:167:20 | i | semmle.label | i | | main.rs:167:20:167:28 | i.clone() | semmle.label | i.clone() | | main.rs:167:20:167:45 | ... .make_permanent() | semmle.label | ... .make_permanent() | +| main.rs:173:22:173:34 | ...::build | semmle.label | ...::build | +| main.rs:173:22:173:59 | ...::build(...) | semmle.label | ...::build(...) | +| main.rs:173:61:173:65 | build | semmle.label | build | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 48671b737a6..e14ac6719d6 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -167,8 +167,30 @@ fn test_biscotti() { cookies.insert(i.clone().make_permanent()); // $ Alert[rust/insecure-cookie] } +fn test_qhelp_examples() {use cookie::Cookie; + { + // BAD: creating a cookie without specifying the `secure` attribute + let cookie = Cookie::build(("session", "abcd1234")).build(); // $ Alert[rust/insecure-cookie] + let mut jar = cookie::CookieJar::new(); + jar.add(cookie.clone()); + } + + { + // GOOD: set the `CookieBuilder` 'Secure' attribute so that the cookie is only sent over HTTPS + let secure_cookie = Cookie::build(("session", "abcd1234")).secure(true).build(); + let mut jar = cookie::CookieJar::new(); + jar.add(secure_cookie.clone()); + + // GOOD: alternatively, set the 'Secure' attribute on an existing `Cookie` + let mut secure_cookie2 = Cookie::new("session", "abcd1234"); + secure_cookie2.set_secure(true); + jar.add(secure_cookie2); + } +} + fn main() { test_cookie(true); test_cookie(false); test_biscotti(); + test_qhelp_examples(); } From ae9025334e747e6170d89b3be583bed11627afce Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 Sep 2025 16:31:34 +0100 Subject: [PATCH 082/160] Rust: Add the new query to suite lists. --- .../query-suite/rust-code-scanning.qls.expected | 1 + .../query-suite/rust-security-and-quality.qls.expected | 1 + .../query-suite/rust-security-extended.qls.expected | 1 + 3 files changed, 3 insertions(+) diff --git a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected index b601905e6a3..2035af15218 100644 --- a/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected +++ b/rust/ql/integration-tests/query-suite/rust-code-scanning.qls.expected @@ -16,6 +16,7 @@ ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql ql/rust/ql/src/queries/security/CWE-328/WeakSensitiveDataHashing.ql +ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql ql/rust/ql/src/queries/security/CWE-825/AccessInvalidPointer.ql diff --git a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected index 074cb2ec888..960ba9079cc 100644 --- a/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected +++ b/rust/ql/integration-tests/query-suite/rust-security-and-quality.qls.expected @@ -17,6 +17,7 @@ ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql ql/rust/ql/src/queries/security/CWE-328/WeakSensitiveDataHashing.ql +ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql ql/rust/ql/src/queries/security/CWE-696/BadCtorInitialization.ql ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql diff --git a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected index 38846e281eb..d758b7ac8d5 100644 --- a/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected +++ b/rust/ql/integration-tests/query-suite/rust-security-extended.qls.expected @@ -17,6 +17,7 @@ ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql ql/rust/ql/src/queries/security/CWE-327/BrokenCryptoAlgorithm.ql ql/rust/ql/src/queries/security/CWE-328/WeakSensitiveDataHashing.ql +ql/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql ql/rust/ql/src/queries/security/CWE-770/UncontrolledAllocationSize.ql ql/rust/ql/src/queries/security/CWE-798/HardcodedCryptographicValue.ql ql/rust/ql/src/queries/security/CWE-825/AccessAfterLifetime.ql From 3de191177cdb21b20495f11e54503d4a83d173d8 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 19 Sep 2025 16:35:54 +0100 Subject: [PATCH 083/160] Rust: Change note. --- rust/ql/src/change-notes/2025-09-19-insecure-cookie.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 rust/ql/src/change-notes/2025-09-19-insecure-cookie.md diff --git a/rust/ql/src/change-notes/2025-09-19-insecure-cookie.md b/rust/ql/src/change-notes/2025-09-19-insecure-cookie.md new file mode 100644 index 00000000000..d84da707c43 --- /dev/null +++ b/rust/ql/src/change-notes/2025-09-19-insecure-cookie.md @@ -0,0 +1,4 @@ +--- +category: newQuery +--- +* Added a new query, `rust/insecure-cookie`, to detect cookies created without the 'Secure' attribute. From cc9c4149d7ae4ce30fc6fe0d3717076ab70ad801 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:54:08 +0100 Subject: [PATCH 084/160] Apply suggestions from code review --- rust/ql/test/query-tests/security/CWE-614/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index e14ac6719d6..674ad95a7ba 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -167,7 +167,7 @@ fn test_biscotti() { cookies.insert(i.clone().make_permanent()); // $ Alert[rust/insecure-cookie] } -fn test_qhelp_examples() {use cookie::Cookie; +fn test_qhelp_examples() { { // BAD: creating a cookie without specifying the `secure` attribute let cookie = Cookie::build(("session", "abcd1234")).build(); // $ Alert[rust/insecure-cookie] From 5b4632b4326765014dfb8d4532ce1807c206ee37 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:55:43 +0100 Subject: [PATCH 085/160] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- rust/ql/src/queries/security/CWE-614/InsecureCookie.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index 987940a2f0a..e215bd65f03 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -20,7 +20,7 @@ import codeql.rust.security.InsecureCookieExtensions /** * A data flow configuration for tracking values representing cookies without the - * 'secure' attribute set. This is the primary data flow configurationn for this + * 'secure' attribute set. This is the primary data flow configuration for this * query. */ module InsecureCookieConfig implements DataFlow::ConfigSig { From 43ac75ed625e3e5d0fe6d2a06b6e4d1566b53fbb Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:58:07 +0100 Subject: [PATCH 086/160] Rust: Address another tiny suggestion from review. --- rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 30a033ba155..0dea9844d0b 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -8,7 +8,7 @@ private import codeql.rust.dataflow.DataFlow private import codeql.rust.dataflow.FlowSource private import codeql.rust.dataflow.FlowSink private import codeql.rust.Concepts -private import codeql.rust.dataflow.internal.DataFlowImpl as DataflowImpl +private import codeql.rust.dataflow.internal.DataFlowImpl as DataFlowImpl private import codeql.rust.dataflow.internal.Node private import codeql.rust.controlflow.BasicBlocks @@ -60,7 +60,7 @@ module InsecureCookie { DataFlow::Node argNode | // decode a `cookie-`... optional barrier - DataflowImpl::optionalBarrier(summaryNode, barrierName) and + DataFlowImpl::optionalBarrier(summaryNode, barrierName) and attrib = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 1) and arg = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 2).toInt() and // find a call and arg referenced by this optional barrier From 6362884d1683e8674775bc514537f90768ebbbba Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 16:59:11 +0100 Subject: [PATCH 087/160] Rust: Autoformat. --- rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 0dea9844d0b..3525614c0dc 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -71,7 +71,8 @@ module InsecureCookie { if forex(DataFlow::Node argSourceNode, BooleanLiteralExpr argSourceValue | DataFlow::localFlow(argSourceNode, argNode) and - argSourceValue = argSourceNode.asExpr().getExpr() | + argSourceValue = argSourceNode.asExpr().getExpr() + | argSourceValue.getTextValue() = "true" ) then value = true // `true` flows to here From 86c8c3c8c09e98ca7a8f04ae692d431b90699bb0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 17:01:12 +0100 Subject: [PATCH 088/160] Rust: Fix warning by making the query a path-problem. --- rust/ql/src/queries/security/CWE-614/InsecureCookie.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql index e215bd65f03..e2d7288db45 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.ql @@ -3,7 +3,7 @@ * @description Omitting the 'Secure' attribute allows data to be transmitted insecurely * using HTTP. Always set 'Secure' to 'true' to ensure that HTTPS * is used at all times. - * @kind problem + * @kind path-problem * @problem.severity error * @security-severity 7.5 * @precision high From 266624dd0f653a237c6a863d2e49370f68388669 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 22 Sep 2025 17:12:52 +0100 Subject: [PATCH 089/160] Rust: The test needs to have Source tags now. --- .../test/query-tests/security/CWE-614/main.rs | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-614/main.rs b/rust/ql/test/query-tests/security/CWE-614/main.rs index 674ad95a7ba..afcbb28931f 100644 --- a/rust/ql/test/query-tests/security/CWE-614/main.rs +++ b/rust/ql/test/query-tests/security/CWE-614/main.rs @@ -55,26 +55,26 @@ fn test_cookie(sometimes: bool) { // mutable cookie let mut jar = CookieJar::new(); - let mut a = Cookie::new("name", "value"); + let mut a = Cookie::new("name", "value"); // $ Source jar.add(a.clone()); // $ Alert[rust/insecure-cookie] jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] a.set_secure(true); jar.add(a.clone()); // good - a.set_secure(false); + a.set_secure(false); // $ Source jar.add(a.clone()); // $ Alert[rust/insecure-cookie] let key = Key::generate(); let mut signed_jar = jar.signed_mut(&key); - let mut b = Cookie::named("name"); + let mut b = Cookie::named("name"); // $ Source signed_jar.add(b.clone()); // $ Alert[rust/insecure-cookie] signed_jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] - b.set_secure(sometimes); + b.set_secure(sometimes); // $ Source signed_jar.add(b.clone()); // $ Alert[rust/insecure-cookie] b.set_secure(true); signed_jar.add(b.clone()); // good let mut private_jar = jar.private_mut(&key); - let mut c = Cookie::from("name"); + let mut c = Cookie::from("name"); // $ Source private_jar.add(c.clone()); // $ Alert[rust/insecure-cookie] private_jar.add_original(a.clone()); // $ Alert[rust/insecure-cookie] if sometimes { @@ -84,7 +84,7 @@ fn test_cookie(sometimes: bool) { c.set_secure(true); private_jar.add(c.clone()); // $ good - let mut d = Cookie::from("name"); + let mut d = Cookie::from("name"); // $ Source jar.add(d.clone()); // $ Alert[rust/insecure-cookie] if sometimes { c.set_secure(true); @@ -119,7 +119,7 @@ fn test_biscotti() { // test set_secure, set_partitioned - let a = biscotti::ResponseCookie::new("name", "value"); + let a = biscotti::ResponseCookie::new("name", "value"); // $ Source cookies.insert(a.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti1 = {}", a.to_string()); @@ -127,7 +127,7 @@ fn test_biscotti() { cookies.insert(b.clone()); // good println!("biscotti2 = {}", b.to_string()); - let c = b.set_secure(false); + let c = b.set_secure(false); // $ Source cookies.insert(c.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti3 = {}", c.to_string()); @@ -143,16 +143,16 @@ fn test_biscotti() { cookies.insert(f.clone()); // good println!("biscotti6 = {}", f.to_string()); - let g = f.set_secure(false); + let g = f.set_secure(false); // $ Source cookies.insert(g.clone()); // $ Alert[rust/insecure-cookie] println!("biscotti7 = {}", g.to_string()); // variant creation (insecure) - let h = biscotti::ResponseCookie::from(("name", "value")); + let h = biscotti::ResponseCookie::from(("name", "value")); // $ Source cookies.insert(h); // $ Alert[rust/insecure-cookie] // variant uses (all insecure) - let i = biscotti::ResponseCookie::new("name", "value"); + let i = biscotti::ResponseCookie::new("name", "value"); // $ Source cookies.insert(i.clone().set_name("name2")); // $ Alert[rust/insecure-cookie] cookies.insert(i.clone().set_value("value2")); // $ Alert[rust/insecure-cookie] cookies.insert(i.clone().set_http_only(true)); // $ Alert[rust/insecure-cookie] From ecd0ce65fe91f6ff604185c59f526ca0442c8389 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Mon, 22 Sep 2025 12:52:30 -0400 Subject: [PATCH 090/160] Refactor GrapeHeadersBlockCall and GrapeCookiesBlockCall to simplify method call checks --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index 95aa42fdfad..7e3d6c54fe4 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -237,11 +237,8 @@ module Grape { */ private class GrapeHeadersBlockCall extends MethodCall { GrapeHeadersBlockCall() { - exists(GrapeApiClass api | - this.getParent+() = api.getADeclaration() and - this.getMethodName() = "headers" and - exists(this.getBlock()) - ) + this = grapeApiInstance().getAMethodCall("headers").asExpr().getExpr() and + exists(this.getBlock()) } } @@ -251,11 +248,8 @@ module Grape { */ private class GrapeCookiesBlockCall extends MethodCall { GrapeCookiesBlockCall() { - exists(GrapeApiClass api | - this.getParent+() = api.getADeclaration() and - this.getMethodName() = "cookies" and - exists(this.getBlock()) - ) + this = grapeApiInstance().getAMethodCall("cookies").asExpr().getExpr() and + exists(this.getBlock()) } } From 1183e50435d615679a27644e290138684aa7d203 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 22 Sep 2025 19:45:34 +0200 Subject: [PATCH 091/160] Update rust/ql/lib/change-notes/2025-09-19-parameter-mad.md --- rust/ql/lib/change-notes/2025-09-19-parameter-mad.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/change-notes/2025-09-19-parameter-mad.md b/rust/ql/lib/change-notes/2025-09-19-parameter-mad.md index 06f664a5213..fa3970790fa 100644 --- a/rust/ql/lib/change-notes/2025-09-19-parameter-mad.md +++ b/rust/ql/lib/change-notes/2025-09-19-parameter-mad.md @@ -3,5 +3,5 @@ category: feature --- * The models-as-data format for sources now supports access paths of the form `Argument[i].Parameter[j]`. This denotes that the source passes tainted data to - the `j`th parameter of it's `i`th argument (which must be a function or a + the `j`th parameter of its `i`th argument (which must be a function or a closure). \ No newline at end of file From 0665c39a072181e9adac06470466ff4377b17148 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Mon, 22 Sep 2025 19:08:34 -0400 Subject: [PATCH 092/160] Refactor GrapeHelperMethod constructor to reuse getHelperSelf to traverse dataflow instead of AST - add tests to check for nested helpers --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 7 +- .../frameworks/grape/Flow.expected | 276 ++++++++++++------ .../frameworks/grape/Grape.expected | 32 +- .../library-tests/frameworks/grape/app.rb | 71 +++++ 4 files changed, 275 insertions(+), 111 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index 7e3d6c54fe4..4d64e9461b3 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -291,12 +291,7 @@ module Grape { private class GrapeHelperMethod extends Method { private GrapeApiClass apiClass; - GrapeHelperMethod() { - exists(DataFlow::CallNode helpersCall | - helpersCall = apiClass.getAModuleLevelCall("helpers") and - this.getParent+() = helpersCall.getBlock().asExpr().getExpr() - ) - } + GrapeHelperMethod() { this = apiClass.getHelperSelf().getSelfVariable().getDeclaringScope() } /** * Gets the API class that contains this helper method. diff --git a/ruby/ql/test/library-tests/frameworks/grape/Flow.expected b/ruby/ql/test/library-tests/frameworks/grape/Flow.expected index c104b36afb2..f04bd930ea9 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Flow.expected +++ b/ruby/ql/test/library-tests/frameworks/grape/Flow.expected @@ -2,44 +2,80 @@ models edges | app.rb:103:13:103:18 | call to params | app.rb:103:13:103:70 | call to select | provenance | | | app.rb:103:13:103:18 | call to params | app.rb:103:13:103:70 | call to select : [collection] [element] | provenance | | -| app.rb:103:13:103:70 | call to select | app.rb:149:21:149:31 | call to user_params | provenance | | -| app.rb:103:13:103:70 | call to select | app.rb:165:21:165:31 | call to user_params | provenance | | -| app.rb:103:13:103:70 | call to select : [collection] [element] | app.rb:149:21:149:31 | call to user_params : [collection] [element] | provenance | | -| app.rb:103:13:103:70 | call to select : [collection] [element] | app.rb:165:21:165:31 | call to user_params : [collection] [element] | provenance | | -| app.rb:107:13:107:32 | call to source | app.rb:143:18:143:43 | call to vulnerable_helper | provenance | | -| app.rb:107:13:107:32 | call to source | app.rb:143:18:143:43 | call to vulnerable_helper | provenance | | -| app.rb:111:13:111:33 | call to source | app.rb:150:25:150:37 | call to simple_helper | provenance | | -| app.rb:111:13:111:33 | call to source | app.rb:150:25:150:37 | call to simple_helper | provenance | | -| app.rb:126:9:126:15 | user_id | app.rb:133:14:133:20 | user_id | provenance | | -| app.rb:126:19:126:24 | call to params | app.rb:126:19:126:34 | ...[...] | provenance | | -| app.rb:126:19:126:34 | ...[...] | app.rb:126:9:126:15 | user_id | provenance | | -| app.rb:127:9:127:16 | route_id | app.rb:134:14:134:21 | route_id | provenance | | -| app.rb:127:20:127:40 | call to route_param | app.rb:127:9:127:16 | route_id | provenance | | -| app.rb:128:9:128:12 | auth | app.rb:135:14:135:17 | auth | provenance | | -| app.rb:128:16:128:22 | call to headers | app.rb:128:16:128:38 | ...[...] | provenance | | -| app.rb:128:16:128:38 | ...[...] | app.rb:128:9:128:12 | auth | provenance | | -| app.rb:129:9:129:15 | session | app.rb:136:14:136:20 | session | provenance | | -| app.rb:129:19:129:25 | call to cookies | app.rb:129:19:129:38 | ...[...] | provenance | | -| app.rb:129:19:129:38 | ...[...] | app.rb:129:9:129:15 | session | provenance | | -| app.rb:143:9:143:14 | result | app.rb:144:14:144:19 | result | provenance | | -| app.rb:143:9:143:14 | result | app.rb:144:14:144:19 | result | provenance | | -| app.rb:143:18:143:43 | call to vulnerable_helper | app.rb:143:9:143:14 | result | provenance | | -| app.rb:143:18:143:43 | call to vulnerable_helper | app.rb:143:9:143:14 | result | provenance | | -| app.rb:149:9:149:17 | user_data | app.rb:151:14:151:22 | user_data | provenance | | -| app.rb:149:9:149:17 | user_data : [collection] [element] | app.rb:151:14:151:22 | user_data | provenance | | -| app.rb:149:21:149:31 | call to user_params | app.rb:149:9:149:17 | user_data | provenance | | -| app.rb:149:21:149:31 | call to user_params : [collection] [element] | app.rb:149:9:149:17 | user_data : [collection] [element] | provenance | | -| app.rb:150:9:150:21 | simple_result | app.rb:152:14:152:26 | simple_result | provenance | | -| app.rb:150:9:150:21 | simple_result | app.rb:152:14:152:26 | simple_result | provenance | | -| app.rb:150:25:150:37 | call to simple_helper | app.rb:150:9:150:21 | simple_result | provenance | | -| app.rb:150:25:150:37 | call to simple_helper | app.rb:150:9:150:21 | simple_result | provenance | | -| app.rb:159:13:159:19 | user_id | app.rb:160:18:160:24 | user_id | provenance | | -| app.rb:159:23:159:28 | call to params | app.rb:159:23:159:33 | ...[...] | provenance | | -| app.rb:159:23:159:33 | ...[...] | app.rb:159:13:159:19 | user_id | provenance | | -| app.rb:165:9:165:17 | user_data | app.rb:166:14:166:22 | user_data | provenance | | -| app.rb:165:9:165:17 | user_data : [collection] [element] | app.rb:166:14:166:22 | user_data | provenance | | -| app.rb:165:21:165:31 | call to user_params | app.rb:165:9:165:17 | user_data | provenance | | -| app.rb:165:21:165:31 | call to user_params : [collection] [element] | app.rb:165:9:165:17 | user_data : [collection] [element] | provenance | | +| app.rb:103:13:103:70 | call to select | app.rb:189:21:189:31 | call to user_params | provenance | | +| app.rb:103:13:103:70 | call to select | app.rb:205:21:205:31 | call to user_params | provenance | | +| app.rb:103:13:103:70 | call to select : [collection] [element] | app.rb:189:21:189:31 | call to user_params : [collection] [element] | provenance | | +| app.rb:103:13:103:70 | call to select : [collection] [element] | app.rb:205:21:205:31 | call to user_params : [collection] [element] | provenance | | +| app.rb:107:13:107:32 | call to source | app.rb:183:18:183:43 | call to vulnerable_helper | provenance | | +| app.rb:107:13:107:32 | call to source | app.rb:183:18:183:43 | call to vulnerable_helper | provenance | | +| app.rb:111:13:111:33 | call to source | app.rb:190:25:190:37 | call to simple_helper | provenance | | +| app.rb:111:13:111:33 | call to source | app.rb:190:25:190:37 | call to simple_helper | provenance | | +| app.rb:118:17:118:43 | call to source | app.rb:212:23:212:39 | call to authenticate_user | provenance | | +| app.rb:118:17:118:43 | call to source | app.rb:212:23:212:39 | call to authenticate_user | provenance | | +| app.rb:122:17:122:47 | call to source | app.rb:216:23:216:48 | call to check_permissions | provenance | | +| app.rb:122:17:122:47 | call to source | app.rb:216:23:216:48 | call to check_permissions | provenance | | +| app.rb:128:17:128:42 | call to source | app.rb:220:29:220:80 | call to validate_email | provenance | | +| app.rb:128:17:128:42 | call to source | app.rb:220:29:220:80 | call to validate_email | provenance | | +| app.rb:134:17:134:42 | call to source | app.rb:225:28:225:39 | call to debug_helper | provenance | | +| app.rb:134:17:134:42 | call to source | app.rb:225:28:225:39 | call to debug_helper | provenance | | +| app.rb:140:17:140:37 | call to source | app.rb:230:25:230:37 | call to rescue_helper | provenance | | +| app.rb:140:17:140:37 | call to source | app.rb:230:25:230:37 | call to rescue_helper | provenance | | +| app.rb:150:17:150:35 | call to source | app.rb:235:27:235:37 | call to test_helper | provenance | | +| app.rb:150:17:150:35 | call to source | app.rb:235:27:235:37 | call to test_helper | provenance | | +| app.rb:166:9:166:15 | user_id | app.rb:173:14:173:20 | user_id | provenance | | +| app.rb:166:19:166:24 | call to params | app.rb:166:19:166:34 | ...[...] | provenance | | +| app.rb:166:19:166:34 | ...[...] | app.rb:166:9:166:15 | user_id | provenance | | +| app.rb:167:9:167:16 | route_id | app.rb:174:14:174:21 | route_id | provenance | | +| app.rb:167:20:167:40 | call to route_param | app.rb:167:9:167:16 | route_id | provenance | | +| app.rb:168:9:168:12 | auth | app.rb:175:14:175:17 | auth | provenance | | +| app.rb:168:16:168:22 | call to headers | app.rb:168:16:168:38 | ...[...] | provenance | | +| app.rb:168:16:168:38 | ...[...] | app.rb:168:9:168:12 | auth | provenance | | +| app.rb:169:9:169:15 | session | app.rb:176:14:176:20 | session | provenance | | +| app.rb:169:19:169:25 | call to cookies | app.rb:169:19:169:38 | ...[...] | provenance | | +| app.rb:169:19:169:38 | ...[...] | app.rb:169:9:169:15 | session | provenance | | +| app.rb:183:9:183:14 | result | app.rb:184:14:184:19 | result | provenance | | +| app.rb:183:9:183:14 | result | app.rb:184:14:184:19 | result | provenance | | +| app.rb:183:18:183:43 | call to vulnerable_helper | app.rb:183:9:183:14 | result | provenance | | +| app.rb:183:18:183:43 | call to vulnerable_helper | app.rb:183:9:183:14 | result | provenance | | +| app.rb:189:9:189:17 | user_data | app.rb:191:14:191:22 | user_data | provenance | | +| app.rb:189:9:189:17 | user_data : [collection] [element] | app.rb:191:14:191:22 | user_data | provenance | | +| app.rb:189:21:189:31 | call to user_params | app.rb:189:9:189:17 | user_data | provenance | | +| app.rb:189:21:189:31 | call to user_params : [collection] [element] | app.rb:189:9:189:17 | user_data : [collection] [element] | provenance | | +| app.rb:190:9:190:21 | simple_result | app.rb:192:14:192:26 | simple_result | provenance | | +| app.rb:190:9:190:21 | simple_result | app.rb:192:14:192:26 | simple_result | provenance | | +| app.rb:190:25:190:37 | call to simple_helper | app.rb:190:9:190:21 | simple_result | provenance | | +| app.rb:190:25:190:37 | call to simple_helper | app.rb:190:9:190:21 | simple_result | provenance | | +| app.rb:199:13:199:19 | user_id | app.rb:200:18:200:24 | user_id | provenance | | +| app.rb:199:23:199:28 | call to params | app.rb:199:23:199:33 | ...[...] | provenance | | +| app.rb:199:23:199:33 | ...[...] | app.rb:199:13:199:19 | user_id | provenance | | +| app.rb:205:9:205:17 | user_data | app.rb:206:14:206:22 | user_data | provenance | | +| app.rb:205:9:205:17 | user_data : [collection] [element] | app.rb:206:14:206:22 | user_data | provenance | | +| app.rb:205:21:205:31 | call to user_params | app.rb:205:9:205:17 | user_data | provenance | | +| app.rb:205:21:205:31 | call to user_params : [collection] [element] | app.rb:205:9:205:17 | user_data : [collection] [element] | provenance | | +| app.rb:212:9:212:19 | auth_result | app.rb:213:14:213:24 | auth_result | provenance | | +| app.rb:212:9:212:19 | auth_result | app.rb:213:14:213:24 | auth_result | provenance | | +| app.rb:212:23:212:39 | call to authenticate_user | app.rb:212:9:212:19 | auth_result | provenance | | +| app.rb:212:23:212:39 | call to authenticate_user | app.rb:212:9:212:19 | auth_result | provenance | | +| app.rb:216:9:216:19 | perm_result | app.rb:217:14:217:24 | perm_result | provenance | | +| app.rb:216:9:216:19 | perm_result | app.rb:217:14:217:24 | perm_result | provenance | | +| app.rb:216:23:216:48 | call to check_permissions | app.rb:216:9:216:19 | perm_result | provenance | | +| app.rb:216:23:216:48 | call to check_permissions | app.rb:216:9:216:19 | perm_result | provenance | | +| app.rb:220:9:220:25 | validation_result | app.rb:221:14:221:30 | validation_result | provenance | | +| app.rb:220:9:220:25 | validation_result | app.rb:221:14:221:30 | validation_result | provenance | | +| app.rb:220:29:220:80 | call to validate_email | app.rb:220:9:220:25 | validation_result | provenance | | +| app.rb:220:29:220:80 | call to validate_email | app.rb:220:9:220:25 | validation_result | provenance | | +| app.rb:225:13:225:24 | debug_result | app.rb:226:18:226:29 | debug_result | provenance | | +| app.rb:225:13:225:24 | debug_result | app.rb:226:18:226:29 | debug_result | provenance | | +| app.rb:225:28:225:39 | call to debug_helper | app.rb:225:13:225:24 | debug_result | provenance | | +| app.rb:225:28:225:39 | call to debug_helper | app.rb:225:13:225:24 | debug_result | provenance | | +| app.rb:230:9:230:21 | rescue_result | app.rb:231:14:231:26 | rescue_result | provenance | | +| app.rb:230:9:230:21 | rescue_result | app.rb:231:14:231:26 | rescue_result | provenance | | +| app.rb:230:25:230:37 | call to rescue_helper | app.rb:230:9:230:21 | rescue_result | provenance | | +| app.rb:230:25:230:37 | call to rescue_helper | app.rb:230:9:230:21 | rescue_result | provenance | | +| app.rb:235:13:235:23 | case_result | app.rb:236:18:236:28 | case_result | provenance | | +| app.rb:235:13:235:23 | case_result | app.rb:236:18:236:28 | case_result | provenance | | +| app.rb:235:27:235:37 | call to test_helper | app.rb:235:13:235:23 | case_result | provenance | | +| app.rb:235:27:235:37 | call to test_helper | app.rb:235:13:235:23 | case_result | provenance | | nodes | app.rb:103:13:103:18 | call to params | semmle.label | call to params | | app.rb:103:13:103:70 | call to select | semmle.label | call to select | @@ -48,58 +84,118 @@ nodes | app.rb:107:13:107:32 | call to source | semmle.label | call to source | | app.rb:111:13:111:33 | call to source | semmle.label | call to source | | app.rb:111:13:111:33 | call to source | semmle.label | call to source | -| app.rb:126:9:126:15 | user_id | semmle.label | user_id | -| app.rb:126:19:126:24 | call to params | semmle.label | call to params | -| app.rb:126:19:126:34 | ...[...] | semmle.label | ...[...] | -| app.rb:127:9:127:16 | route_id | semmle.label | route_id | -| app.rb:127:20:127:40 | call to route_param | semmle.label | call to route_param | -| app.rb:128:9:128:12 | auth | semmle.label | auth | -| app.rb:128:16:128:22 | call to headers | semmle.label | call to headers | -| app.rb:128:16:128:38 | ...[...] | semmle.label | ...[...] | -| app.rb:129:9:129:15 | session | semmle.label | session | -| app.rb:129:19:129:25 | call to cookies | semmle.label | call to cookies | -| app.rb:129:19:129:38 | ...[...] | semmle.label | ...[...] | -| app.rb:133:14:133:20 | user_id | semmle.label | user_id | -| app.rb:134:14:134:21 | route_id | semmle.label | route_id | -| app.rb:135:14:135:17 | auth | semmle.label | auth | -| app.rb:136:14:136:20 | session | semmle.label | session | -| app.rb:143:9:143:14 | result | semmle.label | result | -| app.rb:143:9:143:14 | result | semmle.label | result | -| app.rb:143:18:143:43 | call to vulnerable_helper | semmle.label | call to vulnerable_helper | -| app.rb:143:18:143:43 | call to vulnerable_helper | semmle.label | call to vulnerable_helper | -| app.rb:144:14:144:19 | result | semmle.label | result | -| app.rb:144:14:144:19 | result | semmle.label | result | -| app.rb:149:9:149:17 | user_data | semmle.label | user_data | -| app.rb:149:9:149:17 | user_data : [collection] [element] | semmle.label | user_data : [collection] [element] | -| app.rb:149:21:149:31 | call to user_params | semmle.label | call to user_params | -| app.rb:149:21:149:31 | call to user_params : [collection] [element] | semmle.label | call to user_params : [collection] [element] | -| app.rb:150:9:150:21 | simple_result | semmle.label | simple_result | -| app.rb:150:9:150:21 | simple_result | semmle.label | simple_result | -| app.rb:150:25:150:37 | call to simple_helper | semmle.label | call to simple_helper | -| app.rb:150:25:150:37 | call to simple_helper | semmle.label | call to simple_helper | -| app.rb:151:14:151:22 | user_data | semmle.label | user_data | -| app.rb:152:14:152:26 | simple_result | semmle.label | simple_result | -| app.rb:152:14:152:26 | simple_result | semmle.label | simple_result | -| app.rb:159:13:159:19 | user_id | semmle.label | user_id | -| app.rb:159:23:159:28 | call to params | semmle.label | call to params | -| app.rb:159:23:159:33 | ...[...] | semmle.label | ...[...] | -| app.rb:160:18:160:24 | user_id | semmle.label | user_id | -| app.rb:165:9:165:17 | user_data | semmle.label | user_data | -| app.rb:165:9:165:17 | user_data : [collection] [element] | semmle.label | user_data : [collection] [element] | -| app.rb:165:21:165:31 | call to user_params | semmle.label | call to user_params | -| app.rb:165:21:165:31 | call to user_params : [collection] [element] | semmle.label | call to user_params : [collection] [element] | -| app.rb:166:14:166:22 | user_data | semmle.label | user_data | +| app.rb:118:17:118:43 | call to source | semmle.label | call to source | +| app.rb:118:17:118:43 | call to source | semmle.label | call to source | +| app.rb:122:17:122:47 | call to source | semmle.label | call to source | +| app.rb:122:17:122:47 | call to source | semmle.label | call to source | +| app.rb:128:17:128:42 | call to source | semmle.label | call to source | +| app.rb:128:17:128:42 | call to source | semmle.label | call to source | +| app.rb:134:17:134:42 | call to source | semmle.label | call to source | +| app.rb:134:17:134:42 | call to source | semmle.label | call to source | +| app.rb:140:17:140:37 | call to source | semmle.label | call to source | +| app.rb:140:17:140:37 | call to source | semmle.label | call to source | +| app.rb:150:17:150:35 | call to source | semmle.label | call to source | +| app.rb:150:17:150:35 | call to source | semmle.label | call to source | +| app.rb:166:9:166:15 | user_id | semmle.label | user_id | +| app.rb:166:19:166:24 | call to params | semmle.label | call to params | +| app.rb:166:19:166:34 | ...[...] | semmle.label | ...[...] | +| app.rb:167:9:167:16 | route_id | semmle.label | route_id | +| app.rb:167:20:167:40 | call to route_param | semmle.label | call to route_param | +| app.rb:168:9:168:12 | auth | semmle.label | auth | +| app.rb:168:16:168:22 | call to headers | semmle.label | call to headers | +| app.rb:168:16:168:38 | ...[...] | semmle.label | ...[...] | +| app.rb:169:9:169:15 | session | semmle.label | session | +| app.rb:169:19:169:25 | call to cookies | semmle.label | call to cookies | +| app.rb:169:19:169:38 | ...[...] | semmle.label | ...[...] | +| app.rb:173:14:173:20 | user_id | semmle.label | user_id | +| app.rb:174:14:174:21 | route_id | semmle.label | route_id | +| app.rb:175:14:175:17 | auth | semmle.label | auth | +| app.rb:176:14:176:20 | session | semmle.label | session | +| app.rb:183:9:183:14 | result | semmle.label | result | +| app.rb:183:9:183:14 | result | semmle.label | result | +| app.rb:183:18:183:43 | call to vulnerable_helper | semmle.label | call to vulnerable_helper | +| app.rb:183:18:183:43 | call to vulnerable_helper | semmle.label | call to vulnerable_helper | +| app.rb:184:14:184:19 | result | semmle.label | result | +| app.rb:184:14:184:19 | result | semmle.label | result | +| app.rb:189:9:189:17 | user_data | semmle.label | user_data | +| app.rb:189:9:189:17 | user_data : [collection] [element] | semmle.label | user_data : [collection] [element] | +| app.rb:189:21:189:31 | call to user_params | semmle.label | call to user_params | +| app.rb:189:21:189:31 | call to user_params : [collection] [element] | semmle.label | call to user_params : [collection] [element] | +| app.rb:190:9:190:21 | simple_result | semmle.label | simple_result | +| app.rb:190:9:190:21 | simple_result | semmle.label | simple_result | +| app.rb:190:25:190:37 | call to simple_helper | semmle.label | call to simple_helper | +| app.rb:190:25:190:37 | call to simple_helper | semmle.label | call to simple_helper | +| app.rb:191:14:191:22 | user_data | semmle.label | user_data | +| app.rb:192:14:192:26 | simple_result | semmle.label | simple_result | +| app.rb:192:14:192:26 | simple_result | semmle.label | simple_result | +| app.rb:199:13:199:19 | user_id | semmle.label | user_id | +| app.rb:199:23:199:28 | call to params | semmle.label | call to params | +| app.rb:199:23:199:33 | ...[...] | semmle.label | ...[...] | +| app.rb:200:18:200:24 | user_id | semmle.label | user_id | +| app.rb:205:9:205:17 | user_data | semmle.label | user_data | +| app.rb:205:9:205:17 | user_data : [collection] [element] | semmle.label | user_data : [collection] [element] | +| app.rb:205:21:205:31 | call to user_params | semmle.label | call to user_params | +| app.rb:205:21:205:31 | call to user_params : [collection] [element] | semmle.label | call to user_params : [collection] [element] | +| app.rb:206:14:206:22 | user_data | semmle.label | user_data | +| app.rb:212:9:212:19 | auth_result | semmle.label | auth_result | +| app.rb:212:9:212:19 | auth_result | semmle.label | auth_result | +| app.rb:212:23:212:39 | call to authenticate_user | semmle.label | call to authenticate_user | +| app.rb:212:23:212:39 | call to authenticate_user | semmle.label | call to authenticate_user | +| app.rb:213:14:213:24 | auth_result | semmle.label | auth_result | +| app.rb:213:14:213:24 | auth_result | semmle.label | auth_result | +| app.rb:216:9:216:19 | perm_result | semmle.label | perm_result | +| app.rb:216:9:216:19 | perm_result | semmle.label | perm_result | +| app.rb:216:23:216:48 | call to check_permissions | semmle.label | call to check_permissions | +| app.rb:216:23:216:48 | call to check_permissions | semmle.label | call to check_permissions | +| app.rb:217:14:217:24 | perm_result | semmle.label | perm_result | +| app.rb:217:14:217:24 | perm_result | semmle.label | perm_result | +| app.rb:220:9:220:25 | validation_result | semmle.label | validation_result | +| app.rb:220:9:220:25 | validation_result | semmle.label | validation_result | +| app.rb:220:29:220:80 | call to validate_email | semmle.label | call to validate_email | +| app.rb:220:29:220:80 | call to validate_email | semmle.label | call to validate_email | +| app.rb:221:14:221:30 | validation_result | semmle.label | validation_result | +| app.rb:221:14:221:30 | validation_result | semmle.label | validation_result | +| app.rb:225:13:225:24 | debug_result | semmle.label | debug_result | +| app.rb:225:13:225:24 | debug_result | semmle.label | debug_result | +| app.rb:225:28:225:39 | call to debug_helper | semmle.label | call to debug_helper | +| app.rb:225:28:225:39 | call to debug_helper | semmle.label | call to debug_helper | +| app.rb:226:18:226:29 | debug_result | semmle.label | debug_result | +| app.rb:226:18:226:29 | debug_result | semmle.label | debug_result | +| app.rb:230:9:230:21 | rescue_result | semmle.label | rescue_result | +| app.rb:230:9:230:21 | rescue_result | semmle.label | rescue_result | +| app.rb:230:25:230:37 | call to rescue_helper | semmle.label | call to rescue_helper | +| app.rb:230:25:230:37 | call to rescue_helper | semmle.label | call to rescue_helper | +| app.rb:231:14:231:26 | rescue_result | semmle.label | rescue_result | +| app.rb:231:14:231:26 | rescue_result | semmle.label | rescue_result | +| app.rb:235:13:235:23 | case_result | semmle.label | case_result | +| app.rb:235:13:235:23 | case_result | semmle.label | case_result | +| app.rb:235:27:235:37 | call to test_helper | semmle.label | call to test_helper | +| app.rb:235:27:235:37 | call to test_helper | semmle.label | call to test_helper | +| app.rb:236:18:236:28 | case_result | semmle.label | case_result | +| app.rb:236:18:236:28 | case_result | semmle.label | case_result | subpaths testFailures #select -| app.rb:133:14:133:20 | user_id | app.rb:126:19:126:24 | call to params | app.rb:133:14:133:20 | user_id | $@ | app.rb:126:19:126:24 | call to params | call to params | -| app.rb:134:14:134:21 | route_id | app.rb:127:20:127:40 | call to route_param | app.rb:134:14:134:21 | route_id | $@ | app.rb:127:20:127:40 | call to route_param | call to route_param | -| app.rb:135:14:135:17 | auth | app.rb:128:16:128:22 | call to headers | app.rb:135:14:135:17 | auth | $@ | app.rb:128:16:128:22 | call to headers | call to headers | -| app.rb:136:14:136:20 | session | app.rb:129:19:129:25 | call to cookies | app.rb:136:14:136:20 | session | $@ | app.rb:129:19:129:25 | call to cookies | call to cookies | -| app.rb:144:14:144:19 | result | app.rb:107:13:107:32 | call to source | app.rb:144:14:144:19 | result | $@ | app.rb:107:13:107:32 | call to source | call to source | -| app.rb:144:14:144:19 | result | app.rb:107:13:107:32 | call to source | app.rb:144:14:144:19 | result | $@ | app.rb:107:13:107:32 | call to source | call to source | -| app.rb:151:14:151:22 | user_data | app.rb:103:13:103:18 | call to params | app.rb:151:14:151:22 | user_data | $@ | app.rb:103:13:103:18 | call to params | call to params | -| app.rb:152:14:152:26 | simple_result | app.rb:111:13:111:33 | call to source | app.rb:152:14:152:26 | simple_result | $@ | app.rb:111:13:111:33 | call to source | call to source | -| app.rb:152:14:152:26 | simple_result | app.rb:111:13:111:33 | call to source | app.rb:152:14:152:26 | simple_result | $@ | app.rb:111:13:111:33 | call to source | call to source | -| app.rb:160:18:160:24 | user_id | app.rb:159:23:159:28 | call to params | app.rb:160:18:160:24 | user_id | $@ | app.rb:159:23:159:28 | call to params | call to params | -| app.rb:166:14:166:22 | user_data | app.rb:103:13:103:18 | call to params | app.rb:166:14:166:22 | user_data | $@ | app.rb:103:13:103:18 | call to params | call to params | +| app.rb:173:14:173:20 | user_id | app.rb:166:19:166:24 | call to params | app.rb:173:14:173:20 | user_id | $@ | app.rb:166:19:166:24 | call to params | call to params | +| app.rb:174:14:174:21 | route_id | app.rb:167:20:167:40 | call to route_param | app.rb:174:14:174:21 | route_id | $@ | app.rb:167:20:167:40 | call to route_param | call to route_param | +| app.rb:175:14:175:17 | auth | app.rb:168:16:168:22 | call to headers | app.rb:175:14:175:17 | auth | $@ | app.rb:168:16:168:22 | call to headers | call to headers | +| app.rb:176:14:176:20 | session | app.rb:169:19:169:25 | call to cookies | app.rb:176:14:176:20 | session | $@ | app.rb:169:19:169:25 | call to cookies | call to cookies | +| app.rb:184:14:184:19 | result | app.rb:107:13:107:32 | call to source | app.rb:184:14:184:19 | result | $@ | app.rb:107:13:107:32 | call to source | call to source | +| app.rb:184:14:184:19 | result | app.rb:107:13:107:32 | call to source | app.rb:184:14:184:19 | result | $@ | app.rb:107:13:107:32 | call to source | call to source | +| app.rb:191:14:191:22 | user_data | app.rb:103:13:103:18 | call to params | app.rb:191:14:191:22 | user_data | $@ | app.rb:103:13:103:18 | call to params | call to params | +| app.rb:192:14:192:26 | simple_result | app.rb:111:13:111:33 | call to source | app.rb:192:14:192:26 | simple_result | $@ | app.rb:111:13:111:33 | call to source | call to source | +| app.rb:192:14:192:26 | simple_result | app.rb:111:13:111:33 | call to source | app.rb:192:14:192:26 | simple_result | $@ | app.rb:111:13:111:33 | call to source | call to source | +| app.rb:200:18:200:24 | user_id | app.rb:199:23:199:28 | call to params | app.rb:200:18:200:24 | user_id | $@ | app.rb:199:23:199:28 | call to params | call to params | +| app.rb:206:14:206:22 | user_data | app.rb:103:13:103:18 | call to params | app.rb:206:14:206:22 | user_data | $@ | app.rb:103:13:103:18 | call to params | call to params | +| app.rb:213:14:213:24 | auth_result | app.rb:118:17:118:43 | call to source | app.rb:213:14:213:24 | auth_result | $@ | app.rb:118:17:118:43 | call to source | call to source | +| app.rb:213:14:213:24 | auth_result | app.rb:118:17:118:43 | call to source | app.rb:213:14:213:24 | auth_result | $@ | app.rb:118:17:118:43 | call to source | call to source | +| app.rb:217:14:217:24 | perm_result | app.rb:122:17:122:47 | call to source | app.rb:217:14:217:24 | perm_result | $@ | app.rb:122:17:122:47 | call to source | call to source | +| app.rb:217:14:217:24 | perm_result | app.rb:122:17:122:47 | call to source | app.rb:217:14:217:24 | perm_result | $@ | app.rb:122:17:122:47 | call to source | call to source | +| app.rb:221:14:221:30 | validation_result | app.rb:128:17:128:42 | call to source | app.rb:221:14:221:30 | validation_result | $@ | app.rb:128:17:128:42 | call to source | call to source | +| app.rb:221:14:221:30 | validation_result | app.rb:128:17:128:42 | call to source | app.rb:221:14:221:30 | validation_result | $@ | app.rb:128:17:128:42 | call to source | call to source | +| app.rb:226:18:226:29 | debug_result | app.rb:134:17:134:42 | call to source | app.rb:226:18:226:29 | debug_result | $@ | app.rb:134:17:134:42 | call to source | call to source | +| app.rb:226:18:226:29 | debug_result | app.rb:134:17:134:42 | call to source | app.rb:226:18:226:29 | debug_result | $@ | app.rb:134:17:134:42 | call to source | call to source | +| app.rb:231:14:231:26 | rescue_result | app.rb:140:17:140:37 | call to source | app.rb:231:14:231:26 | rescue_result | $@ | app.rb:140:17:140:37 | call to source | call to source | +| app.rb:231:14:231:26 | rescue_result | app.rb:140:17:140:37 | call to source | app.rb:231:14:231:26 | rescue_result | $@ | app.rb:140:17:140:37 | call to source | call to source | +| app.rb:236:18:236:28 | case_result | app.rb:150:17:150:35 | call to source | app.rb:236:18:236:28 | case_result | $@ | app.rb:150:17:150:35 | call to source | call to source | +| app.rb:236:18:236:28 | case_result | app.rb:150:17:150:35 | call to source | app.rb:236:18:236:28 | case_result | $@ | app.rb:150:17:150:35 | call to source | call to source | diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.expected b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected index d39d9430f92..7088eeb9018 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Grape.expected +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.expected @@ -1,7 +1,7 @@ grapeApiClasses | app.rb:1:1:90:3 | MyAPI | | app.rb:92:1:96:3 | AdminAPI | -| app.rb:98:1:168:3 | UserAPI | +| app.rb:98:1:239:3 | UserAPI | grapeEndpoints | app.rb:1:1:90:3 | MyAPI | app.rb:7:3:11:5 | call to get | GET | /hello/:name | | app.rb:1:1:90:3 | MyAPI | app.rb:17:3:20:5 | call to post | POST | /messages | @@ -14,10 +14,11 @@ grapeEndpoints | app.rb:1:1:90:3 | MyAPI | app.rb:78:3:82:5 | call to get | GET | /cookie_test | | app.rb:1:1:90:3 | MyAPI | app.rb:85:3:89:5 | call to get | GET | /header_test | | app.rb:92:1:96:3 | AdminAPI | app.rb:93:3:95:5 | call to get | GET | /admin | -| app.rb:98:1:168:3 | UserAPI | app.rb:124:5:138:7 | call to get | GET | /comprehensive_test/:user_id | -| app.rb:98:1:168:3 | UserAPI | app.rb:140:5:145:7 | call to get | GET | /helper_test/:user_id | -| app.rb:98:1:168:3 | UserAPI | app.rb:147:5:153:7 | call to post | POST | /users | -| app.rb:98:1:168:3 | UserAPI | app.rb:164:5:167:7 | call to post | POST | /users | +| app.rb:98:1:239:3 | UserAPI | app.rb:164:5:178:7 | call to get | GET | /comprehensive_test/:user_id | +| app.rb:98:1:239:3 | UserAPI | app.rb:180:5:185:7 | call to get | GET | /helper_test/:user_id | +| app.rb:98:1:239:3 | UserAPI | app.rb:187:5:193:7 | call to post | POST | /users | +| app.rb:98:1:239:3 | UserAPI | app.rb:204:5:207:7 | call to post | POST | /users | +| app.rb:98:1:239:3 | UserAPI | app.rb:210:5:238:7 | call to get | GET | /nested_test/:token | grapeParams | app.rb:8:12:8:17 | call to params | | app.rb:14:3:16:5 | call to params | @@ -28,29 +29,30 @@ grapeParams | app.rb:60:12:60:17 | call to params | | app.rb:94:5:94:10 | call to params | | app.rb:103:13:103:18 | call to params | -| app.rb:126:19:126:24 | call to params | -| app.rb:142:19:142:24 | call to params | -| app.rb:159:23:159:28 | call to params | +| app.rb:117:25:117:30 | call to params | +| app.rb:166:19:166:24 | call to params | +| app.rb:182:19:182:24 | call to params | +| app.rb:199:23:199:28 | call to params | grapeHeaders | app.rb:9:18:9:24 | call to headers | | app.rb:46:5:46:11 | call to headers | | app.rb:66:3:69:5 | call to headers | | app.rb:86:12:86:18 | call to headers | | app.rb:87:14:87:20 | call to headers | -| app.rb:116:5:118:7 | call to headers | -| app.rb:128:16:128:22 | call to headers | +| app.rb:156:5:158:7 | call to headers | +| app.rb:168:16:168:22 | call to headers | grapeRequest | app.rb:25:12:25:18 | call to request | -| app.rb:130:21:130:27 | call to request | +| app.rb:170:21:170:27 | call to request | grapeRouteParam | app.rb:51:15:51:35 | call to route_param | | app.rb:52:15:52:36 | call to route_param | | app.rb:57:3:63:5 | call to route_param | -| app.rb:127:20:127:40 | call to route_param | -| app.rb:156:5:162:7 | call to route_param | +| app.rb:167:20:167:40 | call to route_param | +| app.rb:196:5:202:7 | call to route_param | grapeCookies | app.rb:72:3:75:5 | call to cookies | | app.rb:79:15:79:21 | call to cookies | | app.rb:80:16:80:22 | call to cookies | -| app.rb:120:5:122:7 | call to cookies | -| app.rb:129:19:129:25 | call to cookies | +| app.rb:160:5:162:7 | call to cookies | +| app.rb:169:19:169:25 | call to cookies | diff --git a/ruby/ql/test/library-tests/frameworks/grape/app.rb b/ruby/ql/test/library-tests/frameworks/grape/app.rb index 81f46482687..1b1fd15d5d8 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/app.rb +++ b/ruby/ql/test/library-tests/frameworks/grape/app.rb @@ -110,6 +110,46 @@ class UserAPI < Grape::API def simple_helper source "simpleHelper" # Test simple helper return end + + # Nested helper scenarios that require getParent+() + module AuthHelpers + def authenticate_user + token = params[:token] + source "nestedModuleHelper" # Test nested module helper + end + + def check_permissions(resource) + source "nestedPermissionHelper" # Test nested module helper with params + end + end + + class ValidationHelpers + def self.validate_email(email) + source "nestedClassHelper" # Test nested class helper + end + end + + if Rails.env.development? + def debug_helper + source "conditionalHelper" # Test helper inside conditional block + end + end + + begin + def rescue_helper + source "rescueHelper" # Test helper inside begin block + end + rescue + # error handling + end + + # Helper inside a case statement + case ENV['RACK_ENV'] + when 'test' + def test_helper + source "caseHelper" # Test helper inside case block + end + end end # Headers and cookies blocks for DSL testing @@ -165,4 +205,35 @@ class UserAPI < Grape::API user_data = user_params sink user_data # $ hasTaintFlow end + + # Test nested helper methods + get '/nested_test/:token' do + # Test nested module helper + auth_result = authenticate_user + sink auth_result # $ hasValueFlow=nestedModuleHelper + + # Test nested module helper with parameters + perm_result = check_permissions("admin") + sink perm_result # $ hasValueFlow=nestedPermissionHelper + + # Test nested class helper + validation_result = ValidationHelpers.validate_email("test@example.com") + sink validation_result # $ hasValueFlow=nestedClassHelper + + # Test conditional helper (if it exists) + if respond_to?(:debug_helper) + debug_result = debug_helper + sink debug_result # $ hasValueFlow=conditionalHelper + end + + # Test rescue helper + rescue_result = rescue_helper + sink rescue_result # $ hasValueFlow=rescueHelper + + # Test case helper (if it exists) + if respond_to?(:test_helper) + case_result = test_helper + sink case_result # $ hasValueFlow=caseHelper + end + end end From 6e56c549b2600540306812048ead37ed53dd37bc Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Mon, 22 Sep 2025 19:21:23 -0400 Subject: [PATCH 093/160] Refactor Grape method call classes to simplify handling of API instance calls for headers, request, route_param, and cookies --- ruby/ql/lib/codeql/ruby/frameworks/Grape.qll | 28 +++----------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll index 4d64e9461b3..9b7ae6185cd 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/Grape.qll @@ -163,12 +163,7 @@ module Grape { */ private class GrapeHeadersCall extends MethodCall { GrapeHeadersCall() { - exists(GrapeEndpoint endpoint | - this.getParent+() = endpoint.getBody().asCallableAstNode() and - this.getMethodName() = "headers" - ) - or - // Also handle cases where headers is called on an instance of a Grape API class + // Handle cases where headers is called on an instance of a Grape API class this = grapeApiInstance().getAMethodCall("headers").asExpr().getExpr() } } @@ -206,12 +201,7 @@ module Grape { */ private class GrapeRequestCall extends MethodCall { GrapeRequestCall() { - exists(GrapeEndpoint endpoint | - this.getParent+() = endpoint.getBody().asCallableAstNode() and - this.getMethodName() = "request" - ) - or - // Also handle cases where request is called on an instance of a Grape API class + // Handle cases where request is called on an instance of a Grape API class this = grapeApiInstance().getAMethodCall("request").asExpr().getExpr() } } @@ -221,12 +211,7 @@ module Grape { */ private class GrapeRouteParamCall extends MethodCall { GrapeRouteParamCall() { - exists(GrapeEndpoint endpoint | - this.getParent+() = endpoint.getBody().asExpr().getExpr() and - this.getMethodName() = "route_param" - ) - or - // Also handle cases where route_param is called on an instance of a Grape API class + // Handle cases where route_param is called on an instance of a Grape API class this = grapeApiInstance().getAMethodCall("route_param").asExpr().getExpr() } } @@ -274,12 +259,7 @@ module Grape { */ private class GrapeCookiesCall extends MethodCall { GrapeCookiesCall() { - exists(GrapeEndpoint endpoint | - this.getParent+() = endpoint.getBody().asCallableAstNode() and - this.getMethodName() = "cookies" - ) - or - // Also handle cases where cookies is called on an instance of a Grape API class + // Handle cases where cookies is called on an instance of a Grape API class this = grapeApiInstance().getAMethodCall("cookies").asExpr().getExpr() } } From 89fd9694cef692446e54e71a730abf1d427b7627 Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Mon, 22 Sep 2025 19:25:05 -0400 Subject: [PATCH 094/160] codeql query format --- ruby/ql/test/library-tests/frameworks/grape/Grape.ql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql index c5f0798f7a6..63cd15a547e 100644 --- a/ruby/ql/test/library-tests/frameworks/grape/Grape.ql +++ b/ruby/ql/test/library-tests/frameworks/grape/Grape.ql @@ -5,7 +5,9 @@ import codeql.ruby.AST query predicate grapeApiClasses(Grape::GrapeApiClass api) { any() } -query predicate grapeEndpoints(Grape::GrapeApiClass api, Grape::GrapeEndpoint endpoint, string method, string path) { +query predicate grapeEndpoints( + Grape::GrapeApiClass api, Grape::GrapeEndpoint endpoint, string method, string path +) { endpoint = api.getAnEndpoint() and method = endpoint.getHttpMethod() and path = endpoint.getPath() From 718c0abdb6fe073349de892ddbbc383b404de607 Mon Sep 17 00:00:00 2001 From: Kasper Svendsen Date: Tue, 23 Sep 2025 10:31:28 +0200 Subject: [PATCH 095/160] Overlay: Discard base config entities in overlay extracted files --- java/ql/lib/semmle/code/java/Overlay.qll | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/java/ql/lib/semmle/code/java/Overlay.qll b/java/ql/lib/semmle/code/java/Overlay.qll index 0f6033d87b3..31a1518fc59 100644 --- a/java/ql/lib/semmle/code/java/Overlay.qll +++ b/java/ql/lib/semmle/code/java/Overlay.qll @@ -88,7 +88,17 @@ private string baseConfigLocatable(@configLocatable el) { not isOverlay() and result = getRawFileForConfig(el) } +overlay[local] +private predicate overlayConfigExtracted(string file) { + isOverlay() and + exists(@configLocatable el | file = getRawFileForConfig(el)) +} + overlay[discard_entity] private predicate discardBaseConfigLocatable(@configLocatable el) { overlayChangedFiles(baseConfigLocatable(el)) + or + // The config extractor is currently not incremental and may extract more + // property files than those included in overlayChangedFiles. + overlayConfigExtracted(baseConfigLocatable(el)) } From f02da68c55b450687aab8235b725f58139169fe5 Mon Sep 17 00:00:00 2001 From: Kasper Svendsen Date: Tue, 23 Sep 2025 10:34:49 +0200 Subject: [PATCH 096/160] Overlay: Discard base XML entities in overlay extracted files --- java/ql/lib/semmle/code/java/Overlay.qll | 28 ++++++++++++++++++++++++ java/ql/lib/semmle/code/xml/XML.qll | 10 ++++----- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/java/ql/lib/semmle/code/java/Overlay.qll b/java/ql/lib/semmle/code/java/Overlay.qll index 31a1518fc59..b5f7264eb3d 100644 --- a/java/ql/lib/semmle/code/java/Overlay.qll +++ b/java/ql/lib/semmle/code/java/Overlay.qll @@ -102,3 +102,31 @@ private predicate discardBaseConfigLocatable(@configLocatable el) { // property files than those included in overlayChangedFiles. overlayConfigExtracted(baseConfigLocatable(el)) } + +/** + * An `@xmllocatable` that should be discarded in the base variant if its file is + * extracted in the overlay variant. + */ +overlay[local] +abstract class DiscardableXmlLocatable extends @xmllocatable { + /** Gets the raw file for an xmllocatable in base. */ + string getRawFileInBase() { not isOverlay() and result = getRawFile(this) } + + /** Gets a textual representation of this discardable xmllocatable. */ + string toString() { none() } +} + +overlay[local] +private predicate overlayXmlExtracted(string file) { + isOverlay() and + exists(@xmllocatable el | not files(el, _) and not xmlNs(el, _, _, _) and file = getRawFile(el)) +} + +overlay[discard_entity] +private predicate discardXmlLocatable(@xmllocatable el) { + overlayChangedFiles(el.(DiscardableXmlLocatable).getRawFileInBase()) + or + // The XML extractor is currently not incremental and may extract more + // XML files than those included in overlayChangedFiles. + overlayXmlExtracted(el.(DiscardableXmlLocatable).getRawFileInBase()) +} diff --git a/java/ql/lib/semmle/code/xml/XML.qll b/java/ql/lib/semmle/code/xml/XML.qll index cd00991eb65..d13a83e7798 100644 --- a/java/ql/lib/semmle/code/xml/XML.qll +++ b/java/ql/lib/semmle/code/xml/XML.qll @@ -71,12 +71,12 @@ private module Input implements InputSig { import Make -private class DiscardableXmlAttribute extends DiscardableLocatable, @xmlattribute { } +private class DiscardableXmlAttribute extends DiscardableXmlLocatable, @xmlattribute { } -private class DiscardableXmlElement extends DiscardableLocatable, @xmlelement { } +private class DiscardableXmlElement extends DiscardableXmlLocatable, @xmlelement { } -private class DiscardableXmlComment extends DiscardableLocatable, @xmlcomment { } +private class DiscardableXmlComment extends DiscardableXmlLocatable, @xmlcomment { } -private class DiscardableXmlCharacters extends DiscardableLocatable, @xmlcharacters { } +private class DiscardableXmlCharacters extends DiscardableXmlLocatable, @xmlcharacters { } -private class DiscardableXmlDtd extends DiscardableLocatable, @xmldtd { } +private class DiscardableXmlDtd extends DiscardableXmlLocatable, @xmldtd { } From 37e0c3084278fd5a326b7021eaf73b08d1be801f Mon Sep 17 00:00:00 2001 From: Chad Bentz <1760475+felickz@users.noreply.github.com> Date: Tue, 23 Sep 2025 10:40:30 -0400 Subject: [PATCH 097/160] Add expected output for VariablesConsistency test case --- .../grape/CONSISTENCY/VariablesConsistency.expected | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ruby/ql/test/library-tests/frameworks/grape/CONSISTENCY/VariablesConsistency.expected diff --git a/ruby/ql/test/library-tests/frameworks/grape/CONSISTENCY/VariablesConsistency.expected b/ruby/ql/test/library-tests/frameworks/grape/CONSISTENCY/VariablesConsistency.expected new file mode 100644 index 00000000000..edcc754b792 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/grape/CONSISTENCY/VariablesConsistency.expected @@ -0,0 +1,4 @@ +variableIsCaptured +| app.rb:126:9:130:11 | self | CapturedVariable is not captured | +consistencyOverview +| CapturedVariable is not captured | 1 | From e6b1e8ec561059d45b828e89e5c09e3f1274f63e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 22 Sep 2025 14:35:27 +0200 Subject: [PATCH 098/160] Rust: Check call arities in path resolution --- .../internal/ControlFlowGraphImpl.qll | 2 +- .../rust/elements/internal/CallImpl.qll | 2 +- .../rust/elements/internal/CallableImpl.qll | 10 ++++ .../rust/elements/internal/VariableImpl.qll | 2 +- .../codeql/rust/internal/PathResolution.qll | 40 +++++++++++-- .../codeql/rust/internal/TypeInference.qll | 12 ++-- .../PathResolutionConsistency.expected | 5 -- .../PathResolutionConsistency.expected | 10 ---- .../HardcodedCryptographicValue.expected | 59 +++++++------------ 9 files changed, 75 insertions(+), 67 deletions(-) delete mode 100644 rust/ql/test/query-tests/security/CWE-798/CONSISTENCY/PathResolutionConsistency.expected diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index ddc4dae9b95..f87daaaf51a 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -77,7 +77,7 @@ class CallableScopeTree extends StandardTree, PreOrderTree, PostOrderTree, Scope override AstNode getChildNode(int i) { i = 0 and - result = this.getParamList().getSelfParam() + result = this.getSelfParam() or result = this.getParam(i - 1) or diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll index 020b50594a6..210820fd105 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallImpl.qll @@ -102,7 +102,7 @@ module Impl { f = resolvePath(path) and path.getSegment().getIdentifier().getText() = methodName and exists(SelfParam self | - self = f.getParamList().getSelfParam() and + self = f.getSelfParam() and if self.isRef() then selfIsRef = true else selfIsRef = false ) ) diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallableImpl.qll index 37e24a9150c..46489cab981 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallableImpl.qll @@ -17,5 +17,15 @@ module Impl { */ class Callable extends Generated::Callable { override Param getParam(int index) { result = this.getParamList().getParam(index) } + + /** + * Gets the self parameter of this callable, if it exists. + */ + SelfParam getSelfParam() { result = this.getParamList().getSelfParam() } + + /** + * Holds if `getSelfParam()` exists. + */ + predicate hasSelfParam() { exists(this.getSelfParam()) } } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll index eaced654b01..80569281721 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/VariableImpl.qll @@ -109,7 +109,7 @@ module Impl { text = name.getText() and // exclude self parameters from functions without a body as these are // trait method declarations without implementations - not exists(Function f | not f.hasBody() and f.getParamList().getSelfParam() = sp) + not exists(Function f | not f.hasBody() and f.getSelfParam() = sp) ) or exists(IdentPat pat | diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index efd614db63a..4b368308878 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -4,6 +4,7 @@ private import rust private import codeql.rust.elements.internal.generated.ParentChild +private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl private import codeql.rust.internal.CachedStages private import codeql.rust.frameworks.stdlib.Builtins as Builtins private import codeql.util.Option @@ -604,7 +605,13 @@ private class EnumItemNode extends TypeItemNode instanceof Enum { } } -private class VariantItemNode extends ItemNode instanceof Variant { +/** An item that can be called with arguments. */ +abstract class CallableItemNode extends ItemNode { + /** Gets the number of parameters of this item. */ + abstract int getNumberOfParameters(); +} + +private class VariantItemNode extends CallableItemNode instanceof Variant { override string getName() { result = Variant.super.getName().getText() } override Namespace getNamespace() { @@ -617,6 +624,10 @@ private class VariantItemNode extends ItemNode instanceof Variant { override Visibility getVisibility() { result = super.getEnum().getVisibility() } + override int getNumberOfParameters() { + result = super.getFieldList().(TupleFieldList).getNumberOfFields() + } + override predicate hasCanonicalPath(Crate c) { this.hasCanonicalPathPrefix(c) } bindingset[c] @@ -638,7 +649,7 @@ private class VariantItemNode extends ItemNode instanceof Variant { } } -class FunctionItemNode extends AssocItemNode instanceof Function { +class FunctionItemNode extends AssocItemNode, CallableItemNode instanceof Function { override string getName() { result = Function.super.getName().getText() } override predicate hasImplementation() { Function.super.hasImplementation() } @@ -648,6 +659,13 @@ class FunctionItemNode extends AssocItemNode instanceof Function { override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) } override Visibility getVisibility() { result = Function.super.getVisibility() } + + override int getNumberOfParameters() { + exists(int arr | + arr = super.getNumberOfParams() and + if super.hasSelfParam() then result = arr + 1 else result = arr + ) + } } abstract class ImplOrTraitItemNode extends ItemNode { @@ -712,8 +730,10 @@ final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl { TypeParamItemNode getBlanketImplementationTypeParam() { result = this.resolveSelfTy() } /** - * Holds if this impl block is a blanket implementation. That is, the + * Holds if this impl block is a [blanket implementation][1]. That is, the * implementation targets a generic parameter of the impl block. + * + * [1]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods */ predicate isBlanketImplementation() { exists(this.getBlanketImplementationTypeParam()) } @@ -865,7 +885,7 @@ private class ImplItemNodeImpl extends ImplItemNode { TraitItemNode resolveTraitTyCand() { result = resolvePathCand(this.getTraitPath()) } } -private class StructItemNode extends TypeItemNode instanceof Struct { +private class StructItemNode extends TypeItemNode, CallableItemNode instanceof Struct { override string getName() { result = Struct.super.getName().getText() } override Namespace getNamespace() { @@ -877,6 +897,10 @@ private class StructItemNode extends TypeItemNode instanceof Struct { override Visibility getVisibility() { result = Struct.super.getVisibility() } + override int getNumberOfParameters() { + result = super.getFieldList().(TupleFieldList).getNumberOfFields() + } + override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) } override predicate hasCanonicalPath(Crate c) { this.hasCanonicalPathPrefix(c) } @@ -1687,6 +1711,14 @@ private ItemNode resolvePathCand(RelevantPath path) { or not pathUsesNamespace(path, _) and not path = any(MacroCall mc).getPath() + ) and + ( + not path = CallExprImpl::getFunctionPath(_) + or + exists(CallExpr ce | + path = CallExprImpl::getFunctionPath(ce) and + result.(CallableItemNode).getNumberOfParameters() = ce.getNumberOfArgs() + ) ) } diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index 16c0b30332e..48281bd4846 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -230,7 +230,7 @@ module Consistency { // Suppress the inconsistency if `n` is a self parameter and the type // mention for the self type has multiple types for a path. not exists(ImplItemNode impl, TypePath selfTypePath | - n = impl.getAnAssocItem().(Function).getParamList().getSelfParam() and + n = impl.getAnAssocItem().(Function).getSelfParam() and strictcount(impl.(Impl).getSelfTy().(TypeMention).resolveTypeAt(selfTypePath)) > 1 ) } @@ -948,7 +948,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig { ) or exists(SelfParam self | - self = pragma[only_bind_into](this.getParamList().getSelfParam()) and + self = pragma[only_bind_into](this.getSelfParam()) and dpos.isSelf() and result = inferAnnotatedType(self, path) // `self` parameter with type annotation ) @@ -972,7 +972,7 @@ private module CallExprBaseMatchingInput implements MatchingInputSig { exists(ImplOrTraitItemNode i | this = i.getAnAssocItem() and dpos.isSelf() and - not this.getParamList().hasSelfParam() + not this.hasSelfParam() | result = TSelfTypeParameter(i) and path.isEmpty() @@ -1900,7 +1900,7 @@ private predicate methodCandidate(Type type, string name, int arity, Impl impl) type = impl.getSelfTy().(TypeMention).resolveType() and exists(Function f | f = impl.(ImplItemNode).getASuccessor(name) and - f.getParamList().hasSelfParam() and + f.hasSelfParam() and arity = f.getParamList().getNumberOfParams() ) } @@ -2222,7 +2222,7 @@ private module BlanketImplementation { ) { isCanonicalImpl(impl) and blanketImplementationTraitBound(impl, traitBound) and - f.getParamList().hasSelfParam() and + f.hasSelfParam() and arity = f.getParamList().getNumberOfParams() and ( f = impl.getAssocItem(name) @@ -2332,7 +2332,7 @@ private Function resolveMethodCallTarget(MethodCall mc) { pragma[nomagic] private predicate assocFuncResolutionDependsOnArgument(Function f, Impl impl, int pos) { functionResolutionDependsOnArgument(impl, _, f, pos, _, _) and - not f.getParamList().hasSelfParam() + not f.hasSelfParam() } private class FunctionCallExpr extends CallImpl::CallExprCall { diff --git a/rust/ql/test/query-tests/security/CWE-327/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/query-tests/security/CWE-327/CONSISTENCY/PathResolutionConsistency.expected index 50dd9e9f0ed..b9925a323cc 100644 --- a/rust/ql/test/query-tests/security/CWE-327/CONSISTENCY/PathResolutionConsistency.expected +++ b/rust/ql/test/query-tests/security/CWE-327/CONSISTENCY/PathResolutionConsistency.expected @@ -1,7 +1,2 @@ multipleCallTargets -| test_cipher.rs:20:27:20:48 | ...::new(...) | -| test_cipher.rs:26:27:26:48 | ...::new(...) | -| test_cipher.rs:29:27:29:48 | ...::new(...) | -| test_cipher.rs:36:30:36:59 | ...::new(...) | -| test_cipher.rs:39:30:39:63 | ...::new(...) | | test_cipher.rs:114:23:114:50 | ...::new(...) | diff --git a/rust/ql/test/query-tests/security/CWE-798/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/query-tests/security/CWE-798/CONSISTENCY/PathResolutionConsistency.expected deleted file mode 100644 index b0ca6300065..00000000000 --- a/rust/ql/test/query-tests/security/CWE-798/CONSISTENCY/PathResolutionConsistency.expected +++ /dev/null @@ -1,10 +0,0 @@ -multipleCallTargets -| test_cipher.rs:15:30:15:77 | ...::new(...) | -| test_cipher.rs:19:30:19:80 | ...::new(...) | -| test_cipher.rs:22:30:22:98 | ...::new(...) | -| test_cipher.rs:26:30:26:101 | ...::new(...) | -| test_cipher.rs:30:30:30:102 | ...::new(...) | -| test_cipher.rs:38:30:38:81 | ...::new(...) | -| test_cipher.rs:42:30:42:80 | ...::new(...) | -| test_cipher.rs:47:30:47:85 | ...::new(...) | -| test_cipher.rs:51:31:51:83 | ...::new(...) | diff --git a/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected b/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected index d16be723b8f..3b52014e1fc 100644 --- a/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected +++ b/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected @@ -1,15 +1,9 @@ #select | test_cipher.rs:18:30:18:32 | 0u8 | test_cipher.rs:18:30:18:32 | 0u8 | test_cipher.rs:19:30:19:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:19:30:19:47 | ...::new | a key | -| test_cipher.rs:18:30:18:32 | 0u8 | test_cipher.rs:18:30:18:32 | 0u8 | test_cipher.rs:19:30:19:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:19:30:19:47 | ...::new | a key | -| test_cipher.rs:25:30:25:32 | 0u8 | test_cipher.rs:25:30:25:32 | 0u8 | test_cipher.rs:26:30:26:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:26:30:26:40 | ...::new | a key | | test_cipher.rs:25:30:25:32 | 0u8 | test_cipher.rs:25:30:25:32 | 0u8 | test_cipher.rs:26:30:26:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:26:30:26:40 | ...::new | a key | | test_cipher.rs:29:30:29:32 | 0u8 | test_cipher.rs:29:30:29:32 | 0u8 | test_cipher.rs:30:30:30:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:30:30:30:40 | ...::new | an initialization vector | -| test_cipher.rs:29:30:29:32 | 0u8 | test_cipher.rs:29:30:29:32 | 0u8 | test_cipher.rs:30:30:30:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:30:30:30:40 | ...::new | an initialization vector | -| test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:38:30:38:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:38:30:38:47 | ...::new | a key | | test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:38:30:38:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:38:30:38:47 | ...::new | a key | | test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:42:30:42:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:42:30:42:47 | ...::new | a key | -| test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:42:30:42:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:42:30:42:47 | ...::new | a key | -| test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:51:31:51:48 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:51:31:51:48 | ...::new | a key | | test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:51:31:51:48 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:51:31:51:48 | ...::new | a key | | test_cipher.rs:73:20:73:22 | 0u8 | test_cipher.rs:73:20:73:22 | 0u8 | test_cipher.rs:74:23:74:44 | ...::new_from_slice | This hard-coded value is used as $@. | test_cipher.rs:74:23:74:44 | ...::new_from_slice | a key | | test_cookie.rs:17:29:17:29 | 0 | test_cookie.rs:17:29:17:29 | 0 | test_cookie.rs:18:16:18:24 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:18:16:18:24 | ...::from | a key | @@ -22,40 +16,34 @@ edges | test_cipher.rs:18:29:18:36 | [0u8; 16] [element] | test_cipher.rs:18:28:18:36 | &... [&ref, element] | provenance | | | test_cipher.rs:18:30:18:32 | 0u8 | test_cipher.rs:18:29:18:36 | [0u8; 16] [element] | provenance | | | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | test_cipher.rs:19:30:19:47 | ...::new | provenance | MaD:3 Sink:MaD:3 Sink:MaD:3 | -| test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | test_cipher.rs:19:30:19:47 | ...::new | provenance | MaD:5 Sink:MaD:5 Sink:MaD:5 | -| test_cipher.rs:19:73:19:78 | const1 [&ref, element] | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | provenance | MaD:10 | +| test_cipher.rs:19:73:19:78 | const1 [&ref, element] | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | | test_cipher.rs:25:9:25:14 | const4 [&ref, element] | test_cipher.rs:26:66:26:71 | const4 [&ref, element] | provenance | | | test_cipher.rs:25:28:25:36 | &... [&ref, element] | test_cipher.rs:25:9:25:14 | const4 [&ref, element] | provenance | | | test_cipher.rs:25:29:25:36 | [0u8; 16] [element] | test_cipher.rs:25:28:25:36 | &... [&ref, element] | provenance | | | test_cipher.rs:25:30:25:32 | 0u8 | test_cipher.rs:25:29:25:36 | [0u8; 16] [element] | provenance | | -| test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | test_cipher.rs:26:30:26:40 | ...::new | provenance | MaD:3 Sink:MaD:3 Sink:MaD:3 | -| test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | test_cipher.rs:26:30:26:40 | ...::new | provenance | MaD:5 Sink:MaD:5 Sink:MaD:5 | -| test_cipher.rs:26:66:26:71 | const4 [&ref, element] | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | provenance | MaD:10 | +| test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | test_cipher.rs:26:30:26:40 | ...::new | provenance | MaD:4 Sink:MaD:4 Sink:MaD:4 | +| test_cipher.rs:26:66:26:71 | const4 [&ref, element] | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | | test_cipher.rs:29:9:29:14 | const5 [&ref, element] | test_cipher.rs:30:95:30:100 | const5 [&ref, element] | provenance | | | test_cipher.rs:29:28:29:36 | &... [&ref, element] | test_cipher.rs:29:9:29:14 | const5 [&ref, element] | provenance | | | test_cipher.rs:29:29:29:36 | [0u8; 16] [element] | test_cipher.rs:29:28:29:36 | &... [&ref, element] | provenance | | | test_cipher.rs:29:30:29:32 | 0u8 | test_cipher.rs:29:29:29:36 | [0u8; 16] [element] | provenance | | -| test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | test_cipher.rs:30:30:30:40 | ...::new | provenance | MaD:4 Sink:MaD:4 Sink:MaD:4 | -| test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | test_cipher.rs:30:30:30:40 | ...::new | provenance | MaD:6 Sink:MaD:6 Sink:MaD:6 | -| test_cipher.rs:30:95:30:100 | const5 [&ref, element] | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | provenance | MaD:10 | +| test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | test_cipher.rs:30:30:30:40 | ...::new | provenance | MaD:5 Sink:MaD:5 Sink:MaD:5 | +| test_cipher.rs:30:95:30:100 | const5 [&ref, element] | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | | test_cipher.rs:37:9:37:14 | const7 | test_cipher.rs:38:74:38:79 | const7 | provenance | | | test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:37:9:37:14 | const7 | provenance | | | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | test_cipher.rs:38:30:38:47 | ...::new | provenance | MaD:3 Sink:MaD:3 | -| test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | test_cipher.rs:38:30:38:47 | ...::new | provenance | MaD:5 Sink:MaD:5 | -| test_cipher.rs:38:73:38:79 | &const7 [&ref] | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | provenance | MaD:10 | +| test_cipher.rs:38:73:38:79 | &const7 [&ref] | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | provenance | MaD:9 | | test_cipher.rs:38:74:38:79 | const7 | test_cipher.rs:38:73:38:79 | &const7 [&ref] | provenance | | | test_cipher.rs:41:9:41:14 | const8 [&ref] | test_cipher.rs:42:73:42:78 | const8 [&ref] | provenance | | | test_cipher.rs:41:28:41:76 | &... [&ref] | test_cipher.rs:41:9:41:14 | const8 [&ref] | provenance | | | test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:41:28:41:76 | &... [&ref] | provenance | | | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | test_cipher.rs:42:30:42:47 | ...::new | provenance | MaD:3 Sink:MaD:3 | -| test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | test_cipher.rs:42:30:42:47 | ...::new | provenance | MaD:5 Sink:MaD:5 | -| test_cipher.rs:42:73:42:78 | const8 [&ref] | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | provenance | MaD:10 | +| test_cipher.rs:42:73:42:78 | const8 [&ref] | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | provenance | MaD:9 | | test_cipher.rs:50:9:50:15 | const10 [element] | test_cipher.rs:51:75:51:81 | const10 [element] | provenance | | -| test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:50:37:50:54 | ...::zeroed(...) [element] | provenance | Src:MaD:8 | +| test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:50:37:50:54 | ...::zeroed(...) [element] | provenance | Src:MaD:7 | | test_cipher.rs:50:37:50:54 | ...::zeroed(...) [element] | test_cipher.rs:50:9:50:15 | const10 [element] | provenance | | | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | test_cipher.rs:51:31:51:48 | ...::new | provenance | MaD:3 Sink:MaD:3 Sink:MaD:3 | -| test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | test_cipher.rs:51:31:51:48 | ...::new | provenance | MaD:5 Sink:MaD:5 Sink:MaD:5 | -| test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | provenance | MaD:10 | +| test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | | test_cipher.rs:51:75:51:81 | const10 [element] | test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | provenance | | | test_cipher.rs:73:9:73:14 | const2 [&ref, element] | test_cipher.rs:74:46:74:51 | const2 [&ref, element] | provenance | | | test_cipher.rs:73:18:73:26 | &... [&ref, element] | test_cipher.rs:73:9:73:14 | const2 [&ref, element] | provenance | | @@ -65,41 +53,39 @@ edges | test_cookie.rs:17:9:17:14 | array1 [element] | test_cookie.rs:18:27:18:32 | array1 [element] | provenance | | | test_cookie.rs:17:28:17:34 | [0; 64] [element] | test_cookie.rs:17:9:17:14 | array1 [element] | provenance | | | test_cookie.rs:17:29:17:29 | 0 | test_cookie.rs:17:28:17:34 | [0; 64] [element] | provenance | | -| test_cookie.rs:18:26:18:32 | &array1 [&ref, element] | test_cookie.rs:18:16:18:24 | ...::from | provenance | MaD:7 Sink:MaD:7 | +| test_cookie.rs:18:26:18:32 | &array1 [&ref, element] | test_cookie.rs:18:16:18:24 | ...::from | provenance | MaD:6 Sink:MaD:6 | | test_cookie.rs:18:27:18:32 | array1 [element] | test_cookie.rs:18:26:18:32 | &array1 [&ref, element] | provenance | | | test_cookie.rs:21:9:21:14 | array2 [element] | test_cookie.rs:22:27:22:32 | array2 [element] | provenance | | | test_cookie.rs:21:28:21:34 | [0; 64] [element] | test_cookie.rs:21:9:21:14 | array2 [element] | provenance | | | test_cookie.rs:21:29:21:29 | 0 | test_cookie.rs:21:28:21:34 | [0; 64] [element] | provenance | | -| test_cookie.rs:22:26:22:32 | &array2 [&ref, element] | test_cookie.rs:22:16:22:24 | ...::from | provenance | MaD:7 Sink:MaD:7 | +| test_cookie.rs:22:26:22:32 | &array2 [&ref, element] | test_cookie.rs:22:16:22:24 | ...::from | provenance | MaD:6 Sink:MaD:6 | | test_cookie.rs:22:27:22:32 | array2 [element] | test_cookie.rs:22:26:22:32 | &array2 [&ref, element] | provenance | | | test_cookie.rs:38:9:38:14 | array2 [element] | test_cookie.rs:42:34:42:39 | array2 [element] | provenance | | | test_cookie.rs:38:18:38:37 | ...::from(...) [element] | test_cookie.rs:38:9:38:14 | array2 [element] | provenance | | -| test_cookie.rs:38:28:38:36 | [0u8; 64] [element] | test_cookie.rs:38:18:38:37 | ...::from(...) [element] | provenance | MaD:9 | +| test_cookie.rs:38:28:38:36 | [0u8; 64] [element] | test_cookie.rs:38:18:38:37 | ...::from(...) [element] | provenance | MaD:8 | | test_cookie.rs:38:29:38:31 | 0u8 | test_cookie.rs:38:28:38:36 | [0u8; 64] [element] | provenance | | | test_cookie.rs:42:34:42:39 | array2 [element] | test_cookie.rs:42:14:42:32 | ...::from | provenance | MaD:2 Sink:MaD:2 | | test_cookie.rs:49:9:49:14 | array3 [element] | test_cookie.rs:53:34:53:39 | array3 [element] | provenance | | -| test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | provenance | MaD:11 | +| test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | provenance | MaD:10 | | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | test_cookie.rs:49:9:49:14 | array3 [element] | provenance | | | test_cookie.rs:53:34:53:39 | array3 [element] | test_cookie.rs:53:14:53:32 | ...::from | provenance | MaD:2 Sink:MaD:2 | models | 1 | Sink: <_ as crypto_common::KeyInit>::new_from_slice; Argument[0]; credentials-key | | 2 | Sink: ::from; Argument[0]; credentials-key | | 3 | Sink: ::new; Argument[0]; credentials-key | -| 4 | Sink: ::new; Argument[1]; credentials-iv | -| 5 | Sink: ::new; Argument[0]; credentials-key | -| 6 | Sink: ::new; Argument[1]; credentials-iv | -| 7 | Sink: ::from; Argument[0].Reference; credentials-key | -| 8 | Source: core::mem::zeroed; ReturnValue.Element; constant-source | -| 9 | Summary: <_ as core::convert::From>::from; Argument[0]; ReturnValue; value | -| 10 | Summary: ::from_slice; Argument[0].Reference; ReturnValue.Reference; value | -| 11 | Summary: alloc::vec::from_elem; Argument[0]; ReturnValue.Element; value | +| 4 | Sink: ::new; Argument[0]; credentials-key | +| 5 | Sink: ::new; Argument[1]; credentials-iv | +| 6 | Sink: ::from; Argument[0].Reference; credentials-key | +| 7 | Source: core::mem::zeroed; ReturnValue.Element; constant-source | +| 8 | Summary: <_ as core::convert::From>::from; Argument[0]; ReturnValue; value | +| 9 | Summary: ::from_slice; Argument[0].Reference; ReturnValue.Reference; value | +| 10 | Summary: alloc::vec::from_elem; Argument[0]; ReturnValue.Element; value | nodes | test_cipher.rs:18:9:18:14 | const1 [&ref, element] | semmle.label | const1 [&ref, element] | | test_cipher.rs:18:28:18:36 | &... [&ref, element] | semmle.label | &... [&ref, element] | | test_cipher.rs:18:29:18:36 | [0u8; 16] [element] | semmle.label | [0u8; 16] [element] | | test_cipher.rs:18:30:18:32 | 0u8 | semmle.label | 0u8 | | test_cipher.rs:19:30:19:47 | ...::new | semmle.label | ...::new | -| test_cipher.rs:19:30:19:47 | ...::new | semmle.label | ...::new | | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | semmle.label | ...::from_slice(...) [&ref, element] | | test_cipher.rs:19:73:19:78 | const1 [&ref, element] | semmle.label | const1 [&ref, element] | | test_cipher.rs:25:9:25:14 | const4 [&ref, element] | semmle.label | const4 [&ref, element] | @@ -107,7 +93,6 @@ nodes | test_cipher.rs:25:29:25:36 | [0u8; 16] [element] | semmle.label | [0u8; 16] [element] | | test_cipher.rs:25:30:25:32 | 0u8 | semmle.label | 0u8 | | test_cipher.rs:26:30:26:40 | ...::new | semmle.label | ...::new | -| test_cipher.rs:26:30:26:40 | ...::new | semmle.label | ...::new | | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | semmle.label | ...::from_slice(...) [&ref, element] | | test_cipher.rs:26:66:26:71 | const4 [&ref, element] | semmle.label | const4 [&ref, element] | | test_cipher.rs:29:9:29:14 | const5 [&ref, element] | semmle.label | const5 [&ref, element] | @@ -115,13 +100,11 @@ nodes | test_cipher.rs:29:29:29:36 | [0u8; 16] [element] | semmle.label | [0u8; 16] [element] | | test_cipher.rs:29:30:29:32 | 0u8 | semmle.label | 0u8 | | test_cipher.rs:30:30:30:40 | ...::new | semmle.label | ...::new | -| test_cipher.rs:30:30:30:40 | ...::new | semmle.label | ...::new | | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | semmle.label | ...::from_slice(...) [&ref, element] | | test_cipher.rs:30:95:30:100 | const5 [&ref, element] | semmle.label | const5 [&ref, element] | | test_cipher.rs:37:9:37:14 | const7 | semmle.label | const7 | | test_cipher.rs:37:27:37:74 | [...] | semmle.label | [...] | | test_cipher.rs:38:30:38:47 | ...::new | semmle.label | ...::new | -| test_cipher.rs:38:30:38:47 | ...::new | semmle.label | ...::new | | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | semmle.label | ...::from_slice(...) [&ref] | | test_cipher.rs:38:73:38:79 | &const7 [&ref] | semmle.label | &const7 [&ref] | | test_cipher.rs:38:74:38:79 | const7 | semmle.label | const7 | @@ -129,14 +112,12 @@ nodes | test_cipher.rs:41:28:41:76 | &... [&ref] | semmle.label | &... [&ref] | | test_cipher.rs:41:29:41:76 | [...] | semmle.label | [...] | | test_cipher.rs:42:30:42:47 | ...::new | semmle.label | ...::new | -| test_cipher.rs:42:30:42:47 | ...::new | semmle.label | ...::new | | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | semmle.label | ...::from_slice(...) [&ref] | | test_cipher.rs:42:73:42:78 | const8 [&ref] | semmle.label | const8 [&ref] | | test_cipher.rs:50:9:50:15 | const10 [element] | semmle.label | const10 [element] | | test_cipher.rs:50:37:50:52 | ...::zeroed | semmle.label | ...::zeroed | | test_cipher.rs:50:37:50:54 | ...::zeroed(...) [element] | semmle.label | ...::zeroed(...) [element] | | test_cipher.rs:51:31:51:48 | ...::new | semmle.label | ...::new | -| test_cipher.rs:51:31:51:48 | ...::new | semmle.label | ...::new | | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | semmle.label | ...::from_slice(...) [&ref, element] | | test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | semmle.label | &const10 [&ref, element] | | test_cipher.rs:51:75:51:81 | const10 [element] | semmle.label | const10 [element] | From 6e0ce9a88557150e68e504bcbc3b958079a9908c Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Wed, 24 Sep 2025 13:30:11 +0100 Subject: [PATCH 099/160] Add changelog entry for CodeQL 2.23.1 release --- .../codeql-changelog/codeql-cli-2.23.1.rst | 176 ++++++++++++++++++ .../codeql-changelog/index.rst | 1 + 2 files changed, 177 insertions(+) create mode 100644 docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst new file mode 100644 index 00000000000..3b70843b651 --- /dev/null +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst @@ -0,0 +1,176 @@ +.. _codeql-cli-2.23.1: + +========================== +CodeQL 2.23.1 (2025-09-23) +========================== + +.. contents:: Contents + :depth: 2 + :local: + :backlinks: none + +This is an overview of changes in the CodeQL CLI and relevant CodeQL query and library packs. For additional updates on changes to the CodeQL code scanning experience, check out the `code scanning section on the GitHub blog `__, `relevant GitHub Changelog updates `__, `changes in the CodeQL extension for Visual Studio Code `__, and the `CodeQL Action changelog `__. + +Security Coverage +----------------- + +CodeQL 2.23.1 runs a total of 478 security queries when configured with the Default suite (covering 166 CWE). The Extended suite enables an additional 135 queries (covering 35 more CWE). 3 security queries have been added with this release. + +CodeQL CLI +---------- + +New Features +~~~~~~~~~~~~ + +* CodeQL now adds the sources and sinks of path alerts to the :code:`relatedLocations` property of SARIF results if they are not included as the primary location or within the alert message. This means that path alerts will show on PRs if a source or sink is added or modified, even for queries that don't follow the common convention of selecting the sink as the primary location and mentioning the source in the alert message. + +* CodeQL now populates file coverage information for GitHub Actions on + \ `the tool status page for code scanning `__. + +Query Packs +----------- + +Bug Fixes +~~~~~~~~~ + +C/C++ +""""" + +* The predicate :code:`occurenceCount` in the file module :code:`MagicConstants` has been deprecated. Use :code:`occurrenceCount` instead. +* The predicate :code:`additionalAdditionOrSubstractionCheckForLeapYear` in the file module :code:`LeapYear` has been deprecated. Use :code:`additionalAdditionOrSubtractionCheckForLeapYear` instead. + +C# +"" + +* The message for :code:`csharp/diagnostic/database-quality` has been updated to include detailed database health metrics. Additionally, the threshold for reporting database health issues has been lowered from 95% to 85% (if any metric falls below this percentage). These changes are visible on the tool status page. + +Java/Kotlin +""""""""""" + +* The message for :code:`java/diagnostic/database-quality` has been updated to include detailed database health metrics. Additionally, the threshold for reporting database health issues has been lowered from 95% to 85% (if any metric falls below this percentage). These changes are visible on the tool status page. + +Rust +"""" + +* The message for :code:`rust/diagnostic/database-quality` has been updated to include detailed database health metrics. These changes are visible on the tool status page. + +Major Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C/C++ +""""" + +* The queries :code:`cpp/wrong-type-format-argument`, :code:`cpp/comparison-with-wider-type`, :code:`cpp/integer-multiplication-cast-to-long`, :code:`cpp/implicit-function-declaration` and :code:`cpp/suspicious-add-sizeof` have had their precisions reduced from :code:`high` to :code:`medium`. They will also now give alerts for projects built with :code:`build-mode: none`. +* The queries :code:`cpp/wrong-type-format-argument`, :code:`cpp/comparison-with-wider-type`, :code:`cpp/integer-multiplication-cast-to-long` and :code:`cpp/suspicious-add-sizeof` are no longer included in the :code:`code-scanning` suite. + +Java/Kotlin +""""""""""" + +* The implementation of :code:`java/dereferenced-value-may-be-null` has been completely replaced with a new general control-flow reachability library. This improves precision by reducing false positives. However, since the entire calculation has been reworked, there can be small corner cases where precision regressions might occur and new false positives may occur, but these cases should be rare. + +JavaScript/TypeScript +""""""""""""""""""""" + +* Added support for TypeScript 5.9 +* Added support for :code:`import defer` syntax in JavaScript and TypeScript. + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +C# +"" + +* The query :code:`cs/call-to-object-tostring` has been improved to remove false positives for enum types. + +JavaScript/TypeScript +""""""""""""""""""""" + +* Data flow is now tracked through the :code:`Promise.try` and :code:`Array.prototype.with` functions. +* Query :code:`js/index-out-of-bounds` no longer produces a false-positive when a strictly-less-than check overrides a previous less-than-or-equal test. +* The query :code:`js/remote-property-injection` now detects property injection vulnerabilities through object enumeration patterns such as :code:`Object.keys()`. +* The query "Permissive CORS configuration" (:code:`js/cors-permissive-configuration`) has been promoted from experimental and is now part of the default security suite. + +Python +"""""" + +* The queries :code:`py/missing-call-to-init`, :code:`py/missing-calls-to-del`, :code:`py/multiple-calls-to-init`, and :code:`py/multiple-calls-to-del` queries have been modernized; no longer relying on outdated libraries, producing more precise results with more descriptive alert messages, and improved documentation. + +GitHub Actions +"""""""""""""" + +* Actions analysis now reports file coverage information on the CodeQL status page. + +Deprecated Queries +~~~~~~~~~~~~~~~~~~ + +C# +"" + +* The query :code:`cs/captured-foreach-variable` has been deprecated as the semantics of capturing a 'foreach' variable and using it outside the loop has been stable since C# version 5. + +New Queries +~~~~~~~~~~~ + +Rust +"""" + +* Added a new query, :code:`rust/request-forgery`, for detecting server-side request forgery vulnerabilities. + +Language Libraries +------------------ + +Minor Analysis Improvements +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Golang +"""""" + +* The second argument of the :code:`CreateTemp` function, from the :code:`os` package, is no longer a path-injection sink due to proper sanitization by Go. +* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:`\` to the beginning. + +Java/Kotlin +""""""""""" + +* Improved support for various assertion libraries, in particular JUnit. This affects the control-flow graph slightly, and in turn affects several queries (mainly quality queries). Most queries should see improved precision (new true positives and fewer false positives), in particular :code:`java/constant-comparison`, :code:`java/index-out-of-bounds`, :code:`java/dereferenced-value-may-be-null`, and :code:`java/useless-null-check`. Some medium precision queries like :code:`java/toctou-race-condition` and :code:`java/unreleased-lock` may see mixed result changes (both slight improvements and slight regressions). +* Added taint flow model for :code:`java.crypto.KDF`. +* Added taint flow model for :code:`java.lang.ScopedValue`. + +JavaScript/TypeScript +""""""""""""""""""""" + +* Added modeling for promisification libraries :code:`@gar/promisify`, :code:`es6-promisify`, :code:`util.promisify`, :code:`thenify-all`, :code:`call-me-maybe`, :code:`@google-cloud/promisify`, and :code:`util-promisify`. +* Data flow is now tracked through promisified user-defined functions. + +Swift +""""" + +* Updated to allow analysis of Swift 6.1.3. + +Rust +"""" + +* Added cryptography related models for the :code:`cookie` and :code:`biscotti` crates. + +Deprecated APIs +~~~~~~~~~~~~~~~ + +C/C++ +""""" + +* The predicate :code:`getAContructorCall` in the class :code:`SslContextClass` has been deprecated. Use :code:`getAConstructorCall` instead. + +New Features +~~~~~~~~~~~~ + +C/C++ +""""" + +* Added predicates :code:`getTransitiveNumberOfVlaDimensionStmts`, :code:`getTransitiveVlaDimensionStmt`, and :code:`getParentVlaDecl` to :code:`VlaDeclStmt` for handling :code:`VlaDeclStmt`\ s whose base type is defined in terms of another :code:`VlaDeclStmt` via a :code:`typedef`. + +Java/Kotlin +""""""""""" + +* The Java extractor and QL libraries now support Java 25. +* Added support for Java 25 compact source files (JEP 512). The new predicate :code:`Class.isImplicit()` identifies classes that are implicitly declared when using compact source files, and the new predicate :code:`CompilationUnit.isCompactSourceFile()` identifies compilation units that contain compact source files. +* Added support for Java 25 module import declarations. +* Add :code:`ModuleImportDeclaration` class. diff --git a/docs/codeql/codeql-overview/codeql-changelog/index.rst b/docs/codeql/codeql-overview/codeql-changelog/index.rst index 87cd03ebfaf..41230fc72f1 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/index.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/index.rst @@ -11,6 +11,7 @@ A list of queries for each suite and language `is available here Date: Wed, 24 Sep 2025 15:17:07 +0100 Subject: [PATCH 100/160] Rust: Update doc comments for StmtList. --- rust/schema/annotations.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index 37149392675..d609e1d03b7 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1828,13 +1828,15 @@ class _: @annotate(StmtList) class _: """ - A list of statements in a block. + A list of statements in a block, with an optional tail expression at the + end that determines the block's value. For example: ```rust { let x = 1; let y = 2; + x + y } // ^^^^^^^^^ ``` From ed3a6fd799eff8b48ea6c19af559779c61c92e03 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 24 Sep 2025 15:24:57 +0100 Subject: [PATCH 101/160] Rust: Codegen. --- rust/ql/.generated.list | 8 ++++---- rust/ql/lib/codeql/rust/elements/StmtList.qll | 4 +++- .../ql/lib/codeql/rust/elements/internal/StmtListImpl.qll | 4 +++- .../lib/codeql/rust/elements/internal/generated/Raw.qll | 4 +++- .../codeql/rust/elements/internal/generated/StmtList.qll | 4 +++- .../test/extractor-tests/generated/.generated_tests.list | 2 +- .../extractor-tests/generated/StmtList/gen_stmt_list.rs | 4 +++- 7 files changed, 20 insertions(+), 10 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 92d0a7a4cd8..7c12fda08a9 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -144,7 +144,7 @@ lib/codeql/rust/elements/SliceTypeRepr.qll 730e4d0eeefb9b2284e15b41cd0afc3cbe255 lib/codeql/rust/elements/SourceFile.qll 0b6a3e58767c07602b19975009a2ad53ecf1fd721302af543badb643c1fbb6c4 511d5564aab70b1fcd625e07f3d7e3ceb0c4811a5740de64a55a9a728ba8d32c lib/codeql/rust/elements/Static.qll 9dca6d4fb80fb4ead49a3de89bec2b02bae6f96fbc2601dde35a2aa69a9bfdb0 70f67bc75d7799dab04ea7a7fd13286bb76bbe514be16d23149c59dfb31fd0c9 lib/codeql/rust/elements/Stmt.qll 532b12973037301246daf7d8c0177f734202f43d9261c7a4ca6f5080eea8ca64 b838643c4f2b4623d2c816cddad0e68ca3e11f2879ab7beaece46f489ec4b1f3 -lib/codeql/rust/elements/StmtList.qll e874859ce03672d0085e47e0ca5e571b92b539b31bf0d5a8802f9727bef0c6b0 e5fe83237f713cdb57c446a6e1c20f645c2f49d9f5ef2c984032df83acb3c0de +lib/codeql/rust/elements/StmtList.qll 8bad277dfd88735195b8fd43bb1395cb2393c488d89304d6a6e6d8ec3eb24b73 cd1d483aecb8bb1876b8153a872f680febc2ef6c315d661c85ec1b2fa07e4fc0 lib/codeql/rust/elements/Struct.qll 297d3ea732fc7fbb8b8fb5479c1873ce84705146853ff752c84a6f70af12b923 3df0e5fd50a910a0b5611c3a860a1d7c318f6925c3a0727006d91840caf04812 lib/codeql/rust/elements/StructExpr.qll 84f384ef74c723796e514186037a91dd9666556f62c717f133ce22e9dda4425f 176497835252cfdfe110e58ebde9fbde553d03e44e07d3e4d8041e835dbf31b9 lib/codeql/rust/elements/StructExprField.qll 3eb9f17ecd1ad38679689eb4ecc169d3a0b5b7a3fc597ae5a957a7aea2f74e4f 8fcd26f266f203004899a60447ba16e7eae4e3a654fbec7f54e26857730ede93 @@ -385,7 +385,7 @@ lib/codeql/rust/elements/internal/StaticConstructor.qll 6dd7ee3fd16466c407de35b4 lib/codeql/rust/elements/internal/StaticImpl.qll 48071e29c72032b59ad82771d54be92ac0f4c1a68fb1129c5c7991385804d7b1 85c0be8e37a91d6e775b191f0cb52dd8bf70418e6e9947b82c58c40a6d73b406 lib/codeql/rust/elements/internal/StmtImpl.qll ea99d261f32592ff368cc3a1960864989897c92944f1675549e0753964cb562f 9117b4cdfad56f8fa3bc5d921c2146b4ff0658e8914ac51bf48eb3e68599dd6b lib/codeql/rust/elements/internal/StmtListConstructor.qll 435d59019e17a6279110a23d3d5dfbc1d1e16fc358a93a1d688484d22a754866 23fcb60a5cbb66174e459bc10bd7c28ed532fd1ab46f10b9f0c8a6291d3e343f -lib/codeql/rust/elements/internal/StmtListImpl.qll b39f93534013fe38fee68fbc0232146c92b5f90ee0f6e36da31fb1a3797b3175 2b26bc14c2afb94de2d27ba511eca21313b6fc021c827637cd5904154abb9f3f +lib/codeql/rust/elements/internal/StmtListImpl.qll eecb90e4a64445047804d66af8e00772d25da197540eb93c1e6e53ddeca26a4b 3974e3bd1bb8df15f1086e2b662f970b615db447eb7d88939ce017bfba120c39 lib/codeql/rust/elements/internal/StructConstructor.qll 52921ea6e70421fd08884dc061d0c2dfbbb8dd83d98f1f3c70572cfe57b2a173 dcb3ea8e45ee875525c645fe5d08e6db9013b86bd351c77df4590d0c1439ab9f lib/codeql/rust/elements/internal/StructExprConstructor.qll 69761fa65a4bedf2893fdfc49753fd1289d9eb64cf405227458161b95fa550cb 72ed5f32dcf6a462d9d3cadfc57395a40ee6f4e294a88dbda78761b4a0759ece lib/codeql/rust/elements/internal/StructExprFieldConstructor.qll 6766d7941963904b3a704e64381a478d410c2ef88e8facbc82efca4e781dac96 a14ce465f0f4e43dea5c21c269d803b0ad452d2eb03f4342ea7a9f5d0b357d60 @@ -585,7 +585,7 @@ lib/codeql/rust/elements/internal/generated/PtrTypeRepr.qll 8d0ea4f6c7f8203340bf lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll 80826a6a6868a803aa2372e31c52a03e1811a3f1f2abdb469f91ca0bfdd9ecb6 34ee1e208c1690cba505dff2c588837c0cd91e185e2a87d1fe673191962276a9 -lib/codeql/rust/elements/internal/generated/Raw.qll ae8ebdaa26dc2dfbcc8d64c9c7b296de2e0e78086ce7545cbedfa1f560ef2ffa 6a78058f346e34a2da4dd984f76bf848d7d6708d4c0a35151303748cb0ea92fa +lib/codeql/rust/elements/internal/generated/Raw.qll 74fdb238b66345f937d37a8bf354b13263c1d4fd3fcb5a98c607225bade2df25 31dce64c83ea6f06df0a5df01d18398c65bb767da3d1ea63ebe6226a7b7f848f lib/codeql/rust/elements/internal/generated/RefExpr.qll 7d995884e3dc1c25fc719f5d7253179344d63650e217e9ff6530285fe7a57f64 f2c3c12551deea4964b66553fb9b6423ee16fec53bd63db4796191aa60dc6c66 lib/codeql/rust/elements/internal/generated/RefPat.qll 456ede39837463ee22a630ec7ab6c8630d3664a8ea206fcc6e4f199e92fa564c 5622062765f32930465ba6b170e986706f159f6070f48adee3c20e24e8df4e05 lib/codeql/rust/elements/internal/generated/RefTypeRepr.qll 5b0663a6d234572fb3e467e276d019415caa95ef006438cc59b7af4e1783161e 0e27c8a8f0e323c0e4d6db01fca821bf07c0864d293cdf96fa891b10820c1e4b @@ -600,7 +600,7 @@ lib/codeql/rust/elements/internal/generated/SliceTypeRepr.qll 6f4f9d7e29784ce95d lib/codeql/rust/elements/internal/generated/SourceFile.qll 4bc95c88b49868d1da1a887b35e43ae81e51a69407e79463f5e8824801859380 5641581d70241c0d0d0426976968576ebbef10c183f0371583b243e4e5bbf576 lib/codeql/rust/elements/internal/generated/Static.qll 1a6c87d3c5602e3d02268ebe2463a4ac64614ad25e8966a9bdb9c0ef58991365 cc1fe16d70cdce41a12e41a8f80cc38bdd7efa49c1544e35342fcf3cd26b8219 lib/codeql/rust/elements/internal/generated/Stmt.qll 8473ff532dd5cc9d7decaddcd174b94d610f6ca0aec8e473cc051dad9f3db917 6ef7d2b5237c2dbdcacbf7d8b39109d4dc100229f2b28b5c9e3e4fbf673ba72b -lib/codeql/rust/elements/internal/generated/StmtList.qll 816aebf8f56e179f5f0ba03e80d257ee85459ea757392356a0af6dbd0cd9ef5e 6aa51cdcdc8d93427555fa93f0e84afdfbbd4ffc8b8d378ae4a22b5b6f94f48b +lib/codeql/rust/elements/internal/generated/StmtList.qll 0d0ca02f5a1a0e00ecb1f907e0967c225d77df636921158e516179891a07dc55 e823d6224b75bf06c6633477daf3c822bc38ad721c49e1d3200dfb749c915e48 lib/codeql/rust/elements/internal/generated/Struct.qll 999da1b46e40d6e03fd2338fea02429462877c329c5d1338618cbd886a81567e daa7ff7bd32c554462e0a1502d8319cb5e734e056d0564e06596e416e2b88e9d lib/codeql/rust/elements/internal/generated/StructExpr.qll e77702890561102af38f52d836729e82569c964f8d4c7e680b27992c1ff0f141 23dc51f68107ab0e5c9dd88a6bcc85bb66e8e0f4064cb4d416f50f2ba5db698c lib/codeql/rust/elements/internal/generated/StructExprField.qll 6bdc52ed325fd014495410c619536079b8c404e2247bd2435aa7685dd56c3833 501a30650cf813176ff325a1553da6030f78d14be3f84fea6d38032f4262c6b0 diff --git a/rust/ql/lib/codeql/rust/elements/StmtList.qll b/rust/ql/lib/codeql/rust/elements/StmtList.qll index 76a4b5d2c34..9401cb99084 100644 --- a/rust/ql/lib/codeql/rust/elements/StmtList.qll +++ b/rust/ql/lib/codeql/rust/elements/StmtList.qll @@ -10,13 +10,15 @@ import codeql.rust.elements.Expr import codeql.rust.elements.Stmt /** - * A list of statements in a block. + * A list of statements in a block, with an optional tail expression at the + * end that determines the block's value. * * For example: * ```rust * { * let x = 1; * let y = 2; + * x + y * } * // ^^^^^^^^^ * ``` diff --git a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll index 85940ef7d21..72fcd6a5c70 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll @@ -13,13 +13,15 @@ private import codeql.rust.elements.internal.generated.StmtList */ module Impl { /** - * A list of statements in a block. + * A list of statements in a block, with an optional tail expression at the + * end that determines the block's value. * * For example: * ```rust * { * let x = 1; * let y = 2; + * x + y * } * // ^^^^^^^^^ * ``` diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index abf844b77f5..685c3c65ed3 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -943,13 +943,15 @@ module Raw { /** * INTERNAL: Do not use. - * A list of statements in a block. + * A list of statements in a block, with an optional tail expression at the + * end that determines the block's value. * * For example: * ```rust * { * let x = 1; * let y = 2; + * x + y * } * // ^^^^^^^^^ * ``` diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll index 3460c239a9f..d1913438392 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll @@ -17,13 +17,15 @@ import codeql.rust.elements.Stmt */ module Generated { /** - * A list of statements in a block. + * A list of statements in a block, with an optional tail expression at the + * end that determines the block's value. * * For example: * ```rust * { * let x = 1; * let y = 2; + * x + y * } * // ^^^^^^^^^ * ``` diff --git a/rust/ql/test/extractor-tests/generated/.generated_tests.list b/rust/ql/test/extractor-tests/generated/.generated_tests.list index c0e2d095be6..2fcb0b79be4 100644 --- a/rust/ql/test/extractor-tests/generated/.generated_tests.list +++ b/rust/ql/test/extractor-tests/generated/.generated_tests.list @@ -114,7 +114,7 @@ SlicePat/gen_slice_pat.rs df4a6692f5100aa11dd777561400ce71e37b85f2363b0638c21975 SliceTypeRepr/gen_slice_type_repr.rs 4a85402d40028c5a40ef35018453a89700b2171bc62fd86587378484831b969f 4a85402d40028c5a40ef35018453a89700b2171bc62fd86587378484831b969f SourceFile/gen_source_file.rs c0469cc8f0ecce3dd2e77963216d7e8808046014533359a44c1698e48783b420 c0469cc8f0ecce3dd2e77963216d7e8808046014533359a44c1698e48783b420 Static/gen_static.rs 21314018ea184c1ddcb594d67bab97ae18ceaf663d9f120f39ff755d389dde7a 21314018ea184c1ddcb594d67bab97ae18ceaf663d9f120f39ff755d389dde7a -StmtList/gen_stmt_list.rs adbd82045a50e2051434ce3cdd524c9f2c6ad9f3dd02b4766fb107e2e99212db adbd82045a50e2051434ce3cdd524c9f2c6ad9f3dd02b4766fb107e2e99212db +StmtList/gen_stmt_list.rs 1051a20a90b59142e3fddfbbabd0eff586586b1812c6ab788c5391153bab8851 1051a20a90b59142e3fddfbbabd0eff586586b1812c6ab788c5391153bab8851 Struct/gen_struct.rs 5e181e90075f716c04c75e4ef0334abe3d5f419cd9ccfadfe595c09fab33566b 5e181e90075f716c04c75e4ef0334abe3d5f419cd9ccfadfe595c09fab33566b StructExpr/gen_struct_expr.rs e7824008b0b73d02f6243fd8a18e0ef93c63bfe775a878fc2679c3870fc342fd e7824008b0b73d02f6243fd8a18e0ef93c63bfe775a878fc2679c3870fc342fd StructExprField/gen_struct_expr_field.rs 4ccca8e8ad462b4873f5604f0afdd1836027b8d39e36fbe7d6624ef3e744a084 4ccca8e8ad462b4873f5604f0afdd1836027b8d39e36fbe7d6624ef3e744a084 diff --git a/rust/ql/test/extractor-tests/generated/StmtList/gen_stmt_list.rs b/rust/ql/test/extractor-tests/generated/StmtList/gen_stmt_list.rs index 8cc83732b62..9802e4bc995 100644 --- a/rust/ql/test/extractor-tests/generated/StmtList/gen_stmt_list.rs +++ b/rust/ql/test/extractor-tests/generated/StmtList/gen_stmt_list.rs @@ -1,12 +1,14 @@ // generated by codegen, do not edit fn test_stmt_list() -> () { - // A list of statements in a block. + // A list of statements in a block, with an optional tail expression at the + // end that determines the block's value. // // For example: { let x = 1; let y = 2; + x + y } // ^^^^^^^^^ } From 711d49770f878f62031ee352058789af6cabf594 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 5 Sep 2025 20:27:45 +0100 Subject: [PATCH 102/160] Improve logging to include proxy vars --- go/extractor/util/registryproxy.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/go/extractor/util/registryproxy.go b/go/extractor/util/registryproxy.go index 301d45896d2..fb140cba728 100644 --- a/go/extractor/util/registryproxy.go +++ b/go/extractor/util/registryproxy.go @@ -113,11 +113,6 @@ func getEnvVars() []string { // Applies private package proxy related environment variables to `cmd`. func ApplyProxyEnvVars(cmd *exec.Cmd) { - slog.Debug( - "Applying private registry proxy environment variables", - slog.String("cmd_args", strings.Join(cmd.Args, " ")), - ) - // If we haven't done so yet, check whether the proxy environment variables are set // and extract information from them. if !proxy_vars_checked { @@ -131,4 +126,10 @@ func ApplyProxyEnvVars(cmd *exec.Cmd) { if proxy_vars != nil { cmd.Env = append(os.Environ(), proxy_vars...) } + + slog.Debug( + "Applying private registry proxy environment variables", + slog.String("cmd_args", strings.Join(cmd.Args, " ")), + slog.String("proxy_vars", strings.Join(proxy_vars, ",")), + ) } From 23a04613c08ef2c5ef75309c4336c4561321461b Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 17:40:38 +0100 Subject: [PATCH 103/160] Set lower-case variants of `HTTP_PROXY` and `HTTPS_PROXY` --- go/extractor/util/registryproxy.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/go/extractor/util/registryproxy.go b/go/extractor/util/registryproxy.go index fb140cba728..c3faab4900a 100644 --- a/go/extractor/util/registryproxy.go +++ b/go/extractor/util/registryproxy.go @@ -53,7 +53,13 @@ func getEnvVars() []string { if proxy_host, proxy_host_set := os.LookupEnv(PROXY_HOST); proxy_host_set && proxy_host != "" { if proxy_port, proxy_port_set := os.LookupEnv(PROXY_PORT); proxy_port_set && proxy_port != "" { proxy_address = fmt.Sprintf("http://%s:%s", proxy_host, proxy_port) - result = append(result, fmt.Sprintf("HTTP_PROXY=%s", proxy_address), fmt.Sprintf("HTTPS_PROXY=%s", proxy_address)) + result = append( + result, + fmt.Sprintf("HTTP_PROXY=%s", proxy_address), + fmt.Sprintf("HTTPS_PROXY=%s", proxy_address), + fmt.Sprintf("http_proxy=%s", proxy_address), + fmt.Sprintf("https_proxy=%s", proxy_address), + ) slog.Info("Found private registry proxy", slog.String("proxy_address", proxy_address)) } From 895399ff0569686e0b7995e7fadc7ab82e811716 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 15:31:59 +0100 Subject: [PATCH 104/160] Rename `proxy_configs` to `goproxy_servers` and only store URLs --- go/extractor/util/registryproxy.go | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/go/extractor/util/registryproxy.go b/go/extractor/util/registryproxy.go index c3faab4900a..7ebc3cb508d 100644 --- a/go/extractor/util/registryproxy.go +++ b/go/extractor/util/registryproxy.go @@ -26,9 +26,8 @@ var proxy_address string // The path to the temporary file that stores the proxy certificate, if any. var proxy_cert_file string -// An array of registry configurations that are relevant to Go. -// This excludes other registry configurations that may be available, but are not relevant to Go. -var proxy_configs []RegistryConfig +// An array of goproxy server URLs. +var goproxy_servers []string // Stores the environment variables that we wish to pass on to `go` commands. var proxy_vars []string = nil @@ -97,16 +96,16 @@ func getEnvVars() []string { // filter others out at this point. for _, cfg := range val { if cfg.Type == GOPROXY_SERVER { - proxy_configs = append(proxy_configs, cfg) + goproxy_servers = append(goproxy_servers, cfg.URL) slog.Info("Found GOPROXY server", slog.String("url", cfg.URL)) } } - if len(proxy_configs) > 0 { + if len(goproxy_servers) > 0 { goproxy_val := "https://proxy.golang.org,direct" - for _, cfg := range proxy_configs { - goproxy_val = cfg.URL + "," + goproxy_val + for _, url := range goproxy_servers { + goproxy_val = url + "," + goproxy_val } result = append(result, fmt.Sprintf("GOPROXY=%s", goproxy_val), "GOPRIVATE=", "GONOPROXY=") From a8fa1a76c482146e9cc59c1d58309e6c0eb02f90 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 15:52:53 +0100 Subject: [PATCH 105/160] Use `git_source` configurations for `GOPRIVATE` --- go/extractor/util/registryproxy.go | 17 ++++++++++++++- go/extractor/util/registryproxy_test.go | 28 +++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/go/extractor/util/registryproxy.go b/go/extractor/util/registryproxy.go index 7ebc3cb508d..9aa50ca4cc3 100644 --- a/go/extractor/util/registryproxy.go +++ b/go/extractor/util/registryproxy.go @@ -14,6 +14,7 @@ const PROXY_PORT = "CODEQL_PROXY_PORT" const PROXY_CA_CERTIFICATE = "CODEQL_PROXY_CA_CERTIFICATE" const PROXY_URLS = "CODEQL_PROXY_URLS" const GOPROXY_SERVER = "goproxy_server" +const GIT_SOURCE = "git_source" type RegistryConfig struct { Type string `json:"type"` @@ -29,6 +30,9 @@ var proxy_cert_file string // An array of goproxy server URLs. var goproxy_servers []string +// An array of Git URLs. +var git_sources []string + // Stores the environment variables that we wish to pass on to `go` commands. var proxy_vars []string = nil @@ -98,9 +102,14 @@ func getEnvVars() []string { if cfg.Type == GOPROXY_SERVER { goproxy_servers = append(goproxy_servers, cfg.URL) slog.Info("Found GOPROXY server", slog.String("url", cfg.URL)) + } else if cfg.Type == GIT_SOURCE { + git_sources = append(git_sources, cfg.URL) + slog.Info("Found Git source", slog.String("url", cfg.URL)) } } + goprivate := []string{} + if len(goproxy_servers) > 0 { goproxy_val := "https://proxy.golang.org,direct" @@ -108,8 +117,14 @@ func getEnvVars() []string { goproxy_val = url + "," + goproxy_val } - result = append(result, fmt.Sprintf("GOPROXY=%s", goproxy_val), "GOPRIVATE=", "GONOPROXY=") + result = append(result, fmt.Sprintf("GOPROXY=%s", goproxy_val), "GONOPROXY=") } + + if len(git_sources) > 0 { + goprivate = append(goprivate, git_sources...) + } + + result = append(result, fmt.Sprintf("GOPRIVATE=%s", strings.Join(goprivate, ","))) } } diff --git a/go/extractor/util/registryproxy_test.go b/go/extractor/util/registryproxy_test.go index a21b1a215c1..ef63bd9d3f8 100644 --- a/go/extractor/util/registryproxy_test.go +++ b/go/extractor/util/registryproxy_test.go @@ -47,3 +47,31 @@ func TestParseRegistryConfigs(t *testing.T) { t.Fatalf("Expected `URL` to be `https://proxy.example.com/mod`, but got `%s`", first.URL) } } + +func TestParseRegistryConfigsMultiple(t *testing.T) { + multiple := parseRegistryConfigsSuccess(t, "[{ \"type\": \"git_source\", \"url\": \"https://github.com/github\" }, { \"type\": \"goproxy_server\", \"url\": \"https://proxy.example.com/mod\" }]") + + if len(multiple) != 2 { + t.Fatalf("Expected `parseRegistryConfigs` to return two configurations, but got %d.", len(multiple)) + } + + first := multiple[0] + + if first.Type != "git_source" { + t.Fatalf("Expected `Type` to be `git_source`, but got `%s`", first.Type) + } + + if first.URL != "https://github.com/github" { + t.Fatalf("Expected `URL` to be `https://github.com/github`, but got `%s`", first.URL) + } + + second := multiple[1] + + if second.Type != "goproxy_server" { + t.Fatalf("Expected `Type` to be `goproxy_server`, but got `%s`", second.Type) + } + + if second.URL != "https://proxy.example.com/mod" { + t.Fatalf("Expected `URL` to be `https://proxy.example.com/mod`, but got `%s`", second.URL) + } +} From 4ef8ff9a0fe87940510a2dffe2e1defdfd64c5f2 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 5 Sep 2025 20:35:14 +0100 Subject: [PATCH 106/160] Append `*` to `git_source` URL if not present Since `GOPRIVATE` / `GONOPROXY` expect a glob pattern --- go/extractor/util/registryproxy.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/go/extractor/util/registryproxy.go b/go/extractor/util/registryproxy.go index 9aa50ca4cc3..0ba49cb55d6 100644 --- a/go/extractor/util/registryproxy.go +++ b/go/extractor/util/registryproxy.go @@ -103,7 +103,11 @@ func getEnvVars() []string { goproxy_servers = append(goproxy_servers, cfg.URL) slog.Info("Found GOPROXY server", slog.String("url", cfg.URL)) } else if cfg.Type == GIT_SOURCE { - git_sources = append(git_sources, cfg.URL) + if strings.HasSuffix(cfg.URL, "*") { + git_sources = append(git_sources, cfg.URL) + } else { + git_sources = append(git_sources, cfg.URL+"*") + } slog.Info("Found Git source", slog.String("url", cfg.URL)) } } From bc38b79c9a185d589e16f38f634f878d2995c029 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Fri, 5 Sep 2025 22:38:06 +0100 Subject: [PATCH 107/160] Convert URLs to expected format --- go/extractor/util/registryproxy.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/go/extractor/util/registryproxy.go b/go/extractor/util/registryproxy.go index 0ba49cb55d6..3909f9e5cf1 100644 --- a/go/extractor/util/registryproxy.go +++ b/go/extractor/util/registryproxy.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "log/slog" + "net/url" "os" "os/exec" "strings" @@ -103,12 +104,14 @@ func getEnvVars() []string { goproxy_servers = append(goproxy_servers, cfg.URL) slog.Info("Found GOPROXY server", slog.String("url", cfg.URL)) } else if cfg.Type == GIT_SOURCE { - if strings.HasSuffix(cfg.URL, "*") { - git_sources = append(git_sources, cfg.URL) + parsed, err := url.Parse(cfg.URL) + if err == nil && parsed.Hostname() != "" { + git_source := parsed.Hostname() + parsed.Path + "*" + git_sources = append(git_sources, git_source) + slog.Info("Found Git source", slog.String("source", git_source)) } else { - git_sources = append(git_sources, cfg.URL+"*") + slog.Warn("Not a valid URL for Git source", slog.String("url", cfg.URL)) } - slog.Info("Found Git source", slog.String("url", cfg.URL)) } } From 8c8499229d3dd32440a39909b069235dbbd21e83 Mon Sep 17 00:00:00 2001 From: "Michael B. Gale" Date: Thu, 4 Sep 2025 18:05:38 +0100 Subject: [PATCH 108/160] Configure `git` to use the certificate, if needed --- go/extractor/util/registryproxy.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/go/extractor/util/registryproxy.go b/go/extractor/util/registryproxy.go index 3909f9e5cf1..1f20832e8d8 100644 --- a/go/extractor/util/registryproxy.go +++ b/go/extractor/util/registryproxy.go @@ -129,6 +129,18 @@ func getEnvVars() []string { if len(git_sources) > 0 { goprivate = append(goprivate, git_sources...) + + if proxy_cert_file != "" { + slog.Info("Configuring `git` to use proxy certificate", slog.String("path", proxy_cert_file)) + cmd := exec.Command("git", "config", "--global", "http.sslCAInfo", proxy_cert_file) + + out, cmdErr := cmd.CombinedOutput() + slog.Info(string(out)) + + if cmdErr != nil { + slog.Error("Failed to configure `git` to accept the certificate file", slog.String("error", cmdErr.Error())) + } + } } result = append(result, fmt.Sprintf("GOPRIVATE=%s", strings.Join(goprivate, ","))) From 8ad6952ddaa99736b3ac42a6504b78841cc616f3 Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Wed, 24 Sep 2025 15:58:09 +0100 Subject: [PATCH 109/160] Fix escape character in changelog for Go query --- .../codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst index 3b70843b651..18623d63c45 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst @@ -126,7 +126,7 @@ Golang """""" * The second argument of the :code:`CreateTemp` function, from the :code:`os` package, is no longer a path-injection sink due to proper sanitization by Go. -* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:`\` to the beginning. +* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:`\\` to the beginning. Java/Kotlin """"""""""" From f3ef6ef3c978b8585e917661b1030c5dd581a4f2 Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Wed, 24 Sep 2025 16:00:40 +0100 Subject: [PATCH 110/160] Fix formatting issue in changelog for Go query --- .../codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst index 18623d63c45..95952ee4ac9 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst @@ -126,7 +126,7 @@ Golang """""" * The second argument of the :code:`CreateTemp` function, from the :code:`os` package, is no longer a path-injection sink due to proper sanitization by Go. -* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:`\\` to the beginning. +* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:\ to the beginning. Java/Kotlin """"""""""" From 6c488e6e71d4ae10227ebe496f7e29b68dc2b347 Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Wed, 24 Sep 2025 16:01:38 +0100 Subject: [PATCH 111/160] Fix formatting in codeql-cli-2.23.1.rst --- .../codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst index 95952ee4ac9..67f4ee93e9f 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst @@ -126,7 +126,7 @@ Golang """""" * The second argument of the :code:`CreateTemp` function, from the :code:`os` package, is no longer a path-injection sink due to proper sanitization by Go. -* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:\ to the beginning. +* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:\`` to the beginning. Java/Kotlin """"""""""" From ab30c786a5fdea75a5b7a2a5875adf0fb9021ca2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 24 Sep 2025 16:07:52 +0100 Subject: [PATCH 112/160] Rust: Accept test changes. --- .../generated/StmtList/StmtList.expected | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/rust/ql/test/extractor-tests/generated/StmtList/StmtList.expected b/rust/ql/test/extractor-tests/generated/StmtList/StmtList.expected index 02f322734ca..5c5d77a34ed 100644 --- a/rust/ql/test/extractor-tests/generated/StmtList/StmtList.expected +++ b/rust/ql/test/extractor-tests/generated/StmtList/StmtList.expected @@ -1,9 +1,10 @@ instances -| gen_stmt_list.rs:3:27:12:1 | StmtList | -| gen_stmt_list.rs:7:5:10:5 | StmtList | +| gen_stmt_list.rs:3:27:14:1 | StmtList | +| gen_stmt_list.rs:8:5:12:5 | StmtList | getAttr getStatement -| gen_stmt_list.rs:7:5:10:5 | StmtList | 0 | gen_stmt_list.rs:8:9:8:18 | let ... = 1 | -| gen_stmt_list.rs:7:5:10:5 | StmtList | 1 | gen_stmt_list.rs:9:9:9:18 | let ... = 2 | +| gen_stmt_list.rs:8:5:12:5 | StmtList | 0 | gen_stmt_list.rs:9:9:9:18 | let ... = 1 | +| gen_stmt_list.rs:8:5:12:5 | StmtList | 1 | gen_stmt_list.rs:10:9:10:18 | let ... = 2 | getTailExpr -| gen_stmt_list.rs:3:27:12:1 | StmtList | gen_stmt_list.rs:7:5:10:5 | { ... } | +| gen_stmt_list.rs:3:27:14:1 | StmtList | gen_stmt_list.rs:8:5:12:5 | { ... } | +| gen_stmt_list.rs:8:5:12:5 | StmtList | gen_stmt_list.rs:11:9:11:13 | ... + ... | From 7459eed4355feddd5e254e59dd6652870312ffe9 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 24 Sep 2025 15:40:44 +0100 Subject: [PATCH 113/160] Rust: Update doc comments for StmtList predicates. --- rust/schema/annotations.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/rust/schema/annotations.py b/rust/schema/annotations.py index d609e1d03b7..ce1b97570ee 100644 --- a/rust/schema/annotations.py +++ b/rust/schema/annotations.py @@ -1841,7 +1841,14 @@ class _: // ^^^^^^^^^ ``` """ - + statements: _ | doc("statements of this statement list") | desc(""" + The statements of a `StmtList` do not include any tail expression, which + can be accessed with predicates such as `getTailExpr`. + """) + tail_expr: _ | doc("tail expression of this statement list") | desc(""" + The tail expression is the expression at the end of a block, that + determines the block's value. + """) @annotate(Struct, replace_bases={Item: None}) # still an Item via Adt class _: From 85945dba293716ab99ced966f3f913bb29b983c9 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 24 Sep 2025 15:46:50 +0100 Subject: [PATCH 114/160] Rust: Codegen. --- rust/ql/.generated.list | 4 ++-- rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll | 6 ++++++ .../codeql/rust/elements/internal/generated/StmtList.qll | 6 ++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index 7c12fda08a9..aebbdc50f1e 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -585,7 +585,7 @@ lib/codeql/rust/elements/internal/generated/PtrTypeRepr.qll 8d0ea4f6c7f8203340bf lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9 lib/codeql/rust/elements/internal/generated/RangePat.qll 80826a6a6868a803aa2372e31c52a03e1811a3f1f2abdb469f91ca0bfdd9ecb6 34ee1e208c1690cba505dff2c588837c0cd91e185e2a87d1fe673191962276a9 -lib/codeql/rust/elements/internal/generated/Raw.qll 74fdb238b66345f937d37a8bf354b13263c1d4fd3fcb5a98c607225bade2df25 31dce64c83ea6f06df0a5df01d18398c65bb767da3d1ea63ebe6226a7b7f848f +lib/codeql/rust/elements/internal/generated/Raw.qll 11d48da73543efe2d6c4c5a30ac8ecdd3c24dc64bbd10bf6976b53445e248ef1 72fddbec1e8e5029442c962599877459406010d81dece075147aa1cc37cf7a42 lib/codeql/rust/elements/internal/generated/RefExpr.qll 7d995884e3dc1c25fc719f5d7253179344d63650e217e9ff6530285fe7a57f64 f2c3c12551deea4964b66553fb9b6423ee16fec53bd63db4796191aa60dc6c66 lib/codeql/rust/elements/internal/generated/RefPat.qll 456ede39837463ee22a630ec7ab6c8630d3664a8ea206fcc6e4f199e92fa564c 5622062765f32930465ba6b170e986706f159f6070f48adee3c20e24e8df4e05 lib/codeql/rust/elements/internal/generated/RefTypeRepr.qll 5b0663a6d234572fb3e467e276d019415caa95ef006438cc59b7af4e1783161e 0e27c8a8f0e323c0e4d6db01fca821bf07c0864d293cdf96fa891b10820c1e4b @@ -600,7 +600,7 @@ lib/codeql/rust/elements/internal/generated/SliceTypeRepr.qll 6f4f9d7e29784ce95d lib/codeql/rust/elements/internal/generated/SourceFile.qll 4bc95c88b49868d1da1a887b35e43ae81e51a69407e79463f5e8824801859380 5641581d70241c0d0d0426976968576ebbef10c183f0371583b243e4e5bbf576 lib/codeql/rust/elements/internal/generated/Static.qll 1a6c87d3c5602e3d02268ebe2463a4ac64614ad25e8966a9bdb9c0ef58991365 cc1fe16d70cdce41a12e41a8f80cc38bdd7efa49c1544e35342fcf3cd26b8219 lib/codeql/rust/elements/internal/generated/Stmt.qll 8473ff532dd5cc9d7decaddcd174b94d610f6ca0aec8e473cc051dad9f3db917 6ef7d2b5237c2dbdcacbf7d8b39109d4dc100229f2b28b5c9e3e4fbf673ba72b -lib/codeql/rust/elements/internal/generated/StmtList.qll 0d0ca02f5a1a0e00ecb1f907e0967c225d77df636921158e516179891a07dc55 e823d6224b75bf06c6633477daf3c822bc38ad721c49e1d3200dfb749c915e48 +lib/codeql/rust/elements/internal/generated/StmtList.qll 834b87cd93f0c5b41736fb52a6c25fd0e3bdce41d5a64cb3d0810c54e90507f4 ec42f2dfa322044ceaaf90d278f0e7e751d63710facbaf3f5ee69ca3c64ecd06 lib/codeql/rust/elements/internal/generated/Struct.qll 999da1b46e40d6e03fd2338fea02429462877c329c5d1338618cbd886a81567e daa7ff7bd32c554462e0a1502d8319cb5e734e056d0564e06596e416e2b88e9d lib/codeql/rust/elements/internal/generated/StructExpr.qll e77702890561102af38f52d836729e82569c964f8d4c7e680b27992c1ff0f141 23dc51f68107ab0e5c9dd88a6bcc85bb66e8e0f4064cb4d416f50f2ba5db698c lib/codeql/rust/elements/internal/generated/StructExprField.qll 6bdc52ed325fd014495410c619536079b8c404e2247bd2435aa7685dd56c3833 501a30650cf813176ff325a1553da6030f78d14be3f84fea6d38032f4262c6b0 diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll index 685c3c65ed3..de56bdffb6c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/Raw.qll @@ -966,11 +966,17 @@ module Raw { /** * Gets the `index`th statement of this statement list (0-based). + * + * The statements of a `StmtList` do not include any tail expression, which + * can be accessed with predicates such as `getTailExpr`. */ Stmt getStatement(int index) { stmt_list_statements(this, index, result) } /** * Gets the tail expression of this statement list, if it exists. + * + * The tail expression is the expression at the end of a block, that + * determines the block's value. */ Expr getTailExpr() { stmt_list_tail_exprs(this, result) } } diff --git a/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll b/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll index d1913438392..26a7f1f363a 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/generated/StmtList.qll @@ -55,6 +55,9 @@ module Generated { /** * Gets the `index`th statement of this statement list (0-based). + * + * The statements of a `StmtList` do not include any tail expression, which + * can be accessed with predicates such as `getTailExpr`. */ Stmt getStatement(int index) { result = @@ -75,6 +78,9 @@ module Generated { /** * Gets the tail expression of this statement list, if it exists. + * + * The tail expression is the expression at the end of a block, that + * determines the block's value. */ Expr getTailExpr() { result = From 86fe68bb61367e57e4831d7ea93eaf6ca65b1888 Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Wed, 24 Sep 2025 16:12:17 +0100 Subject: [PATCH 115/160] Fix formatting in changelog for Go path injection query 2 people + 2 models managed to tackle this insurmountable task. --- .../codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst index 67f4ee93e9f..3767c877b5a 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst @@ -126,7 +126,7 @@ Golang """""" * The second argument of the :code:`CreateTemp` function, from the :code:`os` package, is no longer a path-injection sink due to proper sanitization by Go. -* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:\`` to the beginning. +* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:`\ ` to the beginning. Java/Kotlin """"""""""" From 8debce034973775666f1827350694a178cd9a305 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 24 Sep 2025 16:13:05 +0100 Subject: [PATCH 116/160] Rust: Add helper predicates for accessing statements and expressions together. --- .../rust/elements/internal/StmtListImpl.qll | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll index 72fcd6a5c70..a44448f0f0c 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll @@ -1,4 +1,3 @@ -// generated by codegen, remove this comment if you wish to edit this file /** * This module provides a hand-modifiable wrapper around the generated class `StmtList`. * @@ -26,5 +25,25 @@ module Impl { * // ^^^^^^^^^ * ``` */ - class StmtList extends Generated::StmtList { } + class StmtList extends Generated::StmtList { + /** + * Gets the `index`th statement or expression of this statement list (0-based). + */ + AstNode getStmtOrExpr(int index) { + result = this.getStatement(index) + or + index = max(int i | exists(this.getStatement(i))) + 1 and + result = this.getTailExpr() + } + + /** + * Gets any of the statements or expressions of this statement list. + */ + final AstNode getAStmtOrExpr() { result = this.getStmtOrExpr(_) } + + /** + * Gets the number of statements or expressions of this statement list. + */ + final int getNumberOfStmtOrExpr() { result = count(int i | exists(this.getStmtOrExpr(i))) } + } } From b12b36f3028de88e727c8bafe37b9e2759e46468 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 24 Sep 2025 16:59:59 +0100 Subject: [PATCH 117/160] Rust: Codegen. --- rust/ql/.generated.list | 1 - rust/ql/.gitattributes | 1 - rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/rust/ql/.generated.list b/rust/ql/.generated.list index aebbdc50f1e..e3ec533203d 100644 --- a/rust/ql/.generated.list +++ b/rust/ql/.generated.list @@ -385,7 +385,6 @@ lib/codeql/rust/elements/internal/StaticConstructor.qll 6dd7ee3fd16466c407de35b4 lib/codeql/rust/elements/internal/StaticImpl.qll 48071e29c72032b59ad82771d54be92ac0f4c1a68fb1129c5c7991385804d7b1 85c0be8e37a91d6e775b191f0cb52dd8bf70418e6e9947b82c58c40a6d73b406 lib/codeql/rust/elements/internal/StmtImpl.qll ea99d261f32592ff368cc3a1960864989897c92944f1675549e0753964cb562f 9117b4cdfad56f8fa3bc5d921c2146b4ff0658e8914ac51bf48eb3e68599dd6b lib/codeql/rust/elements/internal/StmtListConstructor.qll 435d59019e17a6279110a23d3d5dfbc1d1e16fc358a93a1d688484d22a754866 23fcb60a5cbb66174e459bc10bd7c28ed532fd1ab46f10b9f0c8a6291d3e343f -lib/codeql/rust/elements/internal/StmtListImpl.qll eecb90e4a64445047804d66af8e00772d25da197540eb93c1e6e53ddeca26a4b 3974e3bd1bb8df15f1086e2b662f970b615db447eb7d88939ce017bfba120c39 lib/codeql/rust/elements/internal/StructConstructor.qll 52921ea6e70421fd08884dc061d0c2dfbbb8dd83d98f1f3c70572cfe57b2a173 dcb3ea8e45ee875525c645fe5d08e6db9013b86bd351c77df4590d0c1439ab9f lib/codeql/rust/elements/internal/StructExprConstructor.qll 69761fa65a4bedf2893fdfc49753fd1289d9eb64cf405227458161b95fa550cb 72ed5f32dcf6a462d9d3cadfc57395a40ee6f4e294a88dbda78761b4a0759ece lib/codeql/rust/elements/internal/StructExprFieldConstructor.qll 6766d7941963904b3a704e64381a478d410c2ef88e8facbc82efca4e781dac96 a14ce465f0f4e43dea5c21c269d803b0ad452d2eb03f4342ea7a9f5d0b357d60 diff --git a/rust/ql/.gitattributes b/rust/ql/.gitattributes index 19f5c284240..df4a65e7d95 100644 --- a/rust/ql/.gitattributes +++ b/rust/ql/.gitattributes @@ -387,7 +387,6 @@ /lib/codeql/rust/elements/internal/StaticImpl.qll linguist-generated /lib/codeql/rust/elements/internal/StmtImpl.qll linguist-generated /lib/codeql/rust/elements/internal/StmtListConstructor.qll linguist-generated -/lib/codeql/rust/elements/internal/StmtListImpl.qll linguist-generated /lib/codeql/rust/elements/internal/StructConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/StructExprConstructor.qll linguist-generated /lib/codeql/rust/elements/internal/StructExprFieldConstructor.qll linguist-generated diff --git a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll index a44448f0f0c..824ee0f3108 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll @@ -11,6 +11,7 @@ private import codeql.rust.elements.internal.generated.StmtList * be referenced directly. */ module Impl { + // the following QLdoc is generated: if you need to edit it, do it in the schema file /** * A list of statements in a block, with an optional tail expression at the * end that determines the block's value. From 9bdac9d1cf8502574ad3aafb5aa03ca2a5a385d3 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 24 Sep 2025 16:16:15 +0100 Subject: [PATCH 118/160] Rust: Move 'operations' test into elements subdir. --- rust/ql/test/library-tests/{ => elements}/operations/Cargo.lock | 0 .../library-tests/{ => elements}/operations/Operations.expected | 0 .../ql/test/library-tests/{ => elements}/operations/Operations.ql | 0 rust/ql/test/library-tests/{ => elements}/operations/test.rs | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename rust/ql/test/library-tests/{ => elements}/operations/Cargo.lock (100%) rename rust/ql/test/library-tests/{ => elements}/operations/Operations.expected (100%) rename rust/ql/test/library-tests/{ => elements}/operations/Operations.ql (100%) rename rust/ql/test/library-tests/{ => elements}/operations/test.rs (100%) diff --git a/rust/ql/test/library-tests/operations/Cargo.lock b/rust/ql/test/library-tests/elements/operations/Cargo.lock similarity index 100% rename from rust/ql/test/library-tests/operations/Cargo.lock rename to rust/ql/test/library-tests/elements/operations/Cargo.lock diff --git a/rust/ql/test/library-tests/operations/Operations.expected b/rust/ql/test/library-tests/elements/operations/Operations.expected similarity index 100% rename from rust/ql/test/library-tests/operations/Operations.expected rename to rust/ql/test/library-tests/elements/operations/Operations.expected diff --git a/rust/ql/test/library-tests/operations/Operations.ql b/rust/ql/test/library-tests/elements/operations/Operations.ql similarity index 100% rename from rust/ql/test/library-tests/operations/Operations.ql rename to rust/ql/test/library-tests/elements/operations/Operations.ql diff --git a/rust/ql/test/library-tests/operations/test.rs b/rust/ql/test/library-tests/elements/operations/test.rs similarity index 100% rename from rust/ql/test/library-tests/operations/test.rs rename to rust/ql/test/library-tests/elements/operations/test.rs From 93a01983267cde43be78cf97f22702d87540776a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 24 Sep 2025 16:32:03 +0100 Subject: [PATCH 119/160] Rust: Add a test for StmtList. --- .../elements/stmtlist/Cargo.lock | 7 +++ .../elements/stmtlist/StmtList.expected | 9 ++++ .../elements/stmtlist/StmtList.ql | 13 ++++++ .../elements/stmtlist/StmtList.rs | 43 +++++++++++++++++++ 4 files changed, 72 insertions(+) create mode 100644 rust/ql/test/library-tests/elements/stmtlist/Cargo.lock create mode 100644 rust/ql/test/library-tests/elements/stmtlist/StmtList.expected create mode 100644 rust/ql/test/library-tests/elements/stmtlist/StmtList.ql create mode 100644 rust/ql/test/library-tests/elements/stmtlist/StmtList.rs diff --git a/rust/ql/test/library-tests/elements/stmtlist/Cargo.lock b/rust/ql/test/library-tests/elements/stmtlist/Cargo.lock new file mode 100644 index 00000000000..b9856cfaf77 --- /dev/null +++ b/rust/ql/test/library-tests/elements/stmtlist/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "test" +version = "0.0.1" diff --git a/rust/ql/test/library-tests/elements/stmtlist/StmtList.expected b/rust/ql/test/library-tests/elements/stmtlist/StmtList.expected new file mode 100644 index 00000000000..37956c366e3 --- /dev/null +++ b/rust/ql/test/library-tests/elements/stmtlist/StmtList.expected @@ -0,0 +1,9 @@ +| StmtList.rs:4:19:9:1 | StmtList | 2 | hasTailExpr | 0:let ... = 1, 1:let ... = 2, 2:... + ... | +| StmtList.rs:11:18:15:1 | StmtList | 2 | | 0:let ... = 1, 1:let ... = 2 | +| StmtList.rs:17:19:20:1 | StmtList | 0 | hasTailExpr | | +| StmtList.rs:22:18:25:1 | StmtList | 1 | | 0:ExprStmt | +| StmtList.rs:27:18:29:1 | StmtList | 0 | | | +| StmtList.rs:31:18:34:1 | StmtList | 0 | | | +| StmtList.rs:36:29:43:1 | StmtList | 0 | hasTailExpr | | +| StmtList.rs:38:10:40:2 | StmtList | 0 | hasTailExpr | | +| StmtList.rs:40:9:42:2 | StmtList | 0 | hasTailExpr | | diff --git a/rust/ql/test/library-tests/elements/stmtlist/StmtList.ql b/rust/ql/test/library-tests/elements/stmtlist/StmtList.ql new file mode 100644 index 00000000000..048dcd06d6e --- /dev/null +++ b/rust/ql/test/library-tests/elements/stmtlist/StmtList.ql @@ -0,0 +1,13 @@ +import rust +import TestUtils + +from StmtList sl, string tail +where + toBeTested(sl) and + if sl.hasTailExpr() then tail = "hasTailExpr" else tail = "" +select sl, sl.getNumberOfStatements(), tail, + concat(int i, AstNode n | + n = sl.getStmtOrExpr(i) + | + i.toString() + ":" + n.toString(), ", " order by i + ) diff --git a/rust/ql/test/library-tests/elements/stmtlist/StmtList.rs b/rust/ql/test/library-tests/elements/stmtlist/StmtList.rs new file mode 100644 index 00000000000..1437f2afb26 --- /dev/null +++ b/rust/ql/test/library-tests/elements/stmtlist/StmtList.rs @@ -0,0 +1,43 @@ + +// --- tests --- + +fn test1() -> i32 { + // two statements + tail expression + let a = 1; + let b = 2; + a + b +} + +fn test2() -> () { + // two statements only + let a = 1; + let b = 2; +} + +fn test3() -> i32 { + // tail expression only + 1 + 2 +} + +fn test4() -> () { + // one statement only + 1 + 2; +} + +fn test5() -> () { + // neither +} + +fn test6() -> () { + // neither + ; +} + +fn test7(cond: bool) -> i32 { + // nested blocks + if cond { + 1 + } else { + 2 + } +} From 7e8e855f2821f20e8b019158ccfb2a14dfee779d Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 24 Sep 2025 16:50:18 +0100 Subject: [PATCH 120/160] Rust: Fix bug when there are no statements. --- .../ql/lib/codeql/rust/elements/internal/StmtListImpl.qll | 2 +- .../library-tests/elements/stmtlist/StmtList.expected | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll index 824ee0f3108..648a4eab9b8 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll @@ -33,7 +33,7 @@ module Impl { AstNode getStmtOrExpr(int index) { result = this.getStatement(index) or - index = max(int i | exists(this.getStatement(i))) + 1 and + index = max(int i | i = -1 or exists(this.getStatement(i))) + 1 and result = this.getTailExpr() } diff --git a/rust/ql/test/library-tests/elements/stmtlist/StmtList.expected b/rust/ql/test/library-tests/elements/stmtlist/StmtList.expected index 37956c366e3..820b1a76dc9 100644 --- a/rust/ql/test/library-tests/elements/stmtlist/StmtList.expected +++ b/rust/ql/test/library-tests/elements/stmtlist/StmtList.expected @@ -1,9 +1,9 @@ | StmtList.rs:4:19:9:1 | StmtList | 2 | hasTailExpr | 0:let ... = 1, 1:let ... = 2, 2:... + ... | | StmtList.rs:11:18:15:1 | StmtList | 2 | | 0:let ... = 1, 1:let ... = 2 | -| StmtList.rs:17:19:20:1 | StmtList | 0 | hasTailExpr | | +| StmtList.rs:17:19:20:1 | StmtList | 0 | hasTailExpr | 0:... + ... | | StmtList.rs:22:18:25:1 | StmtList | 1 | | 0:ExprStmt | | StmtList.rs:27:18:29:1 | StmtList | 0 | | | | StmtList.rs:31:18:34:1 | StmtList | 0 | | | -| StmtList.rs:36:29:43:1 | StmtList | 0 | hasTailExpr | | -| StmtList.rs:38:10:40:2 | StmtList | 0 | hasTailExpr | | -| StmtList.rs:40:9:42:2 | StmtList | 0 | hasTailExpr | | +| StmtList.rs:36:29:43:1 | StmtList | 0 | hasTailExpr | 0:if cond {...} else {...} | +| StmtList.rs:38:10:40:2 | StmtList | 0 | hasTailExpr | 0:1 | +| StmtList.rs:40:9:42:2 | StmtList | 0 | hasTailExpr | 0:2 | From e41b5f2bc0ef6507c0a2873a8b592bd3cd01c681 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 25 Sep 2025 09:52:22 +0200 Subject: [PATCH 121/160] C++: Update tests after extractor changes --- cpp/ql/test/library-tests/permissive/accesses.expected | 1 - cpp/ql/test/library-tests/permissive/calls.expected | 1 - cpp/ql/test/library-tests/permissive/permissive.cpp | 8 -------- 3 files changed, 10 deletions(-) delete mode 100644 cpp/ql/test/library-tests/permissive/permissive.cpp diff --git a/cpp/ql/test/library-tests/permissive/accesses.expected b/cpp/ql/test/library-tests/permissive/accesses.expected index f3e66dcedaf..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/permissive/accesses.expected +++ b/cpp/ql/test/library-tests/permissive/accesses.expected @@ -1 +0,0 @@ -| permissive.cpp:6:5:6:7 | str | diff --git a/cpp/ql/test/library-tests/permissive/calls.expected b/cpp/ql/test/library-tests/permissive/calls.expected index 9d780e76405..e69de29bb2d 100644 --- a/cpp/ql/test/library-tests/permissive/calls.expected +++ b/cpp/ql/test/library-tests/permissive/calls.expected @@ -1 +0,0 @@ -| permissive.cpp:6:3:6:3 | call to f | permissive.cpp:2:13:2:13 | f | diff --git a/cpp/ql/test/library-tests/permissive/permissive.cpp b/cpp/ql/test/library-tests/permissive/permissive.cpp deleted file mode 100644 index 15f5b94ef61..00000000000 --- a/cpp/ql/test/library-tests/permissive/permissive.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// semmle-extractor-options: --edg --permissive -static void f(char* foo) {} - -static void g(void) { - const char* str = "foo"; - f(str); -} - From a45a3e427c1174ded8d5d9d2cce451a1135a6d2a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:28:10 +0100 Subject: [PATCH 122/160] Rust: Update supported frameworks. --- docs/codeql/reusables/supported-frameworks.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/codeql/reusables/supported-frameworks.rst b/docs/codeql/reusables/supported-frameworks.rst index 3d89a663004..4cba42604ad 100644 --- a/docs/codeql/reusables/supported-frameworks.rst +++ b/docs/codeql/reusables/supported-frameworks.rst @@ -324,10 +324,14 @@ All support is experimental. Name, Category `actix-web `__, Web framework alloc, Standard library + `async-std `__, Asynchronous programming library + `biscotti `__, Cookie management `clap `__, Utility library + `cookie `__, Cookie management core, Standard library `digest `__, Cryptography library - `futures-executor `__, Utility library + `futures `__, Asynchronous programming library + `futures-rustls `__, Network communicator `hyper `__, HTTP library `hyper-util `__, HTTP library `libc `__, Utility library @@ -345,12 +349,14 @@ All support is experimental. `rusqlite `__, Database std, Standard library `rust-crypto `__, Cryptography library + `rustls `__, Network communicator `serde `__, Serialization `smallvec `__, Utility library `sqlx `__, Database `tokio `__, Asynchronous IO `tokio-postgres `__, Database `url `__, Utility library + `warp `__, Web framework Swift built-in support ================================ From a72eb87c93e3d0b52f1d5f80e20792d713852bb0 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 25 Sep 2025 10:35:47 +0100 Subject: [PATCH 123/160] Rust: Remove one that is essentially a duplicate. --- docs/codeql/reusables/supported-frameworks.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/codeql/reusables/supported-frameworks.rst b/docs/codeql/reusables/supported-frameworks.rst index 4cba42604ad..8e00d32a729 100644 --- a/docs/codeql/reusables/supported-frameworks.rst +++ b/docs/codeql/reusables/supported-frameworks.rst @@ -333,7 +333,6 @@ All support is experimental. `futures `__, Asynchronous programming library `futures-rustls `__, Network communicator `hyper `__, HTTP library - `hyper-util `__, HTTP library `libc `__, Utility library `log `__, Logging library `md5 `__, Utility library From 2a814dd37cf7e3d0025b79cf2831b28cd2a92ac3 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 23 Sep 2025 09:30:05 +0200 Subject: [PATCH 124/160] Rust: Model union, never, and pointer types --- .../rust/elements/internal/UnionImpl.qll | 7 ++ rust/ql/lib/codeql/rust/internal/Type.qll | 64 ++++++++++++++++++- .../codeql/rust/internal/TypeInference.qll | 5 ++ .../lib/codeql/rust/internal/TypeMention.qll | 18 ++++++ .../TypeInferenceConsistency.expected | 2 - .../type-inference/type-inference.expected | 2 + .../PathResolutionConsistency.expected | 3 + .../PathResolutionConsistency.expected | 7 ++ 8 files changed, 105 insertions(+), 3 deletions(-) delete mode 100644 rust/ql/test/extractor-tests/macro-expansion/CONSISTENCY/TypeInferenceConsistency.expected create mode 100644 rust/ql/test/query-tests/security/CWE-696/CONSISTENCY/PathResolutionConsistency.expected create mode 100644 rust/ql/test/query-tests/security/CWE-770/CONSISTENCY/PathResolutionConsistency.expected diff --git a/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll index 17551c4834e..712e39e6685 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll @@ -21,6 +21,13 @@ module Impl { * ``` */ class Union extends Generated::Union { + /** Gets the record field named `name`, if any. */ + pragma[nomagic] + StructField getStructField(string name) { + result = this.getStructFieldList().getAField() and + result.getName().getText() = name + } + override string toStringImpl() { result = "union " + this.getName().getText() } } } diff --git a/rust/ql/lib/codeql/rust/internal/Type.qll b/rust/ql/lib/codeql/rust/internal/Type.qll index eaa7e83fc6d..29e6ed283bc 100644 --- a/rust/ql/lib/codeql/rust/internal/Type.qll +++ b/rust/ql/lib/codeql/rust/internal/Type.qll @@ -42,11 +42,14 @@ newtype TType = TStruct(Struct s) or TEnum(Enum e) or TTrait(Trait t) or + TUnion(Union u) or TArrayType() or // todo: add size? TRefType() or // todo: add mut? TImplTraitType(ImplTraitTypeRepr impl) or TDynTraitType(Trait t) { t = any(DynTraitTypeRepr dt).getTrait() } or TSliceType() or + TNeverType() or + TPtrType() or TTupleTypeParameter(int arity, int i) { exists(TTuple(arity)) and i in [0 .. arity - 1] } or TTypeParamTypeParameter(TypeParam t) or TAssociatedTypeTypeParameter(TypeAlias t) { any(TraitItemNode trait).getAnAssocItem() = t } or @@ -57,7 +60,8 @@ newtype TType = } or TRefTypeParameter() or TSelfTypeParameter(Trait t) or - TSliceTypeParameter() + TSliceTypeParameter() or + TPtrTypeParameter() private predicate implTraitTypeParam(ImplTraitTypeRepr implTrait, int i, TypeParam tp) { implTrait.isInReturnPos() and @@ -224,6 +228,31 @@ class TraitType extends Type, TTrait { override Location getLocation() { result = trait.getLocation() } } +/** A union type. */ +class UnionType extends StructOrEnumType, TUnion { + private Union union; + + UnionType() { this = TUnion(union) } + + override ItemNode asItemNode() { result = union } + + override StructField getStructField(string name) { result = union.getStructField(name) } + + override TupleField getTupleField(int i) { none() } + + override TypeParameter getPositionalTypeParameter(int i) { + result = TTypeParamTypeParameter(union.getGenericParamList().getTypeParam(i)) + } + + override TypeMention getTypeParameterDefault(int i) { + result = union.getGenericParamList().getTypeParam(i).getDefaultType() + } + + override string toString() { result = union.getName().getText() } + + override Location getLocation() { result = union.getLocation() } +} + /** * An array type. * @@ -374,6 +403,33 @@ class SliceType extends Type, TSliceType { override Location getLocation() { result instanceof EmptyLocation } } +class NeverType extends Type, TNeverType { + override StructField getStructField(string name) { none() } + + override TupleField getTupleField(int i) { none() } + + override TypeParameter getPositionalTypeParameter(int i) { none() } + + override string toString() { result = "!" } + + override Location getLocation() { result instanceof EmptyLocation } +} + +class PtrType extends Type, TPtrType { + override StructField getStructField(string name) { none() } + + override TupleField getTupleField(int i) { none() } + + override TypeParameter getPositionalTypeParameter(int i) { + i = 0 and + result = TPtrTypeParameter() + } + + override string toString() { result = "*" } + + override Location getLocation() { result instanceof EmptyLocation } +} + /** A type parameter. */ abstract class TypeParameter extends Type { override StructField getStructField(string name) { none() } @@ -529,6 +585,12 @@ class SliceTypeParameter extends TypeParameter, TSliceTypeParameter { override Location getLocation() { result instanceof EmptyLocation } } +class PtrTypeParameter extends TypeParameter, TPtrTypeParameter { + override string toString() { result = "*T" } + + override Location getLocation() { result instanceof EmptyLocation } +} + /** * The implicit `Self` type parameter of a trait, that refers to the * implementing type of the trait. diff --git a/rust/ql/lib/codeql/rust/internal/TypeInference.qll b/rust/ql/lib/codeql/rust/internal/TypeInference.qll index 16c0b30332e..2d204469d32 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeInference.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeInference.qll @@ -99,6 +99,11 @@ private module Input1 implements InputSig1 { id1 = 0 and id2 = 2 or + tp0 instanceof PtrTypeParameter and + kind = 0 and + id1 = 0 and + id2 = 3 + or kind = 1 and id1 = 0 and id2 = diff --git a/rust/ql/lib/codeql/rust/internal/TypeMention.qll b/rust/ql/lib/codeql/rust/internal/TypeMention.qll index c36e1984237..ba7f4b4659d 100644 --- a/rust/ql/lib/codeql/rust/internal/TypeMention.qll +++ b/rust/ql/lib/codeql/rust/internal/TypeMention.qll @@ -241,6 +241,8 @@ class NonAliasPathTypeMention extends PathTypeMention { else result = TTrait(trait) ) or + result = TUnion(resolved) + or result = TTypeParamTypeParameter(resolved) or result = TAssociatedTypeTypeParameter(resolved) @@ -387,3 +389,19 @@ class DynTypeBoundListMention extends TypeMention instanceof TypeBoundList { ) } } + +class NeverTypeReprMention extends TypeMention, NeverTypeRepr { + override Type resolveTypeAt(TypePath path) { result = TNeverType() and path.isEmpty() } +} + +class PtrTypeReprMention extends TypeMention instanceof PtrTypeRepr { + override Type resolveTypeAt(TypePath path) { + path.isEmpty() and + result = TPtrType() + or + exists(TypePath suffix | + result = super.getTypeRepr().(TypeMention).resolveTypeAt(suffix) and + path = TypePath::cons(TPtrTypeParameter(), suffix) + ) + } +} diff --git a/rust/ql/test/extractor-tests/macro-expansion/CONSISTENCY/TypeInferenceConsistency.expected b/rust/ql/test/extractor-tests/macro-expansion/CONSISTENCY/TypeInferenceConsistency.expected deleted file mode 100644 index 416404c2bd1..00000000000 --- a/rust/ql/test/extractor-tests/macro-expansion/CONSISTENCY/TypeInferenceConsistency.expected +++ /dev/null @@ -1,2 +0,0 @@ -illFormedTypeMention -| macro_expansion.rs:99:7:99:19 | MyDeriveUnion | diff --git a/rust/ql/test/library-tests/type-inference/type-inference.expected b/rust/ql/test/library-tests/type-inference/type-inference.expected index 1a9a6456ce8..09fbdf17a8b 100644 --- a/rust/ql/test/library-tests/type-inference/type-inference.expected +++ b/rust/ql/test/library-tests/type-inference/type-inference.expected @@ -2250,6 +2250,7 @@ inferType | main.rs:1127:43:1127:82 | MacroExpr | | main.rs:1124:15:1124:17 | Snd | | main.rs:1127:50:1127:81 | "PairNone has no second elemen... | | file://:0:0:0:0 | & | | main.rs:1127:50:1127:81 | "PairNone has no second elemen... | &T | {EXTERNAL LOCATION} | str | +| main.rs:1127:50:1127:81 | ...::panic_fmt(...) | | file://:0:0:0:0 | ! | | main.rs:1127:50:1127:81 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | main.rs:1127:50:1127:81 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | main.rs:1127:50:1127:81 | MacroExpr | | main.rs:1124:15:1124:17 | Snd | @@ -2261,6 +2262,7 @@ inferType | main.rs:1128:43:1128:81 | MacroExpr | | main.rs:1124:15:1124:17 | Snd | | main.rs:1128:50:1128:80 | "PairFst has no second element... | | file://:0:0:0:0 | & | | main.rs:1128:50:1128:80 | "PairFst has no second element... | &T | {EXTERNAL LOCATION} | str | +| main.rs:1128:50:1128:80 | ...::panic_fmt(...) | | file://:0:0:0:0 | ! | | main.rs:1128:50:1128:80 | FormatArgsExpr | | {EXTERNAL LOCATION} | Arguments | | main.rs:1128:50:1128:80 | MacroExpr | | {EXTERNAL LOCATION} | Arguments | | main.rs:1128:50:1128:80 | MacroExpr | | main.rs:1124:15:1124:17 | Snd | diff --git a/rust/ql/test/query-tests/security/CWE-696/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/query-tests/security/CWE-696/CONSISTENCY/PathResolutionConsistency.expected new file mode 100644 index 00000000000..16bbea0aba3 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-696/CONSISTENCY/PathResolutionConsistency.expected @@ -0,0 +1,3 @@ +multipleCallTargets +| test.rs:117:9:117:20 | ptr.is_null() | +| test.rs:117:9:117:21 | ptr.is_null() | diff --git a/rust/ql/test/query-tests/security/CWE-770/CONSISTENCY/PathResolutionConsistency.expected b/rust/ql/test/query-tests/security/CWE-770/CONSISTENCY/PathResolutionConsistency.expected new file mode 100644 index 00000000000..1abeb1aeb87 --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-770/CONSISTENCY/PathResolutionConsistency.expected @@ -0,0 +1,7 @@ +multipleCallTargets +| main.rs:242:44:242:78 | ... .cast() | +| main.rs:245:44:245:78 | ... .cast() | +| main.rs:248:44:248:78 | ... .cast() | +| main.rs:251:14:251:48 | ... .cast() | +| main.rs:254:14:254:48 | ... .cast() | +| main.rs:257:14:257:48 | ... .cast() | From 109b6a1d7944ea63a67707f7d3531070ceb30624 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 25 Sep 2025 11:34:34 +0200 Subject: [PATCH 125/160] ControlFlow: Split only on relevant values. --- .../codeql/controlflow/ControlFlow.qll | 306 +++++++----------- .../controlflow/codeql/controlflow/Guards.qll | 3 + 2 files changed, 128 insertions(+), 181 deletions(-) diff --git a/shared/controlflow/codeql/controlflow/ControlFlow.qll b/shared/controlflow/codeql/controlflow/ControlFlow.qll index bfb878e6756..ca0de9d4744 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlow.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlow.qll @@ -80,6 +80,9 @@ signature module InputSig; - private predicate possibleClosedRange(SourceVariable var, int low, int high) { - possibleRangeBound(var, low, false) and - possibleRangeBound(var, high, true) and - low < high - } - - private newtype TGuardValueExt = - AnyValue() or - BaseValue(GuardValue gv) { possibleValue(_, gv) } or - IntRange(int low, int high) { possibleClosedRange(_, low, high) } - - private class GuardValueExt extends TGuardValueExt { - string toString() { - result = "Any" and this = AnyValue() - or - result = this.asBase().toString() - or - exists(int low, int high | - this = IntRange(low, high) and result = "[" + low + ", " + high + "]" - ) - } - - GuardValue asBase() { this = BaseValue(result) } - } - - private class TGuardValueOrAny = AnyValue or BaseValue; - - private class GuardValueOrAny extends GuardValueExt, TGuardValueOrAny { } - - private GuardValueExt mkRange(int low, int high) { - result = IntRange(low, high) - or - low = high and - result.asBase().asIntValue() = low - } - - private GuardValueExt intersectBase1(GuardValue gv1, GuardValue gv2) { - exists(SourceVariable var | - possibleValue(var, gv1) and - possibleValue(var, gv2) - | - smaller(gv1, gv2) and result.asBase() = gv1 - or - exists(int low, int high | - gv1.isIntRange(low, false) and - gv2.isIntRange(high, true) and - result = mkRange(low, high) - ) - or - exists(int bound, boolean upper, int d | - gv1.isIntRange(bound, upper) and - gv2.getDualValue().asIntValue() = bound and - result.asBase().isIntRange(bound + d, upper) - | - upper = true and d = -1 - or - upper = false and d = 1 - ) - ) - } - - private GuardValueExt intersectBase2(GuardValueExt v1, GuardValue v2) { - result = intersectBase1(v1.asBase(), v2) - or - result = intersectBase1(v2, v1.asBase()) - } + private class GuardValueOption = GuardValueOption::Option; + /** + * Gets the best constraint of `v1` and `v2`. If both are non-singletons, + * then we arbitrarily choose `v1`. This operation approximates intersection. + */ bindingset[v1, v2] pragma[inline_late] - private GuardValueExt intersectRange(GuardValueExt v1, GuardValue v2) { - exists(int low, int high | v1 = IntRange(low, high) | - exists(int bound, boolean upper | v2.isIntRange(bound, upper) | - upper = true and result = mkRange(low, high.minimum(bound)) - or - upper = false and result = mkRange(low.maximum(bound), high) - ) - or - exists(int k | - v2.asIntValue() = k and - result.asBase() = v2 and - low <= k and - k <= high - ) - or - not v2.isIntRange(_, _) and not exists(v2.asIntValue()) and result = v1 - ) - } - - bindingset[v1, v2] - pragma[inline_late] - private GuardValueExt intersect(GuardValueExt v1, GuardValue v2) { - v1 = AnyValue() and result.asBase() = v2 - or - result = intersectBase2(v1, v2) - or - result = v1 and - v1 instanceof BaseValue and - not exists(intersectBase2(v1, v2)) - or - result = intersectRange(v1, v2) - } - - bindingset[v1, gv2] - private predicate disjointValuesExt(GuardValueExt v1, GuardValue gv2) { - disjointValues(v1.asBase(), gv2) - or - exists(int low, int high | v1 = IntRange(low, high) | - gv2.asIntValue() < low - or - high < gv2.asIntValue() - or - exists(int bound, boolean upper | gv2.isIntRange(bound, upper) | - upper = true and bound < low - or - upper = false and high < bound - ) - ) + private GuardValueOption intersect(GuardValueOption v1, GuardValue v2) { + if v2.isSingleton() + then result.asSome() = v2 + else + if v1.isNone() + then result.asSome() = v2 + else result = v1 } /** An input configuration for control flow reachability. */ @@ -558,6 +449,7 @@ module Make< * Holds if the edge from `bb1` to `bb2` implies that `def` has a value * that is considered a barrier. */ + pragma[nomagic] private predicate ssaValueBarrierEdge(SsaDefinition def, BasicBlock bb1, BasicBlock bb2) { exists(GuardValue v | ssaControlsBranchEdge(def, bb1, bb2, v) and @@ -565,6 +457,11 @@ module Make< ) } + pragma[nomagic] + private predicate phiBlock(BasicBlock bb, SourceVariable v) { + exists(SsaPhiNode phi | phi.getBasicBlock() = bb and phi.getSourceVariable() = v) + } + /** Holds if `def1` in `bb1` may step to `def2` in `bb2`. */ private predicate step(SsaDefinition def1, BasicBlock bb1, SsaDefinition def2, BasicBlock bb2) { not sinkBlock(def1, bb1, _) and @@ -577,7 +474,7 @@ module Make< ssaRelevantAtEndOfBlock(def1, bb1) and bb1.getASuccessor() = bb2 and v = def1.getSourceVariable() and - not exists(SsaPhiNode phi | phi.getBasicBlock() = bb2 and phi.getSourceVariable() = v) and + not phiBlock(bb2, v) and def1 = def2 ) or @@ -687,8 +584,8 @@ module Make< * Holds if the edge from `bb1` to `bb2` implies that `def` has the value * `gv` and that the edge is relevant for computing reachability of `src`. * - * If multiple values may be implied by this edge, then we only include the - * most precise ones. + * If multiple values may be implied by this edge, including a singleton, + * then we only include the singleton. * * The underlying variable of `t` is `var`. */ @@ -697,7 +594,11 @@ module Make< BasicBlock bb2 ) { ssaControlsBranchEdge(t, bb1, bb2, gv) and - not exists(GuardValue gv0 | ssaControlsBranchEdge(t, bb1, bb2, gv0) and smaller(gv0, gv)) and + ( + exists(GuardValue gv0 | ssaControlsBranchEdge(t, bb1, bb2, gv0) and gv0.isSingleton()) + implies + gv.isSingleton() + ) and pathEdge(src, bb1, bb2) and t.getSourceVariable() = var } @@ -711,18 +612,36 @@ module Make< exists(BasicBlock pred | pathEdge(src, pred, entry) and entry.strictlyDominates(pred)) } + /** + * Gets either `gv` or its dual value. This is intended as a mostly unique + * representation of the set of values `gv` and `gv.getDualValue()`. + */ + private GuardValue getPrimary(GuardValue gv) { + exists(GuardValue dual | dual = gv.getDualValue() | + if dual.isSingleton() then result = dual else result = gv + ) + } + /** * Holds if precision may be improved by splitting control flow on the * value of `var` during the reachability computation of `src`. + * + * The `condgv`/`condgv.getDualValue()` separation of the values of `var` + * determines whether a possibly relevant edge may be taken or not. */ - private predicate relevantSplit(SourceVariable src, SourceVariable var) { + private predicate relevantSplit(SourceVariable src, SourceVariable var, GuardValue condgv) { // `var` may be a relevant split if we encounter 2+ conditional edges // that imply information about `var`. - 2 <= strictcount(BasicBlock bb1 | ssaControlsPathEdge(src, _, var, _, bb1, _)) + exists(GuardValue gv | + ssaControlsPathEdge(src, _, var, gv, _, _) and + condgv = getPrimary(gv) and + 2 <= strictcount(BasicBlock bb1 | ssaControlsPathEdge(src, _, var, _, bb1, _)) + ) or // Or if we encounter a conditional edge that imply a value that's // incompatible with an initial or later assigned value. exists(GuardValue gv1, GuardValue gv2, BasicBlock bb | + condgv = getPrimary(gv1) and ssaControlsPathEdge(src, _, var, gv1, _, _) and initSsaValue(var, bb, _, gv2) and disjointValues(gv1, gv2) and @@ -731,8 +650,11 @@ module Make< or // Or if we encounter a conditional edge in a loop that imply a value for // `var` that may be unchanged from one iteration to the next. - exists(SsaDefinition def, BasicBlock bb1, BasicBlock bb2, BasicBlock loopEntry | - ssaControlsPathEdge(src, def, var, _, bb1, bb2) and + exists( + SsaDefinition def, BasicBlock bb1, BasicBlock bb2, BasicBlock loopEntry, GuardValue gv + | + ssaControlsPathEdge(src, def, var, gv, bb1, bb2) and + condgv = getPrimary(gv) and loopEntryBlock(src, loopEntry) and loopEntry.strictlyDominates(bb1) and bb2.getASuccessor*() = loopEntry @@ -755,6 +677,18 @@ module Make< def = max(SsaDefinition d, int i | d.definesAt(var, bb, i) | d order by i) } + /** + * Holds if `gv` is relatable to the `condgv`/`condgv.getDualValue()` pair + * in the sense that a conditional branch based on `condgv` may be + * determined by `gv`. + */ + bindingset[gv, condgv] + pragma[inline_late] + private predicate relatable(GuardValue gv, GuardValue condgv) { + disjointValues(gv, condgv) or + disjointValues(gv, condgv.getDualValue()) + } + /** * Holds if `bb1` to `bb2` is a relevant edge for computing reachability of * `src`, and `var` is a relevant splitting variable that gets (re-)defined @@ -763,17 +697,20 @@ module Make< * `val` is the best known value for `t` in `bb2`. */ private predicate stepSsaValueRedef( - SourceVariable src, BasicBlock bb1, BasicBlock bb2, SourceVariable var, SsaDefinition t, - GuardValueOrAny val + SourceVariable src, BasicBlock bb1, BasicBlock bb2, SourceVariable var, GuardValue condgv, + SsaDefinition t, GuardValueOption val ) { pathEdge(src, bb1, bb2) and - relevantSplit(src, var) and + relevantSplit(src, var, condgv) and lastDefInBlock(var, t, bb2) and not t instanceof SsaPhiNode and ( - ssaHasValue(t, val.asBase()) + exists(GuardValue gv | + ssaHasValue(t, gv) and + if relatable(gv, condgv) then val.asSome() = gv else val.isNone() + ) or - not ssaHasValue(t, _) and val = AnyValue() + not ssaHasValue(t, _) and val.isNone() ) } @@ -786,18 +723,21 @@ module Make< * `val` is the best value for `t1`/`t2` implied by taking this edge. */ private predicate stepSsaValuePhi( - SourceVariable src, BasicBlock bb1, BasicBlock bb2, SourceVariable var, SsaDefinition t1, - SsaDefinition t2, GuardValueOrAny val + SourceVariable src, BasicBlock bb1, BasicBlock bb2, SourceVariable var, GuardValue condgv, + SsaDefinition t1, SsaDefinition t2, GuardValueOption val ) { pathEdge(src, bb1, bb2) and - relevantSplit(src, var) and + relevantSplit(src, var, condgv) and lastDefInBlock(var, t2, bb2) and t2.(SsaPhiNode).hasInputFromBlock(t1, bb1) and ( - ssaControlsPathEdge(src, t1, _, val.asBase(), bb1, bb2) + exists(GuardValue gv | + ssaControlsPathEdge(src, t1, _, gv, bb1, bb2) and + if relatable(gv, condgv) then val.asSome() = gv else val.isNone() + ) or not ssaControlsPathEdge(src, t1, _, _, bb1, bb2) and - val = AnyValue() + val.isNone() ) } @@ -810,13 +750,14 @@ module Make< * value `val`. */ private predicate stepSsaValueNoRedef( - SourceVariable src, BasicBlock bb1, BasicBlock bb2, SourceVariable var, SsaDefinition t, - GuardValue val + SourceVariable src, BasicBlock bb1, BasicBlock bb2, SourceVariable var, GuardValue condgv, + SsaDefinition t, GuardValue val ) { pathEdge(src, bb1, bb2) and - relevantSplit(src, var) and + relevantSplit(src, var, condgv) and not lastDefInBlock(var, _, bb2) and - ssaControlsPathEdge(src, t, var, val, bb1, bb2) + ssaControlsPathEdge(src, t, var, val, bb1, bb2) and + relatable(val, condgv) } /** @@ -827,64 +768,67 @@ module Make< */ private predicate sourceReachesBlockWithTrackedVar( SsaDefinition srcDef, BasicBlock srcBb, SsaDefinition def, BasicBlock bb, FinallyStack fs, - SsaDefOption tracked, GuardValueExt val, SourceVariable var + SsaDefOption tracked, GuardValueOption val, SourceVariable var, GuardValue condgv ) { sourceBlock(srcDef, srcBb, _) and def = srcDef and bb = srcBb and fs = TNil() and - relevantSplit(def.getSourceVariable(), var) and + relevantSplit(def.getSourceVariable(), var, condgv) and ( // tracking variable is not yet live not ssaLiveAtEndOfBlock(var, _, bb) and tracked.isNone() and - val = AnyValue() + val.isNone() or // tracking variable is live but without known value ssaLiveAtEndOfBlock(var, tracked.asSome(), bb) and not initSsaValue(var, bb, _, _) and - val = AnyValue() + val.isNone() or - // tracking variable has known value - initSsaValue(var, bb, tracked.asSome(), val.asBase()) + // tracking variable has known value, track it if it is relatable to condgv + exists(GuardValue gv | initSsaValue(var, bb, tracked.asSome(), gv) | + if relatable(gv, condgv) then val.asSome() = gv else val.isNone() + ) ) or exists( SourceVariable src, SsaDefinition middef, BasicBlock midbb, FinallyStack midfs, - SsaDefOption tracked0, GuardValueExt val0 + SsaDefOption tracked0, GuardValueOption val0 | - sourceReachesBlockWithTrackedVar(srcDef, srcBb, middef, midbb, midfs, tracked0, val0, var) and + sourceReachesBlockWithTrackedVar(srcDef, srcBb, middef, midbb, midfs, tracked0, val0, var, + condgv) and src = srcDef.getSourceVariable() and step(middef, midbb, def, bb) and stepFinallyStack(midbb, bb, midfs, fs) and - pathBlock(src, bb) and + pathBlock(pragma[only_bind_into](src), bb) and not exists(GuardValue gv | ssaControlsPathEdge(src, tracked0.asSome(), _, gv, midbb, bb) and - disjointValuesExt(val0, gv) + disjointValues(val0.asSome(), gv) ) | // tracking variable is redefined - stepSsaValueRedef(src, midbb, bb, var, tracked.asSome(), val) + stepSsaValueRedef(src, midbb, bb, var, condgv, tracked.asSome(), val) or - exists(GuardValueOrAny val1 | + exists(GuardValueOption val1 | // tracking variable has a phi node, and maybe value information from the edge - stepSsaValuePhi(src, midbb, bb, var, tracked0.asSome(), tracked.asSome(), val1) + stepSsaValuePhi(src, midbb, bb, var, condgv, tracked0.asSome(), tracked.asSome(), val1) | - val = val0 and val1 = AnyValue() + val = val0 and val1.isNone() or - val = intersect(val0, val1.asBase()) + val = intersect(val0, val1.asSome()) ) or exists(GuardValue val1 | // tracking variable is unchanged, and has value information from the edge - stepSsaValueNoRedef(src, midbb, bb, var, tracked0.asSome(), val1) and + stepSsaValueNoRedef(src, midbb, bb, var, condgv, tracked0.asSome(), val1) and tracked = tracked0 and val = intersect(val0, val1) ) or // tracking variable is unchanged, and has no value information from the edge not lastDefInBlock(var, _, bb) and - not stepSsaValueNoRedef(src, midbb, bb, var, tracked0.asSome(), _) and + not stepSsaValueNoRedef(src, midbb, bb, var, condgv, tracked0.asSome(), _) and tracked = tracked0 and val = val0 ) @@ -903,8 +847,8 @@ module Make< sourceReachesBlock(srcDef, srcBb, sinkDef, sinkBb, _) and sinkBlock(sinkDef, sinkBb, sink) and srcVar = srcDef.getSourceVariable() and - forall(SourceVariable t | relevantSplit(srcVar, t) | - sourceReachesBlockWithTrackedVar(srcDef, srcBb, sinkDef, sinkBb, _, _, _, t) + forall(SourceVariable t, GuardValue condgv | relevantSplit(srcVar, t, condgv) | + sourceReachesBlockWithTrackedVar(srcDef, srcBb, sinkDef, sinkBb, _, _, _, t, condgv) ) ) } @@ -920,8 +864,8 @@ module Make< sourceBlock(srcDef, srcBb, src) and sourceEscapesSink(srcDef, srcBb, escDef, escBb) and srcVar = srcDef.getSourceVariable() and - forall(SourceVariable t | relevantSplit(srcVar, t) | - sourceReachesBlockWithTrackedVar(srcDef, srcBb, escDef, escBb, _, _, _, t) + forall(SourceVariable t, GuardValue condgv | relevantSplit(srcVar, t, condgv) | + sourceReachesBlockWithTrackedVar(srcDef, srcBb, escDef, escBb, _, _, _, t, condgv) ) ) } diff --git a/shared/controlflow/codeql/controlflow/Guards.qll b/shared/controlflow/codeql/controlflow/Guards.qll index 0bbfb29e4e6..668fb60655c 100644 --- a/shared/controlflow/codeql/controlflow/Guards.qll +++ b/shared/controlflow/codeql/controlflow/Guards.qll @@ -259,6 +259,9 @@ module Make< ) } + /** Holds if this value represents a single concrete value. */ + predicate isSingleton() { this = TValue(_, true) } + /** Holds if this value represents `null`. */ predicate isNullValue() { this.isNullness(true) } From b22227d0f4b084d41eb7a026975a8562f926fd2c Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 25 Sep 2025 13:30:57 +0100 Subject: [PATCH 126/160] Add .orig files to .gitignore. --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index fe4a5de9672..4dbe45b8d28 100644 --- a/.gitignore +++ b/.gitignore @@ -76,3 +76,6 @@ node_modules/ # some upgrade/downgrade checks create these files **/upgrades/*/*.dbscheme.stats **/downgrades/*/*.dbscheme.stats + +# Mergetool files +*.orig From e9cccb46c067ffb046218711f693c90fc51d5beb Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 25 Sep 2025 15:19:40 +0100 Subject: [PATCH 127/160] Go: mistyped-exponentiation: notice constants with likely-bitmask values --- go/ql/src/InconsistentCode/MistypedExponentiation.ql | 6 +++++- .../InconsistentCode/MistypedExponentiation/main.go | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/go/ql/src/InconsistentCode/MistypedExponentiation.ql b/go/ql/src/InconsistentCode/MistypedExponentiation.ql index b445a713ce6..91fb63d319c 100644 --- a/go/ql/src/InconsistentCode/MistypedExponentiation.ql +++ b/go/ql/src/InconsistentCode/MistypedExponentiation.ql @@ -13,12 +13,16 @@ import go +private Expr getConstantInitialiser(Expr e) { + exists(DeclaredConstant c | e = c.getAReference() | result = c.getInit()) +} + /** Holds if `e` is not 0 and is either an octal or hexadecimal literal, or the number one. */ predicate maybeXorBitPattern(Expr e) { // 0 makes no sense as an xor bit pattern not e.getNumericValue() = 0 and // include octal and hex literals - e.(IntLit).getText().matches("0%") + [e, getConstantInitialiser(e)].(IntLit).getText().matches("0%") or e.getNumericValue() = 1 } diff --git a/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/main.go b/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/main.go index 2449ccdac62..b8b4be44847 100644 --- a/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/main.go +++ b/go/ql/test/query-tests/InconsistentCode/MistypedExponentiation/main.go @@ -22,6 +22,13 @@ func main() { mask := (((1 << 10) - 1) ^ 7) // OK + const ( + c1 = 0x1234 + c2 = 0x5678 + ) + + fmt.Println(c1 ^ c2) // OK + // This is not ok, but isn't detected because the multiplication binds tighter // than the xor operator and so the query doesn't see a constant on the left // hand side of ^. From 9e7a5214f31abbede39a6ba776664e61dea405be Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 25 Sep 2025 15:40:26 +0100 Subject: [PATCH 128/160] Change note --- go/ql/src/change-notes/2025-09-25-exponentiation-constants.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 go/ql/src/change-notes/2025-09-25-exponentiation-constants.md diff --git a/go/ql/src/change-notes/2025-09-25-exponentiation-constants.md b/go/ql/src/change-notes/2025-09-25-exponentiation-constants.md new file mode 100644 index 00000000000..cb6c5e43346 --- /dev/null +++ b/go/ql/src/change-notes/2025-09-25-exponentiation-constants.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `go/mistyped-exponentiation` now recognises constants whose initialisers are hex or octal constants, making them likely targets of the `^` bitwise-xor operator. From 656a7bc37862ffeb31eadacdd65f071ea8130e42 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Thu, 25 Sep 2025 17:25:03 +0100 Subject: [PATCH 129/160] Rust: Add missing Cargo.lock files to query tests. --- .../test/query-tests/diagnostics/Cargo.lock | 7 + .../query-tests/security/CWE-798/Cargo.lock | 726 ++++++++++++++++++ 2 files changed, 733 insertions(+) create mode 100644 rust/ql/test/query-tests/diagnostics/Cargo.lock create mode 100644 rust/ql/test/query-tests/security/CWE-798/Cargo.lock diff --git a/rust/ql/test/query-tests/diagnostics/Cargo.lock b/rust/ql/test/query-tests/diagnostics/Cargo.lock new file mode 100644 index 00000000000..b9856cfaf77 --- /dev/null +++ b/rust/ql/test/query-tests/diagnostics/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "test" +version = "0.0.1" diff --git a/rust/ql/test/query-tests/security/CWE-798/Cargo.lock b/rust/ql/test/query-tests/security/CWE-798/Cargo.lock new file mode 100644 index 00000000000..6d0fce1423e --- /dev/null +++ b/rust/ql/test/query-tests/security/CWE-798/Cargo.lock @@ -0,0 +1,726 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aes-gcm-siv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "polyval", + "subtle", + "zeroize", +] + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "biscotti" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddb6f28a3d15d18cace7a8010282a4d9cee1452dcd33f5861c173b4a31095b79" +dependencies = [ + "aes-gcm-siv", + "anyhow", + "base64", + "hkdf", + "hmac", + "jiff", + "percent-encoding", + "rand 0.9.2", + "serde", + "sha2", + "subtle", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cfb-mode" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738b8d467867f80a71351933f70461f5b56f24d5c93e0cf216e59229c968d330" +dependencies = [ + "cipher", +] + +[[package]] +name = "cfg-if" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "aes-gcm", + "base64", + "hmac", + "rand 0.8.5", + "sha2", + "subtle", + "time", + "version_check", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "deranged" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.7+wasi-0.2.4", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jiff" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +dependencies = [ + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", + "windows-sys", +] + +[[package]] +name = "jiff-static" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "libc" +version = "0.2.176" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro2" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rabbit" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "931a21d28d73d260f6743712e0f04292413fc6d004bb278bb9022302221a05d5" +dependencies = [ + "cipher", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "serde" +version = "1.0.226" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dca6411025b24b60bfa7ec1fe1f8e710ac09782dca409ee8237ba74b51295fd" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.226" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba2ba63999edb9dac981fb34b3e5c0d111a69b0924e253ed29d83f7c99e966a4" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.226" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8db53ae22f34573731bafa1db20f04027b2d25e02d8205921b569171699cdb33" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "test" +version = "0.0.1" +dependencies = [ + "aes", + "aes-gcm", + "base64", + "biscotti", + "cfb-mode", + "cipher", + "cookie", + "getrandom 0.2.16", + "getrandom 0.3.3", + "rabbit", +] + +[[package]] +name = "time" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "unicode-ident" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "zerocopy" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" From ff554055a6c24bb2e2f428f6f9d8c51851e201a2 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 08:43:35 +0100 Subject: [PATCH 130/160] Rust: Correct 'from' model to taint. --- rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml index a92ed8fc235..b0b63fa0201 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-core.model.yml @@ -12,7 +12,7 @@ extensions: - ["::into", "Argument[self].Element", "ReturnValue.Element", "taint", "manual"] - ["::into", "Argument[self].Reference.Element", "ReturnValue.Element", "taint", "manual"] # From - - ["<_ as core::convert::From>::from", "Argument[0]", "ReturnValue", "value", "manual"] + - ["<_ as core::convert::From>::from", "Argument[0]", "ReturnValue", "taint", "manual"] # Iterator - ["::iter", "Argument[self].Element", "ReturnValue.Element", "value", "manual"] - ["::iter", "Argument[self].Element", "ReturnValue.Element", "value", "manual"] From 7a74efcc824783ab1e40fe4c29a2f9885e734f8c Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 26 Sep 2025 09:57:13 +0200 Subject: [PATCH 131/160] Update rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll Co-authored-by: Simon Friis Vindum --- rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll index 712e39e6685..40680f3edc9 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/UnionImpl.qll @@ -21,7 +21,7 @@ module Impl { * ``` */ class Union extends Generated::Union { - /** Gets the record field named `name`, if any. */ + /** Gets the struct field named `name`, if any. */ pragma[nomagic] StructField getStructField(string name) { result = this.getStructFieldList().getAField() and From 74a350a4325c597bc3c9e774e2477ad9c9b2ba18 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 09:41:59 +0100 Subject: [PATCH 132/160] Rust: Effect on tests. --- .../strings/inline-taint-flow.expected | 2 +- .../library-tests/dataflow/strings/main.rs | 2 +- .../security/CWE-022/TaintedPath.expected | 2 +- .../HardcodedCryptographicValue.expected | 34 +++++++------------ 4 files changed, 15 insertions(+), 25 deletions(-) diff --git a/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected b/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected index ea6e06ef616..e6241590137 100644 --- a/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected +++ b/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected @@ -1,5 +1,5 @@ models -| 1 | Summary: <_ as core::convert::From>::from; Argument[0]; ReturnValue; value | +| 1 | Summary: <_ as core::convert::From>::from; Argument[0]; ReturnValue; taint | | 2 | Summary: ::from; Argument[0].Reference; ReturnValue; value | | 3 | Summary: ::add; Argument[self]; ReturnValue; value | | 4 | Summary: ::as_str; Argument[self]; ReturnValue; value | diff --git a/rust/ql/test/library-tests/dataflow/strings/main.rs b/rust/ql/test/library-tests/dataflow/strings/main.rs index 772a45f1993..ca9db9a9026 100644 --- a/rust/ql/test/library-tests/dataflow/strings/main.rs +++ b/rust/ql/test/library-tests/dataflow/strings/main.rs @@ -50,7 +50,7 @@ fn string_add_reference() { fn string_from() { let s1 = source_slice(36); let s2 = String::from(s1); - sink(s2); // $ hasValueFlow=36 + sink(s2); // $ hasTaintFlow=36 } fn string_to_string() { diff --git a/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected b/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected index 8e2a7d13dda..a1f9b448ac7 100644 --- a/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected +++ b/rust/ql/test/query-tests/security/CWE-022/TaintedPath.expected @@ -123,7 +123,7 @@ models | 6 | Sink: std::fs::read_to_string; Argument[0]; path-injection | | 7 | Source: std::env::args; ReturnValue.Element; commandargs | | 8 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value | -| 9 | Summary: <_ as core::convert::From>::from; Argument[0]; ReturnValue; value | +| 9 | Summary: <_ as core::convert::From>::from; Argument[0]; ReturnValue; taint | | 10 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Element; ReturnValue.Field[core::option::Option::Some(0)]; value | | 11 | Summary: ::unwrap; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | | 12 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | diff --git a/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected b/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected index d16be723b8f..0c423a29a6d 100644 --- a/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected +++ b/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected @@ -14,7 +14,6 @@ | test_cipher.rs:73:20:73:22 | 0u8 | test_cipher.rs:73:20:73:22 | 0u8 | test_cipher.rs:74:23:74:44 | ...::new_from_slice | This hard-coded value is used as $@. | test_cipher.rs:74:23:74:44 | ...::new_from_slice | a key | | test_cookie.rs:17:29:17:29 | 0 | test_cookie.rs:17:29:17:29 | 0 | test_cookie.rs:18:16:18:24 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:18:16:18:24 | ...::from | a key | | test_cookie.rs:21:29:21:29 | 0 | test_cookie.rs:21:29:21:29 | 0 | test_cookie.rs:22:16:22:24 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:22:16:22:24 | ...::from | a key | -| test_cookie.rs:38:29:38:31 | 0u8 | test_cookie.rs:38:29:38:31 | 0u8 | test_cookie.rs:42:14:42:32 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:42:14:42:32 | ...::from | a key | | test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:53:14:53:32 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:53:14:53:32 | ...::from | a key | edges | test_cipher.rs:18:9:18:14 | const1 [&ref, element] | test_cipher.rs:19:73:19:78 | const1 [&ref, element] | provenance | | @@ -23,39 +22,39 @@ edges | test_cipher.rs:18:30:18:32 | 0u8 | test_cipher.rs:18:29:18:36 | [0u8; 16] [element] | provenance | | | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | test_cipher.rs:19:30:19:47 | ...::new | provenance | MaD:3 Sink:MaD:3 Sink:MaD:3 | | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | test_cipher.rs:19:30:19:47 | ...::new | provenance | MaD:5 Sink:MaD:5 Sink:MaD:5 | -| test_cipher.rs:19:73:19:78 | const1 [&ref, element] | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | provenance | MaD:10 | +| test_cipher.rs:19:73:19:78 | const1 [&ref, element] | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | | test_cipher.rs:25:9:25:14 | const4 [&ref, element] | test_cipher.rs:26:66:26:71 | const4 [&ref, element] | provenance | | | test_cipher.rs:25:28:25:36 | &... [&ref, element] | test_cipher.rs:25:9:25:14 | const4 [&ref, element] | provenance | | | test_cipher.rs:25:29:25:36 | [0u8; 16] [element] | test_cipher.rs:25:28:25:36 | &... [&ref, element] | provenance | | | test_cipher.rs:25:30:25:32 | 0u8 | test_cipher.rs:25:29:25:36 | [0u8; 16] [element] | provenance | | | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | test_cipher.rs:26:30:26:40 | ...::new | provenance | MaD:3 Sink:MaD:3 Sink:MaD:3 | | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | test_cipher.rs:26:30:26:40 | ...::new | provenance | MaD:5 Sink:MaD:5 Sink:MaD:5 | -| test_cipher.rs:26:66:26:71 | const4 [&ref, element] | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | provenance | MaD:10 | +| test_cipher.rs:26:66:26:71 | const4 [&ref, element] | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | | test_cipher.rs:29:9:29:14 | const5 [&ref, element] | test_cipher.rs:30:95:30:100 | const5 [&ref, element] | provenance | | | test_cipher.rs:29:28:29:36 | &... [&ref, element] | test_cipher.rs:29:9:29:14 | const5 [&ref, element] | provenance | | | test_cipher.rs:29:29:29:36 | [0u8; 16] [element] | test_cipher.rs:29:28:29:36 | &... [&ref, element] | provenance | | | test_cipher.rs:29:30:29:32 | 0u8 | test_cipher.rs:29:29:29:36 | [0u8; 16] [element] | provenance | | | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | test_cipher.rs:30:30:30:40 | ...::new | provenance | MaD:4 Sink:MaD:4 Sink:MaD:4 | | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | test_cipher.rs:30:30:30:40 | ...::new | provenance | MaD:6 Sink:MaD:6 Sink:MaD:6 | -| test_cipher.rs:30:95:30:100 | const5 [&ref, element] | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | provenance | MaD:10 | +| test_cipher.rs:30:95:30:100 | const5 [&ref, element] | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | | test_cipher.rs:37:9:37:14 | const7 | test_cipher.rs:38:74:38:79 | const7 | provenance | | | test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:37:9:37:14 | const7 | provenance | | | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | test_cipher.rs:38:30:38:47 | ...::new | provenance | MaD:3 Sink:MaD:3 | | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | test_cipher.rs:38:30:38:47 | ...::new | provenance | MaD:5 Sink:MaD:5 | -| test_cipher.rs:38:73:38:79 | &const7 [&ref] | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | provenance | MaD:10 | +| test_cipher.rs:38:73:38:79 | &const7 [&ref] | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | provenance | MaD:9 | | test_cipher.rs:38:74:38:79 | const7 | test_cipher.rs:38:73:38:79 | &const7 [&ref] | provenance | | | test_cipher.rs:41:9:41:14 | const8 [&ref] | test_cipher.rs:42:73:42:78 | const8 [&ref] | provenance | | | test_cipher.rs:41:28:41:76 | &... [&ref] | test_cipher.rs:41:9:41:14 | const8 [&ref] | provenance | | | test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:41:28:41:76 | &... [&ref] | provenance | | | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | test_cipher.rs:42:30:42:47 | ...::new | provenance | MaD:3 Sink:MaD:3 | | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | test_cipher.rs:42:30:42:47 | ...::new | provenance | MaD:5 Sink:MaD:5 | -| test_cipher.rs:42:73:42:78 | const8 [&ref] | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | provenance | MaD:10 | +| test_cipher.rs:42:73:42:78 | const8 [&ref] | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | provenance | MaD:9 | | test_cipher.rs:50:9:50:15 | const10 [element] | test_cipher.rs:51:75:51:81 | const10 [element] | provenance | | | test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:50:37:50:54 | ...::zeroed(...) [element] | provenance | Src:MaD:8 | | test_cipher.rs:50:37:50:54 | ...::zeroed(...) [element] | test_cipher.rs:50:9:50:15 | const10 [element] | provenance | | | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | test_cipher.rs:51:31:51:48 | ...::new | provenance | MaD:3 Sink:MaD:3 Sink:MaD:3 | | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | test_cipher.rs:51:31:51:48 | ...::new | provenance | MaD:5 Sink:MaD:5 Sink:MaD:5 | -| test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | provenance | MaD:10 | +| test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | | test_cipher.rs:51:75:51:81 | const10 [element] | test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | provenance | | | test_cipher.rs:73:9:73:14 | const2 [&ref, element] | test_cipher.rs:74:46:74:51 | const2 [&ref, element] | provenance | | | test_cipher.rs:73:18:73:26 | &... [&ref, element] | test_cipher.rs:73:9:73:14 | const2 [&ref, element] | provenance | | @@ -72,13 +71,8 @@ edges | test_cookie.rs:21:29:21:29 | 0 | test_cookie.rs:21:28:21:34 | [0; 64] [element] | provenance | | | test_cookie.rs:22:26:22:32 | &array2 [&ref, element] | test_cookie.rs:22:16:22:24 | ...::from | provenance | MaD:7 Sink:MaD:7 | | test_cookie.rs:22:27:22:32 | array2 [element] | test_cookie.rs:22:26:22:32 | &array2 [&ref, element] | provenance | | -| test_cookie.rs:38:9:38:14 | array2 [element] | test_cookie.rs:42:34:42:39 | array2 [element] | provenance | | -| test_cookie.rs:38:18:38:37 | ...::from(...) [element] | test_cookie.rs:38:9:38:14 | array2 [element] | provenance | | -| test_cookie.rs:38:28:38:36 | [0u8; 64] [element] | test_cookie.rs:38:18:38:37 | ...::from(...) [element] | provenance | MaD:9 | -| test_cookie.rs:38:29:38:31 | 0u8 | test_cookie.rs:38:28:38:36 | [0u8; 64] [element] | provenance | | -| test_cookie.rs:42:34:42:39 | array2 [element] | test_cookie.rs:42:14:42:32 | ...::from | provenance | MaD:2 Sink:MaD:2 | | test_cookie.rs:49:9:49:14 | array3 [element] | test_cookie.rs:53:34:53:39 | array3 [element] | provenance | | -| test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | provenance | MaD:11 | +| test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | provenance | MaD:10 | | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | test_cookie.rs:49:9:49:14 | array3 [element] | provenance | | | test_cookie.rs:53:34:53:39 | array3 [element] | test_cookie.rs:53:14:53:32 | ...::from | provenance | MaD:2 Sink:MaD:2 | models @@ -90,9 +84,8 @@ models | 6 | Sink: ::new; Argument[1]; credentials-iv | | 7 | Sink: ::from; Argument[0].Reference; credentials-key | | 8 | Source: core::mem::zeroed; ReturnValue.Element; constant-source | -| 9 | Summary: <_ as core::convert::From>::from; Argument[0]; ReturnValue; value | -| 10 | Summary: ::from_slice; Argument[0].Reference; ReturnValue.Reference; value | -| 11 | Summary: alloc::vec::from_elem; Argument[0]; ReturnValue.Element; value | +| 9 | Summary: ::from_slice; Argument[0].Reference; ReturnValue.Reference; value | +| 10 | Summary: alloc::vec::from_elem; Argument[0]; ReturnValue.Element; value | nodes | test_cipher.rs:18:9:18:14 | const1 [&ref, element] | semmle.label | const1 [&ref, element] | | test_cipher.rs:18:28:18:36 | &... [&ref, element] | semmle.label | &... [&ref, element] | @@ -158,15 +151,12 @@ nodes | test_cookie.rs:22:16:22:24 | ...::from | semmle.label | ...::from | | test_cookie.rs:22:26:22:32 | &array2 [&ref, element] | semmle.label | &array2 [&ref, element] | | test_cookie.rs:22:27:22:32 | array2 [element] | semmle.label | array2 [element] | -| test_cookie.rs:38:9:38:14 | array2 [element] | semmle.label | array2 [element] | -| test_cookie.rs:38:18:38:37 | ...::from(...) [element] | semmle.label | ...::from(...) [element] | -| test_cookie.rs:38:28:38:36 | [0u8; 64] [element] | semmle.label | [0u8; 64] [element] | -| test_cookie.rs:38:29:38:31 | 0u8 | semmle.label | 0u8 | -| test_cookie.rs:42:14:42:32 | ...::from | semmle.label | ...::from | -| test_cookie.rs:42:34:42:39 | array2 [element] | semmle.label | array2 [element] | | test_cookie.rs:49:9:49:14 | array3 [element] | semmle.label | array3 [element] | | test_cookie.rs:49:23:49:25 | 0u8 | semmle.label | 0u8 | | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | semmle.label | ...::from_elem(...) [element] | | test_cookie.rs:53:14:53:32 | ...::from | semmle.label | ...::from | | test_cookie.rs:53:34:53:39 | array3 [element] | semmle.label | array3 [element] | subpaths +testFailures +| test_cookie.rs:38:40:38:86 | //... | Missing result: Alert[rust/hard-coded-cryptographic-value] | +| test_cookie.rs:42:43:42:51 | //... | Missing result: Sink | From 3a03bb5a0bce190b7cd60df209bf96aa63556c30 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 10:03:38 +0100 Subject: [PATCH 133/160] Rust: Repair rust/hard-coded-cryptographic-value, which had an unintentional dependence on the taint flow. --- .../HardcodedCryptographicValueExtensions.qll | 8 +- .../HardcodedCryptographicValue.expected | 170 +++++++++--------- 2 files changed, 89 insertions(+), 89 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll b/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll index 785a7f815bc..bc487e42ef0 100644 --- a/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/HardcodedCryptographicValueExtensions.qll @@ -69,11 +69,15 @@ module HardcodedCryptographicValue { /** * An array initialized from a list of literals, considered as a single flow source. For example: * ``` - * `[0, 0, 0, 0]` + * [0, 0, 0, 0] + * [0; 10] * ``` */ private class ArrayListSource extends Source { - ArrayListSource() { this.asExpr().getExpr().(ArrayListExpr).getExpr(_) instanceof LiteralExpr } + ArrayListSource() { + this.asExpr().getExpr().(ArrayListExpr).getExpr(_) instanceof LiteralExpr or + this.asExpr().getExpr().(ArrayRepeatExpr).getRepeatOperand() instanceof LiteralExpr + } } /** diff --git a/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected b/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected index 0c423a29a6d..09e2ebdef34 100644 --- a/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected +++ b/rust/ql/test/query-tests/security/CWE-798/HardcodedCryptographicValue.expected @@ -1,78 +1,77 @@ #select -| test_cipher.rs:18:30:18:32 | 0u8 | test_cipher.rs:18:30:18:32 | 0u8 | test_cipher.rs:19:30:19:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:19:30:19:47 | ...::new | a key | -| test_cipher.rs:18:30:18:32 | 0u8 | test_cipher.rs:18:30:18:32 | 0u8 | test_cipher.rs:19:30:19:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:19:30:19:47 | ...::new | a key | -| test_cipher.rs:25:30:25:32 | 0u8 | test_cipher.rs:25:30:25:32 | 0u8 | test_cipher.rs:26:30:26:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:26:30:26:40 | ...::new | a key | -| test_cipher.rs:25:30:25:32 | 0u8 | test_cipher.rs:25:30:25:32 | 0u8 | test_cipher.rs:26:30:26:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:26:30:26:40 | ...::new | a key | -| test_cipher.rs:29:30:29:32 | 0u8 | test_cipher.rs:29:30:29:32 | 0u8 | test_cipher.rs:30:30:30:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:30:30:30:40 | ...::new | an initialization vector | -| test_cipher.rs:29:30:29:32 | 0u8 | test_cipher.rs:29:30:29:32 | 0u8 | test_cipher.rs:30:30:30:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:30:30:30:40 | ...::new | an initialization vector | +| test_cipher.rs:18:29:18:36 | [0u8; 16] | test_cipher.rs:18:29:18:36 | [0u8; 16] | test_cipher.rs:19:30:19:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:19:30:19:47 | ...::new | a key | +| test_cipher.rs:18:29:18:36 | [0u8; 16] | test_cipher.rs:18:29:18:36 | [0u8; 16] | test_cipher.rs:19:30:19:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:19:30:19:47 | ...::new | a key | +| test_cipher.rs:25:29:25:36 | [0u8; 16] | test_cipher.rs:25:29:25:36 | [0u8; 16] | test_cipher.rs:26:30:26:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:26:30:26:40 | ...::new | a key | +| test_cipher.rs:25:29:25:36 | [0u8; 16] | test_cipher.rs:25:29:25:36 | [0u8; 16] | test_cipher.rs:26:30:26:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:26:30:26:40 | ...::new | a key | +| test_cipher.rs:29:29:29:36 | [0u8; 16] | test_cipher.rs:29:29:29:36 | [0u8; 16] | test_cipher.rs:30:30:30:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:30:30:30:40 | ...::new | an initialization vector | +| test_cipher.rs:29:29:29:36 | [0u8; 16] | test_cipher.rs:29:29:29:36 | [0u8; 16] | test_cipher.rs:30:30:30:40 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:30:30:30:40 | ...::new | an initialization vector | | test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:38:30:38:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:38:30:38:47 | ...::new | a key | | test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:38:30:38:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:38:30:38:47 | ...::new | a key | | test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:42:30:42:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:42:30:42:47 | ...::new | a key | | test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:42:30:42:47 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:42:30:42:47 | ...::new | a key | | test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:51:31:51:48 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:51:31:51:48 | ...::new | a key | | test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:51:31:51:48 | ...::new | This hard-coded value is used as $@. | test_cipher.rs:51:31:51:48 | ...::new | a key | -| test_cipher.rs:73:20:73:22 | 0u8 | test_cipher.rs:73:20:73:22 | 0u8 | test_cipher.rs:74:23:74:44 | ...::new_from_slice | This hard-coded value is used as $@. | test_cipher.rs:74:23:74:44 | ...::new_from_slice | a key | -| test_cookie.rs:17:29:17:29 | 0 | test_cookie.rs:17:29:17:29 | 0 | test_cookie.rs:18:16:18:24 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:18:16:18:24 | ...::from | a key | -| test_cookie.rs:21:29:21:29 | 0 | test_cookie.rs:21:29:21:29 | 0 | test_cookie.rs:22:16:22:24 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:22:16:22:24 | ...::from | a key | +| test_cipher.rs:73:19:73:26 | [0u8; 32] | test_cipher.rs:73:19:73:26 | [0u8; 32] | test_cipher.rs:74:23:74:44 | ...::new_from_slice | This hard-coded value is used as $@. | test_cipher.rs:74:23:74:44 | ...::new_from_slice | a key | +| test_cookie.rs:17:28:17:34 | [0; 64] | test_cookie.rs:17:28:17:34 | [0; 64] | test_cookie.rs:18:16:18:24 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:18:16:18:24 | ...::from | a key | +| test_cookie.rs:21:28:21:34 | [0; 64] | test_cookie.rs:21:28:21:34 | [0; 64] | test_cookie.rs:22:16:22:24 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:22:16:22:24 | ...::from | a key | +| test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:42:14:42:32 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:42:14:42:32 | ...::from | a key | | test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:53:14:53:32 | ...::from | This hard-coded value is used as $@. | test_cookie.rs:53:14:53:32 | ...::from | a key | edges -| test_cipher.rs:18:9:18:14 | const1 [&ref, element] | test_cipher.rs:19:73:19:78 | const1 [&ref, element] | provenance | | -| test_cipher.rs:18:28:18:36 | &... [&ref, element] | test_cipher.rs:18:9:18:14 | const1 [&ref, element] | provenance | | -| test_cipher.rs:18:29:18:36 | [0u8; 16] [element] | test_cipher.rs:18:28:18:36 | &... [&ref, element] | provenance | | -| test_cipher.rs:18:30:18:32 | 0u8 | test_cipher.rs:18:29:18:36 | [0u8; 16] [element] | provenance | | -| test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | test_cipher.rs:19:30:19:47 | ...::new | provenance | MaD:3 Sink:MaD:3 Sink:MaD:3 | -| test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | test_cipher.rs:19:30:19:47 | ...::new | provenance | MaD:5 Sink:MaD:5 Sink:MaD:5 | -| test_cipher.rs:19:73:19:78 | const1 [&ref, element] | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | -| test_cipher.rs:25:9:25:14 | const4 [&ref, element] | test_cipher.rs:26:66:26:71 | const4 [&ref, element] | provenance | | -| test_cipher.rs:25:28:25:36 | &... [&ref, element] | test_cipher.rs:25:9:25:14 | const4 [&ref, element] | provenance | | -| test_cipher.rs:25:29:25:36 | [0u8; 16] [element] | test_cipher.rs:25:28:25:36 | &... [&ref, element] | provenance | | -| test_cipher.rs:25:30:25:32 | 0u8 | test_cipher.rs:25:29:25:36 | [0u8; 16] [element] | provenance | | -| test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | test_cipher.rs:26:30:26:40 | ...::new | provenance | MaD:3 Sink:MaD:3 Sink:MaD:3 | -| test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | test_cipher.rs:26:30:26:40 | ...::new | provenance | MaD:5 Sink:MaD:5 Sink:MaD:5 | -| test_cipher.rs:26:66:26:71 | const4 [&ref, element] | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | -| test_cipher.rs:29:9:29:14 | const5 [&ref, element] | test_cipher.rs:30:95:30:100 | const5 [&ref, element] | provenance | | -| test_cipher.rs:29:28:29:36 | &... [&ref, element] | test_cipher.rs:29:9:29:14 | const5 [&ref, element] | provenance | | -| test_cipher.rs:29:29:29:36 | [0u8; 16] [element] | test_cipher.rs:29:28:29:36 | &... [&ref, element] | provenance | | -| test_cipher.rs:29:30:29:32 | 0u8 | test_cipher.rs:29:29:29:36 | [0u8; 16] [element] | provenance | | -| test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | test_cipher.rs:30:30:30:40 | ...::new | provenance | MaD:4 Sink:MaD:4 Sink:MaD:4 | -| test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | test_cipher.rs:30:30:30:40 | ...::new | provenance | MaD:6 Sink:MaD:6 Sink:MaD:6 | -| test_cipher.rs:30:95:30:100 | const5 [&ref, element] | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | +| test_cipher.rs:18:9:18:14 | const1 [&ref] | test_cipher.rs:19:73:19:78 | const1 [&ref] | provenance | | +| test_cipher.rs:18:28:18:36 | &... [&ref] | test_cipher.rs:18:9:18:14 | const1 [&ref] | provenance | | +| test_cipher.rs:18:29:18:36 | [0u8; 16] | test_cipher.rs:18:28:18:36 | &... [&ref] | provenance | | +| test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref] | test_cipher.rs:19:30:19:47 | ...::new | provenance | MaD:3 Sink:MaD:3 | +| test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref] | test_cipher.rs:19:30:19:47 | ...::new | provenance | MaD:5 Sink:MaD:5 | +| test_cipher.rs:19:73:19:78 | const1 [&ref] | test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref] | provenance | MaD:10 | +| test_cipher.rs:25:9:25:14 | const4 [&ref] | test_cipher.rs:26:66:26:71 | const4 [&ref] | provenance | | +| test_cipher.rs:25:28:25:36 | &... [&ref] | test_cipher.rs:25:9:25:14 | const4 [&ref] | provenance | | +| test_cipher.rs:25:29:25:36 | [0u8; 16] | test_cipher.rs:25:28:25:36 | &... [&ref] | provenance | | +| test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref] | test_cipher.rs:26:30:26:40 | ...::new | provenance | MaD:3 Sink:MaD:3 | +| test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref] | test_cipher.rs:26:30:26:40 | ...::new | provenance | MaD:5 Sink:MaD:5 | +| test_cipher.rs:26:66:26:71 | const4 [&ref] | test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref] | provenance | MaD:10 | +| test_cipher.rs:29:9:29:14 | const5 [&ref] | test_cipher.rs:30:95:30:100 | const5 [&ref] | provenance | | +| test_cipher.rs:29:28:29:36 | &... [&ref] | test_cipher.rs:29:9:29:14 | const5 [&ref] | provenance | | +| test_cipher.rs:29:29:29:36 | [0u8; 16] | test_cipher.rs:29:28:29:36 | &... [&ref] | provenance | | +| test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref] | test_cipher.rs:30:30:30:40 | ...::new | provenance | MaD:4 Sink:MaD:4 | +| test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref] | test_cipher.rs:30:30:30:40 | ...::new | provenance | MaD:6 Sink:MaD:6 | +| test_cipher.rs:30:95:30:100 | const5 [&ref] | test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref] | provenance | MaD:10 | | test_cipher.rs:37:9:37:14 | const7 | test_cipher.rs:38:74:38:79 | const7 | provenance | | | test_cipher.rs:37:27:37:74 | [...] | test_cipher.rs:37:9:37:14 | const7 | provenance | | | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | test_cipher.rs:38:30:38:47 | ...::new | provenance | MaD:3 Sink:MaD:3 | | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | test_cipher.rs:38:30:38:47 | ...::new | provenance | MaD:5 Sink:MaD:5 | -| test_cipher.rs:38:73:38:79 | &const7 [&ref] | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | provenance | MaD:9 | +| test_cipher.rs:38:73:38:79 | &const7 [&ref] | test_cipher.rs:38:49:38:80 | ...::from_slice(...) [&ref] | provenance | MaD:10 | | test_cipher.rs:38:74:38:79 | const7 | test_cipher.rs:38:73:38:79 | &const7 [&ref] | provenance | | | test_cipher.rs:41:9:41:14 | const8 [&ref] | test_cipher.rs:42:73:42:78 | const8 [&ref] | provenance | | | test_cipher.rs:41:28:41:76 | &... [&ref] | test_cipher.rs:41:9:41:14 | const8 [&ref] | provenance | | | test_cipher.rs:41:29:41:76 | [...] | test_cipher.rs:41:28:41:76 | &... [&ref] | provenance | | | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | test_cipher.rs:42:30:42:47 | ...::new | provenance | MaD:3 Sink:MaD:3 | | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | test_cipher.rs:42:30:42:47 | ...::new | provenance | MaD:5 Sink:MaD:5 | -| test_cipher.rs:42:73:42:78 | const8 [&ref] | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | provenance | MaD:9 | +| test_cipher.rs:42:73:42:78 | const8 [&ref] | test_cipher.rs:42:49:42:79 | ...::from_slice(...) [&ref] | provenance | MaD:10 | | test_cipher.rs:50:9:50:15 | const10 [element] | test_cipher.rs:51:75:51:81 | const10 [element] | provenance | | | test_cipher.rs:50:37:50:52 | ...::zeroed | test_cipher.rs:50:37:50:54 | ...::zeroed(...) [element] | provenance | Src:MaD:8 | | test_cipher.rs:50:37:50:54 | ...::zeroed(...) [element] | test_cipher.rs:50:9:50:15 | const10 [element] | provenance | | | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | test_cipher.rs:51:31:51:48 | ...::new | provenance | MaD:3 Sink:MaD:3 Sink:MaD:3 | | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | test_cipher.rs:51:31:51:48 | ...::new | provenance | MaD:5 Sink:MaD:5 Sink:MaD:5 | -| test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | provenance | MaD:9 | +| test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | provenance | MaD:10 | | test_cipher.rs:51:75:51:81 | const10 [element] | test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | provenance | | -| test_cipher.rs:73:9:73:14 | const2 [&ref, element] | test_cipher.rs:74:46:74:51 | const2 [&ref, element] | provenance | | -| test_cipher.rs:73:18:73:26 | &... [&ref, element] | test_cipher.rs:73:9:73:14 | const2 [&ref, element] | provenance | | -| test_cipher.rs:73:19:73:26 | [0u8; 32] [element] | test_cipher.rs:73:18:73:26 | &... [&ref, element] | provenance | | -| test_cipher.rs:73:20:73:22 | 0u8 | test_cipher.rs:73:19:73:26 | [0u8; 32] [element] | provenance | | -| test_cipher.rs:74:46:74:51 | const2 [&ref, element] | test_cipher.rs:74:23:74:44 | ...::new_from_slice | provenance | MaD:1 Sink:MaD:1 Sink:MaD:1 | -| test_cookie.rs:17:9:17:14 | array1 [element] | test_cookie.rs:18:27:18:32 | array1 [element] | provenance | | -| test_cookie.rs:17:28:17:34 | [0; 64] [element] | test_cookie.rs:17:9:17:14 | array1 [element] | provenance | | -| test_cookie.rs:17:29:17:29 | 0 | test_cookie.rs:17:28:17:34 | [0; 64] [element] | provenance | | -| test_cookie.rs:18:26:18:32 | &array1 [&ref, element] | test_cookie.rs:18:16:18:24 | ...::from | provenance | MaD:7 Sink:MaD:7 | -| test_cookie.rs:18:27:18:32 | array1 [element] | test_cookie.rs:18:26:18:32 | &array1 [&ref, element] | provenance | | -| test_cookie.rs:21:9:21:14 | array2 [element] | test_cookie.rs:22:27:22:32 | array2 [element] | provenance | | -| test_cookie.rs:21:28:21:34 | [0; 64] [element] | test_cookie.rs:21:9:21:14 | array2 [element] | provenance | | -| test_cookie.rs:21:29:21:29 | 0 | test_cookie.rs:21:28:21:34 | [0; 64] [element] | provenance | | -| test_cookie.rs:22:26:22:32 | &array2 [&ref, element] | test_cookie.rs:22:16:22:24 | ...::from | provenance | MaD:7 Sink:MaD:7 | -| test_cookie.rs:22:27:22:32 | array2 [element] | test_cookie.rs:22:26:22:32 | &array2 [&ref, element] | provenance | | +| test_cipher.rs:73:9:73:14 | const2 [&ref] | test_cipher.rs:74:46:74:51 | const2 [&ref] | provenance | | +| test_cipher.rs:73:18:73:26 | &... [&ref] | test_cipher.rs:73:9:73:14 | const2 [&ref] | provenance | | +| test_cipher.rs:73:19:73:26 | [0u8; 32] | test_cipher.rs:73:18:73:26 | &... [&ref] | provenance | | +| test_cipher.rs:74:46:74:51 | const2 [&ref] | test_cipher.rs:74:23:74:44 | ...::new_from_slice | provenance | MaD:1 Sink:MaD:1 | +| test_cookie.rs:17:9:17:14 | array1 | test_cookie.rs:18:27:18:32 | array1 | provenance | | +| test_cookie.rs:17:28:17:34 | [0; 64] | test_cookie.rs:17:9:17:14 | array1 | provenance | | +| test_cookie.rs:18:26:18:32 | &array1 [&ref] | test_cookie.rs:18:16:18:24 | ...::from | provenance | MaD:7 Sink:MaD:7 | +| test_cookie.rs:18:27:18:32 | array1 | test_cookie.rs:18:26:18:32 | &array1 [&ref] | provenance | | +| test_cookie.rs:21:9:21:14 | array2 | test_cookie.rs:22:27:22:32 | array2 | provenance | | +| test_cookie.rs:21:28:21:34 | [0; 64] | test_cookie.rs:21:9:21:14 | array2 | provenance | | +| test_cookie.rs:22:26:22:32 | &array2 [&ref] | test_cookie.rs:22:16:22:24 | ...::from | provenance | MaD:7 Sink:MaD:7 | +| test_cookie.rs:22:27:22:32 | array2 | test_cookie.rs:22:26:22:32 | &array2 [&ref] | provenance | | +| test_cookie.rs:38:9:38:14 | array2 | test_cookie.rs:42:34:42:39 | array2 | provenance | | +| test_cookie.rs:38:18:38:37 | ...::from(...) | test_cookie.rs:38:9:38:14 | array2 | provenance | | +| test_cookie.rs:38:28:38:36 | [0u8; 64] | test_cookie.rs:38:18:38:37 | ...::from(...) | provenance | MaD:9 | +| test_cookie.rs:42:34:42:39 | array2 | test_cookie.rs:42:14:42:32 | ...::from | provenance | MaD:2 Sink:MaD:2 | | test_cookie.rs:49:9:49:14 | array3 [element] | test_cookie.rs:53:34:53:39 | array3 [element] | provenance | | -| test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | provenance | MaD:10 | +| test_cookie.rs:49:23:49:25 | 0u8 | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | provenance | MaD:11 | | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | test_cookie.rs:49:9:49:14 | array3 [element] | provenance | | | test_cookie.rs:53:34:53:39 | array3 [element] | test_cookie.rs:53:14:53:32 | ...::from | provenance | MaD:2 Sink:MaD:2 | models @@ -84,33 +83,31 @@ models | 6 | Sink: ::new; Argument[1]; credentials-iv | | 7 | Sink: ::from; Argument[0].Reference; credentials-key | | 8 | Source: core::mem::zeroed; ReturnValue.Element; constant-source | -| 9 | Summary: ::from_slice; Argument[0].Reference; ReturnValue.Reference; value | -| 10 | Summary: alloc::vec::from_elem; Argument[0]; ReturnValue.Element; value | +| 9 | Summary: <_ as core::convert::From>::from; Argument[0]; ReturnValue; taint | +| 10 | Summary: ::from_slice; Argument[0].Reference; ReturnValue.Reference; value | +| 11 | Summary: alloc::vec::from_elem; Argument[0]; ReturnValue.Element; value | nodes -| test_cipher.rs:18:9:18:14 | const1 [&ref, element] | semmle.label | const1 [&ref, element] | -| test_cipher.rs:18:28:18:36 | &... [&ref, element] | semmle.label | &... [&ref, element] | -| test_cipher.rs:18:29:18:36 | [0u8; 16] [element] | semmle.label | [0u8; 16] [element] | -| test_cipher.rs:18:30:18:32 | 0u8 | semmle.label | 0u8 | +| test_cipher.rs:18:9:18:14 | const1 [&ref] | semmle.label | const1 [&ref] | +| test_cipher.rs:18:28:18:36 | &... [&ref] | semmle.label | &... [&ref] | +| test_cipher.rs:18:29:18:36 | [0u8; 16] | semmle.label | [0u8; 16] | | test_cipher.rs:19:30:19:47 | ...::new | semmle.label | ...::new | | test_cipher.rs:19:30:19:47 | ...::new | semmle.label | ...::new | -| test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref, element] | semmle.label | ...::from_slice(...) [&ref, element] | -| test_cipher.rs:19:73:19:78 | const1 [&ref, element] | semmle.label | const1 [&ref, element] | -| test_cipher.rs:25:9:25:14 | const4 [&ref, element] | semmle.label | const4 [&ref, element] | -| test_cipher.rs:25:28:25:36 | &... [&ref, element] | semmle.label | &... [&ref, element] | -| test_cipher.rs:25:29:25:36 | [0u8; 16] [element] | semmle.label | [0u8; 16] [element] | -| test_cipher.rs:25:30:25:32 | 0u8 | semmle.label | 0u8 | +| test_cipher.rs:19:49:19:79 | ...::from_slice(...) [&ref] | semmle.label | ...::from_slice(...) [&ref] | +| test_cipher.rs:19:73:19:78 | const1 [&ref] | semmle.label | const1 [&ref] | +| test_cipher.rs:25:9:25:14 | const4 [&ref] | semmle.label | const4 [&ref] | +| test_cipher.rs:25:28:25:36 | &... [&ref] | semmle.label | &... [&ref] | +| test_cipher.rs:25:29:25:36 | [0u8; 16] | semmle.label | [0u8; 16] | | test_cipher.rs:26:30:26:40 | ...::new | semmle.label | ...::new | | test_cipher.rs:26:30:26:40 | ...::new | semmle.label | ...::new | -| test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref, element] | semmle.label | ...::from_slice(...) [&ref, element] | -| test_cipher.rs:26:66:26:71 | const4 [&ref, element] | semmle.label | const4 [&ref, element] | -| test_cipher.rs:29:9:29:14 | const5 [&ref, element] | semmle.label | const5 [&ref, element] | -| test_cipher.rs:29:28:29:36 | &... [&ref, element] | semmle.label | &... [&ref, element] | -| test_cipher.rs:29:29:29:36 | [0u8; 16] [element] | semmle.label | [0u8; 16] [element] | -| test_cipher.rs:29:30:29:32 | 0u8 | semmle.label | 0u8 | +| test_cipher.rs:26:42:26:72 | ...::from_slice(...) [&ref] | semmle.label | ...::from_slice(...) [&ref] | +| test_cipher.rs:26:66:26:71 | const4 [&ref] | semmle.label | const4 [&ref] | +| test_cipher.rs:29:9:29:14 | const5 [&ref] | semmle.label | const5 [&ref] | +| test_cipher.rs:29:28:29:36 | &... [&ref] | semmle.label | &... [&ref] | +| test_cipher.rs:29:29:29:36 | [0u8; 16] | semmle.label | [0u8; 16] | | test_cipher.rs:30:30:30:40 | ...::new | semmle.label | ...::new | | test_cipher.rs:30:30:30:40 | ...::new | semmle.label | ...::new | -| test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref, element] | semmle.label | ...::from_slice(...) [&ref, element] | -| test_cipher.rs:30:95:30:100 | const5 [&ref, element] | semmle.label | const5 [&ref, element] | +| test_cipher.rs:30:72:30:101 | ...::from_slice(...) [&ref] | semmle.label | ...::from_slice(...) [&ref] | +| test_cipher.rs:30:95:30:100 | const5 [&ref] | semmle.label | const5 [&ref] | | test_cipher.rs:37:9:37:14 | const7 | semmle.label | const7 | | test_cipher.rs:37:27:37:74 | [...] | semmle.label | [...] | | test_cipher.rs:38:30:38:47 | ...::new | semmle.label | ...::new | @@ -133,30 +130,29 @@ nodes | test_cipher.rs:51:50:51:82 | ...::from_slice(...) [&ref, element] | semmle.label | ...::from_slice(...) [&ref, element] | | test_cipher.rs:51:74:51:81 | &const10 [&ref, element] | semmle.label | &const10 [&ref, element] | | test_cipher.rs:51:75:51:81 | const10 [element] | semmle.label | const10 [element] | -| test_cipher.rs:73:9:73:14 | const2 [&ref, element] | semmle.label | const2 [&ref, element] | -| test_cipher.rs:73:18:73:26 | &... [&ref, element] | semmle.label | &... [&ref, element] | -| test_cipher.rs:73:19:73:26 | [0u8; 32] [element] | semmle.label | [0u8; 32] [element] | -| test_cipher.rs:73:20:73:22 | 0u8 | semmle.label | 0u8 | +| test_cipher.rs:73:9:73:14 | const2 [&ref] | semmle.label | const2 [&ref] | +| test_cipher.rs:73:18:73:26 | &... [&ref] | semmle.label | &... [&ref] | +| test_cipher.rs:73:19:73:26 | [0u8; 32] | semmle.label | [0u8; 32] | | test_cipher.rs:74:23:74:44 | ...::new_from_slice | semmle.label | ...::new_from_slice | -| test_cipher.rs:74:46:74:51 | const2 [&ref, element] | semmle.label | const2 [&ref, element] | -| test_cookie.rs:17:9:17:14 | array1 [element] | semmle.label | array1 [element] | -| test_cookie.rs:17:28:17:34 | [0; 64] [element] | semmle.label | [0; 64] [element] | -| test_cookie.rs:17:29:17:29 | 0 | semmle.label | 0 | +| test_cipher.rs:74:46:74:51 | const2 [&ref] | semmle.label | const2 [&ref] | +| test_cookie.rs:17:9:17:14 | array1 | semmle.label | array1 | +| test_cookie.rs:17:28:17:34 | [0; 64] | semmle.label | [0; 64] | | test_cookie.rs:18:16:18:24 | ...::from | semmle.label | ...::from | -| test_cookie.rs:18:26:18:32 | &array1 [&ref, element] | semmle.label | &array1 [&ref, element] | -| test_cookie.rs:18:27:18:32 | array1 [element] | semmle.label | array1 [element] | -| test_cookie.rs:21:9:21:14 | array2 [element] | semmle.label | array2 [element] | -| test_cookie.rs:21:28:21:34 | [0; 64] [element] | semmle.label | [0; 64] [element] | -| test_cookie.rs:21:29:21:29 | 0 | semmle.label | 0 | +| test_cookie.rs:18:26:18:32 | &array1 [&ref] | semmle.label | &array1 [&ref] | +| test_cookie.rs:18:27:18:32 | array1 | semmle.label | array1 | +| test_cookie.rs:21:9:21:14 | array2 | semmle.label | array2 | +| test_cookie.rs:21:28:21:34 | [0; 64] | semmle.label | [0; 64] | | test_cookie.rs:22:16:22:24 | ...::from | semmle.label | ...::from | -| test_cookie.rs:22:26:22:32 | &array2 [&ref, element] | semmle.label | &array2 [&ref, element] | -| test_cookie.rs:22:27:22:32 | array2 [element] | semmle.label | array2 [element] | +| test_cookie.rs:22:26:22:32 | &array2 [&ref] | semmle.label | &array2 [&ref] | +| test_cookie.rs:22:27:22:32 | array2 | semmle.label | array2 | +| test_cookie.rs:38:9:38:14 | array2 | semmle.label | array2 | +| test_cookie.rs:38:18:38:37 | ...::from(...) | semmle.label | ...::from(...) | +| test_cookie.rs:38:28:38:36 | [0u8; 64] | semmle.label | [0u8; 64] | +| test_cookie.rs:42:14:42:32 | ...::from | semmle.label | ...::from | +| test_cookie.rs:42:34:42:39 | array2 | semmle.label | array2 | | test_cookie.rs:49:9:49:14 | array3 [element] | semmle.label | array3 [element] | | test_cookie.rs:49:23:49:25 | 0u8 | semmle.label | 0u8 | | test_cookie.rs:49:23:49:29 | ...::from_elem(...) [element] | semmle.label | ...::from_elem(...) [element] | | test_cookie.rs:53:14:53:32 | ...::from | semmle.label | ...::from | | test_cookie.rs:53:34:53:39 | array3 [element] | semmle.label | array3 [element] | subpaths -testFailures -| test_cookie.rs:38:40:38:86 | //... | Missing result: Alert[rust/hard-coded-cryptographic-value] | -| test_cookie.rs:42:43:42:51 | //... | Missing result: Sink | From 2f96e32ec995fd8fecabd88c475f1a245a1fc3a4 Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Fri, 26 Sep 2025 10:08:31 +0100 Subject: [PATCH 134/160] Update 2.1.0.md --- javascript/ql/src/change-notes/released/2.1.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/change-notes/released/2.1.0.md b/javascript/ql/src/change-notes/released/2.1.0.md index e0ef5ddd6e1..6b5696816cf 100644 --- a/javascript/ql/src/change-notes/released/2.1.0.md +++ b/javascript/ql/src/change-notes/released/2.1.0.md @@ -10,4 +10,4 @@ * Data flow is now tracked through the `Promise.try` and `Array.prototype.with` functions. * Query `js/index-out-of-bounds` no longer produces a false-positive when a strictly-less-than check overrides a previous less-than-or-equal test. * The query `js/remote-property-injection` now detects property injection vulnerabilities through object enumeration patterns such as `Object.keys()`. -* The query "Permissive CORS configuration" (`js/cors-permissive-configuration`) has been promoted from experimental and is now part of the default security suite. +* The query "Permissive CORS configuration" (`js/cors-permissive-configuration`) has been promoted from experimental and is now part of the default security suite. Thank you to @maikypedia who submitted the original experimental query! From 09833e2541e36e678993b9fa613113dba0fac32f Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Fri, 26 Sep 2025 10:09:30 +0100 Subject: [PATCH 135/160] Update CHANGELOG for query promotion and acknowledgment Promote 'Permissive CORS configuration' query to default suite and acknowledge contributor. --- javascript/ql/src/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 619bc14bf29..4067c050c2a 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -10,7 +10,7 @@ * Data flow is now tracked through the `Promise.try` and `Array.prototype.with` functions. * Query `js/index-out-of-bounds` no longer produces a false-positive when a strictly-less-than check overrides a previous less-than-or-equal test. * The query `js/remote-property-injection` now detects property injection vulnerabilities through object enumeration patterns such as `Object.keys()`. -* The query "Permissive CORS configuration" (`js/cors-permissive-configuration`) has been promoted from experimental and is now part of the default security suite. +* The query "Permissive CORS configuration" (`js/cors-permissive-configuration`) has been promoted from experimental and is now part of the default security suite. Thank you to @maikypedia who [submitted the original experimental query](https://github.com/github/codeql/pull/14342)! ## 2.0.3 From ba520c60d23a6e7bbd091eade91b5d6544525e41 Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Fri, 26 Sep 2025 10:11:03 +0100 Subject: [PATCH 136/160] Update 2.1.0.md --- javascript/ql/src/change-notes/released/2.1.0.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ql/src/change-notes/released/2.1.0.md b/javascript/ql/src/change-notes/released/2.1.0.md index 6b5696816cf..c95b5add20b 100644 --- a/javascript/ql/src/change-notes/released/2.1.0.md +++ b/javascript/ql/src/change-notes/released/2.1.0.md @@ -10,4 +10,4 @@ * Data flow is now tracked through the `Promise.try` and `Array.prototype.with` functions. * Query `js/index-out-of-bounds` no longer produces a false-positive when a strictly-less-than check overrides a previous less-than-or-equal test. * The query `js/remote-property-injection` now detects property injection vulnerabilities through object enumeration patterns such as `Object.keys()`. -* The query "Permissive CORS configuration" (`js/cors-permissive-configuration`) has been promoted from experimental and is now part of the default security suite. Thank you to @maikypedia who submitted the original experimental query! +* The query "Permissive CORS configuration" (`js/cors-permissive-configuration`) has been promoted from experimental and is now part of the default security suite. Thank you to @maikypedia who [submitted the original experimental query](https://github.com/github/codeql/pull/14342)! From 21fe142955f3c1285ae832f51765756181bc25aa Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 10:39:49 +0100 Subject: [PATCH 137/160] Update rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp Co-authored-by: Simon Friis Vindum --- rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp index ef08ff27b9c..f3d1735251e 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp @@ -14,7 +14,7 @@ -

    The following example creates a cookie using the cookie crate without the 'Secure' attribute:

    +

    The following example creates a cookie using the cookie crate without the 'Secure' attribute:

    From 57f84873b441399cdea83ea429301a2119cb1cda Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 11:29:11 +0100 Subject: [PATCH 138/160] Rust: Split off cookieOptionalBarrier predicate (as suggested) and expand / clarify the QLDoc. --- .../security/InsecureCookieExtensions.qll | 43 ++++++++++++++----- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 3525614c0dc..721f30c1a37 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -49,20 +49,40 @@ module InsecureCookie { } /** - * Holds if cookie attribute `attrib` (`secure` or `partitioned`) is set to `value` (`true` or `false`) at `node`. - * A value that cannot be determined is treated as `false`. + * Holds if a models-as-data optional barrier for cookies is specified for `summaryNode`, + * with arguments `attrib` (`secure` or `partitioned`) and `arg` (argument index). For example, + * if a summary has input: + * ``` + * [..., Argument[self].OptionalBarrier[cookie-secure-arg0], ...] + * ``` + * then `attrib` is `secure` and `arg` is `0`. * - * This references models-as-data optional barrier nodes, for example `OptionalBarrier[cookie-secure-arg0]`. + * The meaning here is that a call to the function summarized by `summaryNode` would set + * the cookie attribute `attrib` to the value of argument `arg`. This may in practice be + * interpretted as a barrier to flow (when the cookie is made secure) or as a source (when + * the cookie is made insecure). */ - predicate cookieSetNode(DataFlow::Node node, string attrib, boolean value) { - exists( - FlowSummaryNode summaryNode, string barrierName, CallExprBase ce, int arg, - DataFlow::Node argNode - | - // decode a `cookie-`... optional barrier + private predicate cookieOptionalBarrier(FlowSummaryNode summaryNode, string attrib, int arg) { + exists(string barrierName | DataFlowImpl::optionalBarrier(summaryNode, barrierName) and attrib = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 1) and - arg = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 2).toInt() and + arg = barrierName.regexpCapture("cookie-(secure|partitioned)-arg([0-9]+)", 2).toInt() + ) + } + + /** + * Holds if cookie attribute `attrib` (`secure` or `partitioned`) is set to `value` + * (`true` or `false`) at `node`. For example, the call: + * ``` + * cookie.secure(true) + * ``` + * sets the `"secure"` attribute to `true`. A value that cannot be determined is treated + * as `false`. + */ + predicate cookieSetNode(DataFlow::Node node, string attrib, boolean value) { + exists(FlowSummaryNode summaryNode, CallExprBase ce, int arg, DataFlow::Node argNode | + // decode the models-as-data `OptionalBarrier` + cookieOptionalBarrier(summaryNode, attrib, arg) and // find a call and arg referenced by this optional barrier ce.getStaticTarget() = summaryNode.getSummarizedCallable() and ce.getArg(arg) = argNode.asExpr().getExpr() and @@ -78,7 +98,8 @@ module InsecureCookie { then value = true // `true` flows to here else value = false // `false`, unknown, or multiple values ) and - // and find the node where this happens + // and find the node where this happens (we can't just use the flow summary node, since its + // shared across all calls to the modelled function, we need a node specific to this call) ( node.asExpr().getExpr() = ce.(MethodCallExpr).getReceiver() // e.g. `a` in `a.set_secure(true)` or From f458149655c1bf7ab9b8673fb480926e65d0d86a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 11:32:45 +0100 Subject: [PATCH 139/160] Rust: Remove a sentance from the qhelp. --- rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp index f3d1735251e..561b334c510 100644 --- a/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp +++ b/rust/ql/src/queries/security/CWE-614/InsecureCookie.qhelp @@ -4,7 +4,7 @@ -

    Failing to set the 'Secure' attribute on a cookie allows it to be transmitted over an unencrypted (HTTP) connection. If an attacker can observe a user's network traffic (for example over an insecure Wi‑Fi network), they can access sensitive information in the cookie and potentially use it to impersonate the user.

    +

    Failing to set the 'Secure' attribute on a cookie allows it to be transmitted over an unencrypted (HTTP) connection. If an attacker can observe a user's network traffic, they can access sensitive information in the cookie and potentially use it to impersonate the user.

    From 77e7898f718087df6debe850bbc74e9946957289 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 11:49:23 +0100 Subject: [PATCH 140/160] Rust: Use US spelling in comment. --- rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll index 721f30c1a37..d5d15c821d8 100644 --- a/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll +++ b/rust/ql/lib/codeql/rust/security/InsecureCookieExtensions.qll @@ -99,7 +99,7 @@ module InsecureCookie { else value = false // `false`, unknown, or multiple values ) and // and find the node where this happens (we can't just use the flow summary node, since its - // shared across all calls to the modelled function, we need a node specific to this call) + // shared across all calls to the modeled function, we need a node specific to this call) ( node.asExpr().getExpr() = ce.(MethodCallExpr).getReceiver() // e.g. `a` in `a.set_secure(true)` or From 4c7b66c66af102eaf2ecf7bcb2f5090cdeee88b6 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 26 Sep 2025 13:11:45 +0200 Subject: [PATCH 141/160] Address review comments --- .../rust/elements/internal/CallableImpl.qll | 10 ++++++ .../codeql/rust/internal/PathResolution.qll | 31 +++++++------------ 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/CallableImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/CallableImpl.qll index 46489cab981..9448de795d3 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/CallableImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/CallableImpl.qll @@ -27,5 +27,15 @@ module Impl { * Holds if `getSelfParam()` exists. */ predicate hasSelfParam() { exists(this.getSelfParam()) } + + /** + * Gets the number of parameters of this callable, including `self` if it exists. + */ + int getNumberOfParamsInclSelf() { + exists(int arr | + arr = this.getNumberOfParams() and + if this.hasSelfParam() then result = arr + 1 else result = arr + ) + } } } diff --git a/rust/ql/lib/codeql/rust/internal/PathResolution.qll b/rust/ql/lib/codeql/rust/internal/PathResolution.qll index 4b368308878..f1574ff38f3 100644 --- a/rust/ql/lib/codeql/rust/internal/PathResolution.qll +++ b/rust/ql/lib/codeql/rust/internal/PathResolution.qll @@ -605,13 +605,13 @@ private class EnumItemNode extends TypeItemNode instanceof Enum { } } -/** An item that can be called with arguments. */ -abstract class CallableItemNode extends ItemNode { - /** Gets the number of parameters of this item. */ - abstract int getNumberOfParameters(); +/** An item that can be referenced with arguments. */ +abstract class ParameterizableItemNode extends ItemNode { + /** Gets the arity this item. */ + abstract int getArity(); } -private class VariantItemNode extends CallableItemNode instanceof Variant { +private class VariantItemNode extends ParameterizableItemNode instanceof Variant { override string getName() { result = Variant.super.getName().getText() } override Namespace getNamespace() { @@ -624,9 +624,7 @@ private class VariantItemNode extends CallableItemNode instanceof Variant { override Visibility getVisibility() { result = super.getEnum().getVisibility() } - override int getNumberOfParameters() { - result = super.getFieldList().(TupleFieldList).getNumberOfFields() - } + override int getArity() { result = super.getFieldList().(TupleFieldList).getNumberOfFields() } override predicate hasCanonicalPath(Crate c) { this.hasCanonicalPathPrefix(c) } @@ -649,7 +647,7 @@ private class VariantItemNode extends CallableItemNode instanceof Variant { } } -class FunctionItemNode extends AssocItemNode, CallableItemNode instanceof Function { +class FunctionItemNode extends AssocItemNode, ParameterizableItemNode instanceof Function { override string getName() { result = Function.super.getName().getText() } override predicate hasImplementation() { Function.super.hasImplementation() } @@ -660,12 +658,7 @@ class FunctionItemNode extends AssocItemNode, CallableItemNode instanceof Functi override Visibility getVisibility() { result = Function.super.getVisibility() } - override int getNumberOfParameters() { - exists(int arr | - arr = super.getNumberOfParams() and - if super.hasSelfParam() then result = arr + 1 else result = arr - ) - } + override int getArity() { result = super.getNumberOfParamsInclSelf() } } abstract class ImplOrTraitItemNode extends ItemNode { @@ -885,7 +878,7 @@ private class ImplItemNodeImpl extends ImplItemNode { TraitItemNode resolveTraitTyCand() { result = resolvePathCand(this.getTraitPath()) } } -private class StructItemNode extends TypeItemNode, CallableItemNode instanceof Struct { +private class StructItemNode extends TypeItemNode, ParameterizableItemNode instanceof Struct { override string getName() { result = Struct.super.getName().getText() } override Namespace getNamespace() { @@ -897,9 +890,7 @@ private class StructItemNode extends TypeItemNode, CallableItemNode instanceof S override Visibility getVisibility() { result = Struct.super.getVisibility() } - override int getNumberOfParameters() { - result = super.getFieldList().(TupleFieldList).getNumberOfFields() - } + override int getArity() { result = super.getFieldList().(TupleFieldList).getNumberOfFields() } override TypeParam getTypeParam(int i) { result = super.getGenericParamList().getTypeParam(i) } @@ -1717,7 +1708,7 @@ private ItemNode resolvePathCand(RelevantPath path) { or exists(CallExpr ce | path = CallExprImpl::getFunctionPath(ce) and - result.(CallableItemNode).getNumberOfParameters() = ce.getNumberOfArgs() + result.(ParameterizableItemNode).getArity() = ce.getNumberOfArgs() ) ) } From 2c29f210046a362db85023cbb4a08d7d12865f1d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Fri, 26 Sep 2025 13:59:53 +0200 Subject: [PATCH 142/160] Shared: Address review comments. --- .../codeql/controlflow/ControlFlow.qll | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/shared/controlflow/codeql/controlflow/ControlFlow.qll b/shared/controlflow/codeql/controlflow/ControlFlow.qll index ca0de9d4744..7fd6ec70bfc 100644 --- a/shared/controlflow/codeql/controlflow/ControlFlow.qll +++ b/shared/controlflow/codeql/controlflow/ControlFlow.qll @@ -278,7 +278,7 @@ module Make< exists(Expr e | def.getDefinition() = e and exprHasValue(e, gv) and - (exists(GuardValue gv0 | exprHasValue(e, gv0) and gv0.isSingleton()) implies gv.isSingleton()) + (any(GuardValue gv0 | exprHasValue(e, gv0)).isSingleton() implies gv.isSingleton()) ) } @@ -595,7 +595,7 @@ module Make< ) { ssaControlsBranchEdge(t, bb1, bb2, gv) and ( - exists(GuardValue gv0 | ssaControlsBranchEdge(t, bb1, bb2, gv0) and gv0.isSingleton()) + any(GuardValue gv0 | ssaControlsBranchEdge(t, bb1, bb2, gv0)).isSingleton() implies gv.isSingleton() ) and @@ -694,7 +694,7 @@ module Make< * `src`, and `var` is a relevant splitting variable that gets (re-)defined * in `bb2` by `t`, which is not a phi node. * - * `val` is the best known value for `t` in `bb2`. + * `val` is the best known value that is relatable to `condgv` for `t` in `bb2`. */ private predicate stepSsaValueRedef( SourceVariable src, BasicBlock bb1, BasicBlock bb2, SourceVariable var, GuardValue condgv, @@ -720,7 +720,8 @@ module Make< * `t2`, in `bb2` taking input from `t1` along this edge. Furthermore, * there is no further redefinition of `var` in `bb2`. * - * `val` is the best value for `t1`/`t2` implied by taking this edge. + * `val` is the best value that is relatable to `condgv` for `t1`/`t2` + * implied by taking this edge. */ private predicate stepSsaValuePhi( SourceVariable src, BasicBlock bb1, BasicBlock bb2, SourceVariable var, GuardValue condgv, @@ -747,7 +748,7 @@ module Make< * redefinition along this edge nor in `bb2`. * * Additionally, this edge implies that the SSA definition `t` of `var` has - * value `val`. + * value `val` and that `val` is relatable to `condgv`. */ private predicate stepSsaValueNoRedef( SourceVariable src, BasicBlock bb1, BasicBlock bb2, SourceVariable var, GuardValue condgv, @@ -763,6 +764,12 @@ module Make< /** * Holds if the source `srcDef` in `srcBb` may reach `def` in `bb`. The * taken path takes splitting based on the value of `var` into account. + * + * When multiple `GuardValue`s can be chosen for `var`, we prioritize those + * that are relatable to `condgv`, as that will help determine whether a + * particular edge may be taken or not. Singleton values are prioritized + * highly as they are in principle relatable to every other `GuardValue`. + * * The pair `(tracked, val)` is the current SSA definition and known value * for `var` in `bb`. */ From 3e9332edfa722f7df6e3ceb0e45b230f0036f605 Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Fri, 26 Sep 2025 13:16:45 +0100 Subject: [PATCH 143/160] Fix formatting in codeql-cli-2.23.1.rst --- .../codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst index 3767c877b5a..920638fdc87 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst @@ -126,7 +126,7 @@ Golang """""" * The second argument of the :code:`CreateTemp` function, from the :code:`os` package, is no longer a path-injection sink due to proper sanitization by Go. -* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:`\ ` to the beginning. +* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:``\`` to the beginning. Java/Kotlin """"""""""" From a4f5e9aaf5277a72e4a1aa995fc2de00b982dbfb Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Fri, 26 Sep 2025 13:46:12 +0100 Subject: [PATCH 144/160] Update changelog for CodeQL CLI 2.23.1 Added acknowledgment for the original contributor of the 'Permissive CORS configuration' query and clarified the detection of path injection in Go. --- .../codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst index 920638fdc87..c93bd8af0c3 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst @@ -88,7 +88,7 @@ JavaScript/TypeScript * Data flow is now tracked through the :code:`Promise.try` and :code:`Array.prototype.with` functions. * Query :code:`js/index-out-of-bounds` no longer produces a false-positive when a strictly-less-than check overrides a previous less-than-or-equal test. * The query :code:`js/remote-property-injection` now detects property injection vulnerabilities through object enumeration patterns such as :code:`Object.keys()`. -* The query "Permissive CORS configuration" (:code:`js/cors-permissive-configuration`) has been promoted from experimental and is now part of the default security suite. +* The query "Permissive CORS configuration" (:code:`js/cors-permissive-configuration`) has been promoted from experimental and is now part of the default security suite. Thank you to @maikypedia who [submitted the original experimental query](https://github.com/github/codeql/pull/14342)! Python """""" @@ -126,7 +126,7 @@ Golang """""" * The second argument of the :code:`CreateTemp` function, from the :code:`os` package, is no longer a path-injection sink due to proper sanitization by Go. -* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or :code:``\`` to the beginning. +* The query "Uncontrolled data used in path expression" (:code:`go/path-injection`) now detects sanitizing a path by adding :code:`os.PathSeparator` or ``\`` to the beginning. Java/Kotlin """"""""""" From 5a0bae27ac97393c76c1470cfccc0828dabb33e5 Mon Sep 17 00:00:00 2001 From: Florin Coada Date: Fri, 26 Sep 2025 13:57:57 +0100 Subject: [PATCH 145/160] Update changelog for CodeQL CLI 2.23.1 --- .../codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst index c93bd8af0c3..1c4ac199687 100644 --- a/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst +++ b/docs/codeql/codeql-overview/codeql-changelog/codeql-cli-2.23.1.rst @@ -88,7 +88,7 @@ JavaScript/TypeScript * Data flow is now tracked through the :code:`Promise.try` and :code:`Array.prototype.with` functions. * Query :code:`js/index-out-of-bounds` no longer produces a false-positive when a strictly-less-than check overrides a previous less-than-or-equal test. * The query :code:`js/remote-property-injection` now detects property injection vulnerabilities through object enumeration patterns such as :code:`Object.keys()`. -* The query "Permissive CORS configuration" (:code:`js/cors-permissive-configuration`) has been promoted from experimental and is now part of the default security suite. Thank you to @maikypedia who [submitted the original experimental query](https://github.com/github/codeql/pull/14342)! +* The query "Permissive CORS configuration" (:code:`js/cors-permissive-configuration`) has been promoted from experimental and is now part of the default security suite. Thank you to @maikypedia who `submitted the original experimental query `__! Python """""" From 27b6f12b3c0414dc1a498a8c564da7dac37f99c4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 14:30:27 +0100 Subject: [PATCH 146/160] Rust: Use the suggested cleaner implementation for getStmtOrExpr. --- rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll index 648a4eab9b8..9120728dcbc 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll @@ -33,7 +33,7 @@ module Impl { AstNode getStmtOrExpr(int index) { result = this.getStatement(index) or - index = max(int i | i = -1 or exists(this.getStatement(i))) + 1 and + index = this.getNumberOfStatements() and result = this.getTailExpr() } From 4570d7e46e205703ef46e4c997601ce322567e6f Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 14:32:05 +0100 Subject: [PATCH 147/160] Rust: Replace getBlockChildNode with uses of getStmtOrExpr. --- .../controlflow/internal/ControlFlowGraphImpl.qll | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll index ddc4dae9b95..609a68fc392 100644 --- a/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll +++ b/rust/ql/lib/codeql/rust/controlflow/internal/ControlFlowGraphImpl.qll @@ -266,15 +266,8 @@ module ExprTrees { } } - private AstNode getBlockChildNode(BlockExpr b, int i) { - result = b.getStmtList().getStatement(i) - or - i = b.getStmtList().getNumberOfStatements() and - result = b.getStmtList().getTailExpr() - } - class AsyncBlockExprTree extends StandardTree, PreOrderTree, PostOrderTree, AsyncBlockExpr { - override AstNode getChildNode(int i) { result = getBlockChildNode(this, i) } + override AstNode getChildNode(int i) { result = this.getStmtList().getStmtOrExpr(i) } override predicate propagatesAbnormal(AstNode child) { none() } } @@ -282,7 +275,7 @@ module ExprTrees { class BlockExprTree extends StandardPostOrderTree, BlockExpr { BlockExprTree() { not this.isAsync() } - override AstNode getChildNode(int i) { result = getBlockChildNode(this, i) } + override AstNode getChildNode(int i) { result = this.getStmtList().getStmtOrExpr(i) } override predicate propagatesAbnormal(AstNode child) { child = this.getChildNode(_) } } From 1236e2b8295cc3202e19ec76c433c374cb54bbb4 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 14:55:06 +0100 Subject: [PATCH 148/160] Rust: Add references to alternatives in the getStmtOrExpr methods. --- .../ql/lib/codeql/rust/elements/internal/StmtListImpl.qll | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll index 9120728dcbc..d56b4c49ce2 100644 --- a/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll +++ b/rust/ql/lib/codeql/rust/elements/internal/StmtListImpl.qll @@ -29,6 +29,10 @@ module Impl { class StmtList extends Generated::StmtList { /** * Gets the `index`th statement or expression of this statement list (0-based). + * + * This includes both the statements and any tail expression in the statement list. To access + * just the statements, use `getStatement`. To access just the tail expression, if any, + * use `getTailExpr`. */ AstNode getStmtOrExpr(int index) { result = this.getStatement(index) @@ -39,6 +43,10 @@ module Impl { /** * Gets any of the statements or expressions of this statement list. + * + * This includes both the statements and any tail expression in the statement list. To access + * just the statements, use `getAStatement`. To access just the tail expression, if any, + * use `getTailExpr`. */ final AstNode getAStmtOrExpr() { result = this.getStmtOrExpr(_) } From f5f61193a03b0c1697e28138503f3977d98fdac5 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:33:26 +0100 Subject: [PATCH 149/160] Delete change note --- go/ql/src/change-notes/2025-09-25-exponentiation-constants.md | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 go/ql/src/change-notes/2025-09-25-exponentiation-constants.md diff --git a/go/ql/src/change-notes/2025-09-25-exponentiation-constants.md b/go/ql/src/change-notes/2025-09-25-exponentiation-constants.md deleted file mode 100644 index cb6c5e43346..00000000000 --- a/go/ql/src/change-notes/2025-09-25-exponentiation-constants.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* The query `go/mistyped-exponentiation` now recognises constants whose initialisers are hex or octal constants, making them likely targets of the `^` bitwise-xor operator. From c7f6f2c8e1a6a42a23d84b215a87aa7e8c685f00 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Fri, 26 Sep 2025 16:40:25 +0100 Subject: [PATCH 150/160] Rust: Consistency fix for reusables/extractors.rst. --- docs/codeql/reusables/extractors.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/codeql/reusables/extractors.rst b/docs/codeql/reusables/extractors.rst index c09926666b0..4365d106258 100644 --- a/docs/codeql/reusables/extractors.rst +++ b/docs/codeql/reusables/extractors.rst @@ -20,7 +20,7 @@ - ``python`` * - Ruby - ``ruby`` - - Rust + * - Rust - ``rust`` * - Swift - ``swift`` From d2130a589be81b1575495e4e1da96b350d1bbbd5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 29 Sep 2025 10:28:45 +0000 Subject: [PATCH 151/160] Release preparation for version 2.23.2 --- actions/ql/lib/CHANGELOG.md | 4 ++++ actions/ql/lib/change-notes/released/0.4.18.md | 3 +++ actions/ql/lib/codeql-pack.release.yml | 2 +- actions/ql/lib/qlpack.yml | 2 +- actions/ql/src/CHANGELOG.md | 4 ++++ actions/ql/src/change-notes/released/0.6.10.md | 3 +++ actions/ql/src/codeql-pack.release.yml | 2 +- actions/ql/src/qlpack.yml | 2 +- cpp/ql/lib/CHANGELOG.md | 4 ++++ cpp/ql/lib/change-notes/released/5.6.1.md | 3 +++ cpp/ql/lib/codeql-pack.release.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/CHANGELOG.md | 4 ++++ cpp/ql/src/change-notes/released/1.5.1.md | 3 +++ cpp/ql/src/codeql-pack.release.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md | 4 ++++ .../Solorigate/lib/change-notes/released/1.7.49.md | 3 +++ .../ql/campaigns/Solorigate/lib/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/CHANGELOG.md | 4 ++++ .../Solorigate/src/change-notes/released/1.7.49.md | 3 +++ .../ql/campaigns/Solorigate/src/codeql-pack.release.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/CHANGELOG.md | 4 ++++ csharp/ql/lib/change-notes/released/5.2.5.md | 3 +++ csharp/ql/lib/codeql-pack.release.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/CHANGELOG.md | 7 +++++++ .../change-notes/2025-09-16-code-quality-doc-query.md | 4 ---- .../1.4.1.md} | 8 +++++--- csharp/ql/src/codeql-pack.release.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/CHANGELOG.md | 4 ++++ .../consistency-queries/change-notes/released/1.0.32.md | 3 +++ go/ql/consistency-queries/codeql-pack.release.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/CHANGELOG.md | 4 ++++ go/ql/lib/change-notes/released/4.3.5.md | 3 +++ go/ql/lib/codeql-pack.release.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/CHANGELOG.md | 4 ++++ go/ql/src/change-notes/released/1.4.6.md | 3 +++ go/ql/src/codeql-pack.release.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/CHANGELOG.md | 4 ++++ java/ql/lib/change-notes/released/7.7.1.md | 3 +++ java/ql/lib/codeql-pack.release.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/CHANGELOG.md | 4 ++++ java/ql/src/change-notes/released/1.8.1.md | 3 +++ java/ql/src/codeql-pack.release.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/CHANGELOG.md | 8 ++++++++ javascript/ql/lib/change-notes/2025-07-28-dynamodb.md | 4 ---- .../ql/lib/change-notes/2025-09-17-graphql-enhance.md | 4 ---- .../lib/change-notes/2025-09-19-graphql-type-object.md | 4 ---- javascript/ql/lib/change-notes/released/2.6.12.md | 7 +++++++ javascript/ql/lib/codeql-pack.release.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/CHANGELOG.md | 4 ++++ javascript/ql/src/change-notes/released/2.1.1.md | 3 +++ javascript/ql/src/codeql-pack.release.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/CHANGELOG.md | 4 ++++ misc/suite-helpers/change-notes/released/1.0.32.md | 3 +++ misc/suite-helpers/codeql-pack.release.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/CHANGELOG.md | 6 ++++++ .../4.0.16.md} | 9 +++++---- python/ql/lib/codeql-pack.release.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/CHANGELOG.md | 8 ++++++++ .../ql/src/change-notes/2025-08-19-signature-mismatch.md | 5 ----- ...-19-fix-unmatchable-dollar-and-caret-in-assertions.md | 5 ----- python/ql/src/change-notes/released/1.6.6.md | 7 +++++++ python/ql/src/codeql-pack.release.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/CHANGELOG.md | 6 ++++++ .../5.1.0.md} | 9 +++++---- ruby/ql/lib/codeql-pack.release.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/CHANGELOG.md | 4 ++++ ruby/ql/src/change-notes/released/1.4.6.md | 3 +++ ruby/ql/src/codeql-pack.release.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- rust/ql/lib/CHANGELOG.md | 9 +++++++++ .../{2025-09-19-parameter-mad.md => released/0.1.17.md} | 9 +++++---- rust/ql/lib/codeql-pack.release.yml | 2 +- rust/ql/lib/qlpack.yml | 2 +- rust/ql/src/CHANGELOG.md | 6 ++++++ rust/ql/src/change-notes/2025-09-15-non-https-url.md | 4 ---- rust/ql/src/change-notes/released/0.1.17.md | 5 +++++ rust/ql/src/codeql-pack.release.yml | 2 +- rust/ql/src/qlpack.yml | 2 +- shared/concepts/CHANGELOG.md | 4 ++++ shared/concepts/change-notes/released/0.0.6.md | 3 +++ shared/concepts/codeql-pack.release.yml | 2 +- shared/concepts/qlpack.yml | 2 +- shared/controlflow/CHANGELOG.md | 4 ++++ shared/controlflow/change-notes/released/2.0.16.md | 3 +++ shared/controlflow/codeql-pack.release.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/CHANGELOG.md | 4 ++++ shared/dataflow/change-notes/released/2.0.16.md | 3 +++ shared/dataflow/codeql-pack.release.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/CHANGELOG.md | 4 ++++ shared/mad/change-notes/released/1.0.32.md | 3 +++ shared/mad/codeql-pack.release.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/quantum/CHANGELOG.md | 4 ++++ shared/quantum/change-notes/released/0.0.10.md | 3 +++ shared/quantum/codeql-pack.release.yml | 2 +- shared/quantum/qlpack.yml | 2 +- shared/rangeanalysis/CHANGELOG.md | 4 ++++ shared/rangeanalysis/change-notes/released/1.0.32.md | 3 +++ shared/rangeanalysis/codeql-pack.release.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/CHANGELOG.md | 4 ++++ shared/regex/change-notes/released/1.0.32.md | 3 +++ shared/regex/codeql-pack.release.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/CHANGELOG.md | 4 ++++ shared/ssa/change-notes/released/2.0.8.md | 3 +++ shared/ssa/codeql-pack.release.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/CHANGELOG.md | 4 ++++ shared/threat-models/change-notes/released/1.0.32.md | 3 +++ shared/threat-models/codeql-pack.release.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/CHANGELOG.md | 4 ++++ shared/tutorial/change-notes/released/1.0.32.md | 3 +++ shared/tutorial/codeql-pack.release.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/CHANGELOG.md | 4 ++++ shared/typeflow/change-notes/released/1.0.32.md | 3 +++ shared/typeflow/codeql-pack.release.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typeinference/CHANGELOG.md | 4 ++++ shared/typeinference/change-notes/released/0.0.13.md | 3 +++ shared/typeinference/codeql-pack.release.yml | 2 +- shared/typeinference/qlpack.yml | 2 +- shared/typetracking/CHANGELOG.md | 4 ++++ shared/typetracking/change-notes/released/2.0.16.md | 3 +++ shared/typetracking/codeql-pack.release.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/CHANGELOG.md | 4 ++++ shared/typos/change-notes/released/1.0.32.md | 3 +++ shared/typos/codeql-pack.release.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/CHANGELOG.md | 4 ++++ shared/util/change-notes/released/2.0.19.md | 3 +++ shared/util/codeql-pack.release.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/CHANGELOG.md | 4 ++++ shared/xml/change-notes/released/1.0.32.md | 3 +++ shared/xml/codeql-pack.release.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/CHANGELOG.md | 4 ++++ shared/yaml/change-notes/released/1.0.32.md | 3 +++ shared/yaml/codeql-pack.release.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/CHANGELOG.md | 4 ++++ swift/ql/lib/change-notes/released/5.0.8.md | 3 +++ swift/ql/lib/codeql-pack.release.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/CHANGELOG.md | 4 ++++ swift/ql/src/change-notes/released/1.2.6.md | 3 +++ swift/ql/src/codeql-pack.release.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 171 files changed, 409 insertions(+), 127 deletions(-) create mode 100644 actions/ql/lib/change-notes/released/0.4.18.md create mode 100644 actions/ql/src/change-notes/released/0.6.10.md create mode 100644 cpp/ql/lib/change-notes/released/5.6.1.md create mode 100644 cpp/ql/src/change-notes/released/1.5.1.md create mode 100644 csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.49.md create mode 100644 csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.49.md create mode 100644 csharp/ql/lib/change-notes/released/5.2.5.md delete mode 100644 csharp/ql/src/change-notes/2025-09-16-code-quality-doc-query.md rename csharp/ql/src/change-notes/{2025-09-17-nullguard-pattern.md => released/1.4.1.md} (55%) create mode 100644 go/ql/consistency-queries/change-notes/released/1.0.32.md create mode 100644 go/ql/lib/change-notes/released/4.3.5.md create mode 100644 go/ql/src/change-notes/released/1.4.6.md create mode 100644 java/ql/lib/change-notes/released/7.7.1.md create mode 100644 java/ql/src/change-notes/released/1.8.1.md delete mode 100644 javascript/ql/lib/change-notes/2025-07-28-dynamodb.md delete mode 100644 javascript/ql/lib/change-notes/2025-09-17-graphql-enhance.md delete mode 100644 javascript/ql/lib/change-notes/2025-09-19-graphql-type-object.md create mode 100644 javascript/ql/lib/change-notes/released/2.6.12.md create mode 100644 javascript/ql/src/change-notes/released/2.1.1.md create mode 100644 misc/suite-helpers/change-notes/released/1.0.32.md rename python/ql/lib/change-notes/{2025-08-11-jump-step-global-nested.md => released/4.0.16.md} (68%) delete mode 100644 python/ql/src/change-notes/2025-08-19-signature-mismatch.md delete mode 100644 python/ql/src/change-notes/2025-09-19-fix-unmatchable-dollar-and-caret-in-assertions.md create mode 100644 python/ql/src/change-notes/released/1.6.6.md rename ruby/ql/lib/change-notes/{2025-09-15-grape-framework-support.md => released/5.1.0.md} (70%) create mode 100644 ruby/ql/src/change-notes/released/1.4.6.md rename rust/ql/lib/change-notes/{2025-09-19-parameter-mad.md => released/0.1.17.md} (85%) delete mode 100644 rust/ql/src/change-notes/2025-09-15-non-https-url.md create mode 100644 rust/ql/src/change-notes/released/0.1.17.md create mode 100644 shared/concepts/change-notes/released/0.0.6.md create mode 100644 shared/controlflow/change-notes/released/2.0.16.md create mode 100644 shared/dataflow/change-notes/released/2.0.16.md create mode 100644 shared/mad/change-notes/released/1.0.32.md create mode 100644 shared/quantum/change-notes/released/0.0.10.md create mode 100644 shared/rangeanalysis/change-notes/released/1.0.32.md create mode 100644 shared/regex/change-notes/released/1.0.32.md create mode 100644 shared/ssa/change-notes/released/2.0.8.md create mode 100644 shared/threat-models/change-notes/released/1.0.32.md create mode 100644 shared/tutorial/change-notes/released/1.0.32.md create mode 100644 shared/typeflow/change-notes/released/1.0.32.md create mode 100644 shared/typeinference/change-notes/released/0.0.13.md create mode 100644 shared/typetracking/change-notes/released/2.0.16.md create mode 100644 shared/typos/change-notes/released/1.0.32.md create mode 100644 shared/util/change-notes/released/2.0.19.md create mode 100644 shared/xml/change-notes/released/1.0.32.md create mode 100644 shared/yaml/change-notes/released/1.0.32.md create mode 100644 swift/ql/lib/change-notes/released/5.0.8.md create mode 100644 swift/ql/src/change-notes/released/1.2.6.md diff --git a/actions/ql/lib/CHANGELOG.md b/actions/ql/lib/CHANGELOG.md index 60f6a45ea94..e6ae9a82059 100644 --- a/actions/ql/lib/CHANGELOG.md +++ b/actions/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.18 + +No user-facing changes. + ## 0.4.17 No user-facing changes. diff --git a/actions/ql/lib/change-notes/released/0.4.18.md b/actions/ql/lib/change-notes/released/0.4.18.md new file mode 100644 index 00000000000..a6a7b2e276b --- /dev/null +++ b/actions/ql/lib/change-notes/released/0.4.18.md @@ -0,0 +1,3 @@ +## 0.4.18 + +No user-facing changes. diff --git a/actions/ql/lib/codeql-pack.release.yml b/actions/ql/lib/codeql-pack.release.yml index d5b31a0cac9..1a848f92899 100644 --- a/actions/ql/lib/codeql-pack.release.yml +++ b/actions/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.4.17 +lastReleaseVersion: 0.4.18 diff --git a/actions/ql/lib/qlpack.yml b/actions/ql/lib/qlpack.yml index 266007af096..bfebfa99d04 100644 --- a/actions/ql/lib/qlpack.yml +++ b/actions/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-all -version: 0.4.18-dev +version: 0.4.18 library: true warnOnImplicitThis: true dependencies: diff --git a/actions/ql/src/CHANGELOG.md b/actions/ql/src/CHANGELOG.md index 78b4591c521..534ba89566b 100644 --- a/actions/ql/src/CHANGELOG.md +++ b/actions/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.6.10 + +No user-facing changes. + ## 0.6.9 ### Minor Analysis Improvements diff --git a/actions/ql/src/change-notes/released/0.6.10.md b/actions/ql/src/change-notes/released/0.6.10.md new file mode 100644 index 00000000000..048cd0c98ba --- /dev/null +++ b/actions/ql/src/change-notes/released/0.6.10.md @@ -0,0 +1,3 @@ +## 0.6.10 + +No user-facing changes. diff --git a/actions/ql/src/codeql-pack.release.yml b/actions/ql/src/codeql-pack.release.yml index f03da398190..c2eebb652b0 100644 --- a/actions/ql/src/codeql-pack.release.yml +++ b/actions/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.6.9 +lastReleaseVersion: 0.6.10 diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml index e4a69c7cd61..9dba67fea76 100644 --- a/actions/ql/src/qlpack.yml +++ b/actions/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-queries -version: 0.6.10-dev +version: 0.6.10 library: false warnOnImplicitThis: true groups: [actions, queries] diff --git a/cpp/ql/lib/CHANGELOG.md b/cpp/ql/lib/CHANGELOG.md index cfe24937b74..0909c8e3c88 100644 --- a/cpp/ql/lib/CHANGELOG.md +++ b/cpp/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.6.1 + +No user-facing changes. + ## 5.6.0 ### Deprecated APIs diff --git a/cpp/ql/lib/change-notes/released/5.6.1.md b/cpp/ql/lib/change-notes/released/5.6.1.md new file mode 100644 index 00000000000..368d902c7fe --- /dev/null +++ b/cpp/ql/lib/change-notes/released/5.6.1.md @@ -0,0 +1,3 @@ +## 5.6.1 + +No user-facing changes. diff --git a/cpp/ql/lib/codeql-pack.release.yml b/cpp/ql/lib/codeql-pack.release.yml index df73323b21f..2dcac412aa9 100644 --- a/cpp/ql/lib/codeql-pack.release.yml +++ b/cpp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.6.0 +lastReleaseVersion: 5.6.1 diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 63500a12a2f..23bf4d8fc9e 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 5.6.1-dev +version: 5.6.1 groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/CHANGELOG.md b/cpp/ql/src/CHANGELOG.md index 0cafbd23191..39549ed1bdc 100644 --- a/cpp/ql/src/CHANGELOG.md +++ b/cpp/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.5.1 + +No user-facing changes. + ## 1.5.0 ### Major Analysis Improvements diff --git a/cpp/ql/src/change-notes/released/1.5.1.md b/cpp/ql/src/change-notes/released/1.5.1.md new file mode 100644 index 00000000000..7b24a64aca3 --- /dev/null +++ b/cpp/ql/src/change-notes/released/1.5.1.md @@ -0,0 +1,3 @@ +## 1.5.1 + +No user-facing changes. diff --git a/cpp/ql/src/codeql-pack.release.yml b/cpp/ql/src/codeql-pack.release.yml index 639f80c4341..c5775c46013 100644 --- a/cpp/ql/src/codeql-pack.release.yml +++ b/cpp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.5.0 +lastReleaseVersion: 1.5.1 diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 8b6b27302cc..7322e2571d1 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.5.1-dev +version: 1.5.1 groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md index 41b8b166a6c..bcfd38e1494 100644 --- a/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.49 + +No user-facing changes. + ## 1.7.48 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.49.md b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.49.md new file mode 100644 index 00000000000..431bff76c0b --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/lib/change-notes/released/1.7.49.md @@ -0,0 +1,3 @@ +## 1.7.49 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml index f5fe8023097..fe16fdfefdc 100644 --- a/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.48 +lastReleaseVersion: 1.7.49 diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index bc2dd9a229c..02e6cddfc17 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.49-dev +version: 1.7.49 groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md index 41b8b166a6c..bcfd38e1494 100644 --- a/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md +++ b/csharp/ql/campaigns/Solorigate/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.7.49 + +No user-facing changes. + ## 1.7.48 No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.49.md b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.49.md new file mode 100644 index 00000000000..431bff76c0b --- /dev/null +++ b/csharp/ql/campaigns/Solorigate/src/change-notes/released/1.7.49.md @@ -0,0 +1,3 @@ +## 1.7.49 + +No user-facing changes. diff --git a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml index f5fe8023097..fe16fdfefdc 100644 --- a/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml +++ b/csharp/ql/campaigns/Solorigate/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.7.48 +lastReleaseVersion: 1.7.49 diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 82cad1a6472..84e6c8ef7e0 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.49-dev +version: 1.7.49 groups: - csharp - solorigate diff --git a/csharp/ql/lib/CHANGELOG.md b/csharp/ql/lib/CHANGELOG.md index cb639225e7d..095eab5cdba 100644 --- a/csharp/ql/lib/CHANGELOG.md +++ b/csharp/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.2.5 + +No user-facing changes. + ## 5.2.4 No user-facing changes. diff --git a/csharp/ql/lib/change-notes/released/5.2.5.md b/csharp/ql/lib/change-notes/released/5.2.5.md new file mode 100644 index 00000000000..bd0e1157099 --- /dev/null +++ b/csharp/ql/lib/change-notes/released/5.2.5.md @@ -0,0 +1,3 @@ +## 5.2.5 + +No user-facing changes. diff --git a/csharp/ql/lib/codeql-pack.release.yml b/csharp/ql/lib/codeql-pack.release.yml index fc4dc64578b..63222f8b4a0 100644 --- a/csharp/ql/lib/codeql-pack.release.yml +++ b/csharp/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.2.4 +lastReleaseVersion: 5.2.5 diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index f5795e12558..aba9ee98b5a 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 5.2.5-dev +version: 5.2.5 groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index e044a3dbb4f..e432045f72e 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -1,3 +1,10 @@ +## 1.4.1 + +### Minor Analysis Improvements + +* The modeling of null guards based on complex pattern expressions has been improved, which in turn improves the query `cs/dereferenced-value-may-be-null` by removing false positives. +* Remove the query `cs/xmldoc/missing-summary` from the `code-quality` suite (align with other languages). + ## 1.4.0 ### Deprecated Queries diff --git a/csharp/ql/src/change-notes/2025-09-16-code-quality-doc-query.md b/csharp/ql/src/change-notes/2025-09-16-code-quality-doc-query.md deleted file mode 100644 index 8972be616b9..00000000000 --- a/csharp/ql/src/change-notes/2025-09-16-code-quality-doc-query.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Remove the query `cs/xmldoc/missing-summary` from the `code-quality` suite (align with other languages). diff --git a/csharp/ql/src/change-notes/2025-09-17-nullguard-pattern.md b/csharp/ql/src/change-notes/released/1.4.1.md similarity index 55% rename from csharp/ql/src/change-notes/2025-09-17-nullguard-pattern.md rename to csharp/ql/src/change-notes/released/1.4.1.md index 49b76c25b0b..48b31092714 100644 --- a/csharp/ql/src/change-notes/2025-09-17-nullguard-pattern.md +++ b/csharp/ql/src/change-notes/released/1.4.1.md @@ -1,4 +1,6 @@ ---- -category: minorAnalysis ---- +## 1.4.1 + +### Minor Analysis Improvements + * The modeling of null guards based on complex pattern expressions has been improved, which in turn improves the query `cs/dereferenced-value-may-be-null` by removing false positives. +* Remove the query `cs/xmldoc/missing-summary` from the `code-quality` suite (align with other languages). diff --git a/csharp/ql/src/codeql-pack.release.yml b/csharp/ql/src/codeql-pack.release.yml index b8b2e97d508..43ccf4467be 100644 --- a/csharp/ql/src/codeql-pack.release.yml +++ b/csharp/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.4.0 +lastReleaseVersion: 1.4.1 diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 724ec4c0097..7ecdec07f35 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.4.1-dev +version: 1.4.1 groups: - csharp - queries diff --git a/go/ql/consistency-queries/CHANGELOG.md b/go/ql/consistency-queries/CHANGELOG.md index d5040623557..331bb4c220e 100644 --- a/go/ql/consistency-queries/CHANGELOG.md +++ b/go/ql/consistency-queries/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.32 + +No user-facing changes. + ## 1.0.31 No user-facing changes. diff --git a/go/ql/consistency-queries/change-notes/released/1.0.32.md b/go/ql/consistency-queries/change-notes/released/1.0.32.md new file mode 100644 index 00000000000..05c4073731c --- /dev/null +++ b/go/ql/consistency-queries/change-notes/released/1.0.32.md @@ -0,0 +1,3 @@ +## 1.0.32 + +No user-facing changes. diff --git a/go/ql/consistency-queries/codeql-pack.release.yml b/go/ql/consistency-queries/codeql-pack.release.yml index f5bdc98ffc8..7bc5c51ba7b 100644 --- a/go/ql/consistency-queries/codeql-pack.release.yml +++ b/go/ql/consistency-queries/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.31 +lastReleaseVersion: 1.0.32 diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 3a3f60920be..3b1e2d9586b 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 1.0.32-dev +version: 1.0.32 groups: - go - queries diff --git a/go/ql/lib/CHANGELOG.md b/go/ql/lib/CHANGELOG.md index 50d61186f73..adf218a99e4 100644 --- a/go/ql/lib/CHANGELOG.md +++ b/go/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 4.3.5 + +No user-facing changes. + ## 4.3.4 ### Minor Analysis Improvements diff --git a/go/ql/lib/change-notes/released/4.3.5.md b/go/ql/lib/change-notes/released/4.3.5.md new file mode 100644 index 00000000000..e386c2fbd98 --- /dev/null +++ b/go/ql/lib/change-notes/released/4.3.5.md @@ -0,0 +1,3 @@ +## 4.3.5 + +No user-facing changes. diff --git a/go/ql/lib/codeql-pack.release.yml b/go/ql/lib/codeql-pack.release.yml index f755e0936a7..d6a08512942 100644 --- a/go/ql/lib/codeql-pack.release.yml +++ b/go/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 4.3.4 +lastReleaseVersion: 4.3.5 diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index 1e8bdd280f7..bc9bf12c80c 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 4.3.5-dev +version: 4.3.5 groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/CHANGELOG.md b/go/ql/src/CHANGELOG.md index c3b9c32ff32..65d6436fce3 100644 --- a/go/ql/src/CHANGELOG.md +++ b/go/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.4.6 + +No user-facing changes. + ## 1.4.5 No user-facing changes. diff --git a/go/ql/src/change-notes/released/1.4.6.md b/go/ql/src/change-notes/released/1.4.6.md new file mode 100644 index 00000000000..5146f9e1cbf --- /dev/null +++ b/go/ql/src/change-notes/released/1.4.6.md @@ -0,0 +1,3 @@ +## 1.4.6 + +No user-facing changes. diff --git a/go/ql/src/codeql-pack.release.yml b/go/ql/src/codeql-pack.release.yml index a74b6b08d86..3b00bbce928 100644 --- a/go/ql/src/codeql-pack.release.yml +++ b/go/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.4.5 +lastReleaseVersion: 1.4.6 diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 9320b29d8e8..816d4b95867 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.4.6-dev +version: 1.4.6 groups: - go - queries diff --git a/java/ql/lib/CHANGELOG.md b/java/ql/lib/CHANGELOG.md index a6b4649e42e..0e74414917b 100644 --- a/java/ql/lib/CHANGELOG.md +++ b/java/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 7.7.1 + +No user-facing changes. + ## 7.7.0 ### New Features diff --git a/java/ql/lib/change-notes/released/7.7.1.md b/java/ql/lib/change-notes/released/7.7.1.md new file mode 100644 index 00000000000..7349fc621cc --- /dev/null +++ b/java/ql/lib/change-notes/released/7.7.1.md @@ -0,0 +1,3 @@ +## 7.7.1 + +No user-facing changes. diff --git a/java/ql/lib/codeql-pack.release.yml b/java/ql/lib/codeql-pack.release.yml index 5c876a864fc..c94dbb3cd65 100644 --- a/java/ql/lib/codeql-pack.release.yml +++ b/java/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 7.7.0 +lastReleaseVersion: 7.7.1 diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 3009b1b327f..7d0153cc566 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 7.7.1-dev +version: 7.7.1 groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/CHANGELOG.md b/java/ql/src/CHANGELOG.md index 022442a1628..1e6df88fc31 100644 --- a/java/ql/src/CHANGELOG.md +++ b/java/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.8.1 + +No user-facing changes. + ## 1.8.0 ### Major Analysis Improvements diff --git a/java/ql/src/change-notes/released/1.8.1.md b/java/ql/src/change-notes/released/1.8.1.md new file mode 100644 index 00000000000..0b1a7cdad10 --- /dev/null +++ b/java/ql/src/change-notes/released/1.8.1.md @@ -0,0 +1,3 @@ +## 1.8.1 + +No user-facing changes. diff --git a/java/ql/src/codeql-pack.release.yml b/java/ql/src/codeql-pack.release.yml index dc8a37cc443..28a7c123ae8 100644 --- a/java/ql/src/codeql-pack.release.yml +++ b/java/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.8.0 +lastReleaseVersion: 1.8.1 diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index 01bf070bb07..bbfafc65503 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.8.1-dev +version: 1.8.1 groups: - java - queries diff --git a/javascript/ql/lib/CHANGELOG.md b/javascript/ql/lib/CHANGELOG.md index b98534e791d..975d14e1098 100644 --- a/javascript/ql/lib/CHANGELOG.md +++ b/javascript/ql/lib/CHANGELOG.md @@ -1,3 +1,11 @@ +## 2.6.12 + +### Minor Analysis Improvements + +* Added modeling of `GraphQLObjectType` resolver function parameters as remote sources. +* Support for the [graphql](https://www.npmjs.com/package/graphql) library has been improved. Data flow from GraphQL query sources and variables to resolver function parameters is now tracked. +* Added support for the `aws-sdk` and `@aws-sdk/client-dynamodb`, `@aws-sdk/client-athena`, `@aws-sdk/client-s3`, and `@aws-sdk/client-rds-data` packages. + ## 2.6.11 ### Minor Analysis Improvements diff --git a/javascript/ql/lib/change-notes/2025-07-28-dynamodb.md b/javascript/ql/lib/change-notes/2025-07-28-dynamodb.md deleted file mode 100644 index bbf5d57163a..00000000000 --- a/javascript/ql/lib/change-notes/2025-07-28-dynamodb.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added support for the `aws-sdk` and `@aws-sdk/client-dynamodb`, `@aws-sdk/client-athena`, `@aws-sdk/client-s3`, and `@aws-sdk/client-rds-data` packages. diff --git a/javascript/ql/lib/change-notes/2025-09-17-graphql-enhance.md b/javascript/ql/lib/change-notes/2025-09-17-graphql-enhance.md deleted file mode 100644 index cb0b886a6f7..00000000000 --- a/javascript/ql/lib/change-notes/2025-09-17-graphql-enhance.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Support for the [graphql](https://www.npmjs.com/package/graphql) library has been improved. Data flow from GraphQL query sources and variables to resolver function parameters is now tracked. diff --git a/javascript/ql/lib/change-notes/2025-09-19-graphql-type-object.md b/javascript/ql/lib/change-notes/2025-09-19-graphql-type-object.md deleted file mode 100644 index 6afa4ece331..00000000000 --- a/javascript/ql/lib/change-notes/2025-09-19-graphql-type-object.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: minorAnalysis ---- -* Added modeling of `GraphQLObjectType` resolver function parameters as remote sources. diff --git a/javascript/ql/lib/change-notes/released/2.6.12.md b/javascript/ql/lib/change-notes/released/2.6.12.md new file mode 100644 index 00000000000..adc136621d8 --- /dev/null +++ b/javascript/ql/lib/change-notes/released/2.6.12.md @@ -0,0 +1,7 @@ +## 2.6.12 + +### Minor Analysis Improvements + +* Added modeling of `GraphQLObjectType` resolver function parameters as remote sources. +* Support for the [graphql](https://www.npmjs.com/package/graphql) library has been improved. Data flow from GraphQL query sources and variables to resolver function parameters is now tracked. +* Added support for the `aws-sdk` and `@aws-sdk/client-dynamodb`, `@aws-sdk/client-athena`, `@aws-sdk/client-s3`, and `@aws-sdk/client-rds-data` packages. diff --git a/javascript/ql/lib/codeql-pack.release.yml b/javascript/ql/lib/codeql-pack.release.yml index a31eb42966c..8b34428a845 100644 --- a/javascript/ql/lib/codeql-pack.release.yml +++ b/javascript/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.6.11 +lastReleaseVersion: 2.6.12 diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 1d05d1003f3..74ccf251956 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.6.12-dev +version: 2.6.12 groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/CHANGELOG.md b/javascript/ql/src/CHANGELOG.md index 4067c050c2a..46aae437f77 100644 --- a/javascript/ql/src/CHANGELOG.md +++ b/javascript/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.1.1 + +No user-facing changes. + ## 2.1.0 ### Major Analysis Improvements diff --git a/javascript/ql/src/change-notes/released/2.1.1.md b/javascript/ql/src/change-notes/released/2.1.1.md new file mode 100644 index 00000000000..f023e9166c2 --- /dev/null +++ b/javascript/ql/src/change-notes/released/2.1.1.md @@ -0,0 +1,3 @@ +## 2.1.1 + +No user-facing changes. diff --git a/javascript/ql/src/codeql-pack.release.yml b/javascript/ql/src/codeql-pack.release.yml index 487a1a58b2b..576c2ea18d6 100644 --- a/javascript/ql/src/codeql-pack.release.yml +++ b/javascript/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.1.0 +lastReleaseVersion: 2.1.1 diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index 916ad1339b2..cafde25bbf9 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 2.1.1-dev +version: 2.1.1 groups: - javascript - queries diff --git a/misc/suite-helpers/CHANGELOG.md b/misc/suite-helpers/CHANGELOG.md index 6b54042fef3..4cbaa48190d 100644 --- a/misc/suite-helpers/CHANGELOG.md +++ b/misc/suite-helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.32 + +No user-facing changes. + ## 1.0.31 No user-facing changes. diff --git a/misc/suite-helpers/change-notes/released/1.0.32.md b/misc/suite-helpers/change-notes/released/1.0.32.md new file mode 100644 index 00000000000..05c4073731c --- /dev/null +++ b/misc/suite-helpers/change-notes/released/1.0.32.md @@ -0,0 +1,3 @@ +## 1.0.32 + +No user-facing changes. diff --git a/misc/suite-helpers/codeql-pack.release.yml b/misc/suite-helpers/codeql-pack.release.yml index f5bdc98ffc8..7bc5c51ba7b 100644 --- a/misc/suite-helpers/codeql-pack.release.yml +++ b/misc/suite-helpers/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.31 +lastReleaseVersion: 1.0.32 diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 72c2f165759..7d71d83613d 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.32-dev +version: 1.0.32 groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/CHANGELOG.md b/python/ql/lib/CHANGELOG.md index 6a4fefd4446..070309c08a0 100644 --- a/python/ql/lib/CHANGELOG.md +++ b/python/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 4.0.16 + +### Minor Analysis Improvements + +* Data flow tracking through global variables now supports nested field access patterns such as `global_var.obj.field`. This improves the precision of taint tracking analysis when data flows through complex global variable structures. + ## 4.0.15 No user-facing changes. diff --git a/python/ql/lib/change-notes/2025-08-11-jump-step-global-nested.md b/python/ql/lib/change-notes/released/4.0.16.md similarity index 68% rename from python/ql/lib/change-notes/2025-08-11-jump-step-global-nested.md rename to python/ql/lib/change-notes/released/4.0.16.md index 4109bb78825..025815a5c02 100644 --- a/python/ql/lib/change-notes/2025-08-11-jump-step-global-nested.md +++ b/python/ql/lib/change-notes/released/4.0.16.md @@ -1,4 +1,5 @@ ---- -category: minorAnalysis ---- -* Data flow tracking through global variables now supports nested field access patterns such as `global_var.obj.field`. This improves the precision of taint tracking analysis when data flows through complex global variable structures. \ No newline at end of file +## 4.0.16 + +### Minor Analysis Improvements + +* Data flow tracking through global variables now supports nested field access patterns such as `global_var.obj.field`. This improves the precision of taint tracking analysis when data flows through complex global variable structures. diff --git a/python/ql/lib/codeql-pack.release.yml b/python/ql/lib/codeql-pack.release.yml index eef62765883..916d99df3ad 100644 --- a/python/ql/lib/codeql-pack.release.yml +++ b/python/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 4.0.15 +lastReleaseVersion: 4.0.16 diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 61875fc7f4e..5eba946c3cf 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 4.0.16-dev +version: 4.0.16 groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/CHANGELOG.md b/python/ql/src/CHANGELOG.md index de3fc1ddf2b..e620dee4fca 100644 --- a/python/ql/src/CHANGELOG.md +++ b/python/ql/src/CHANGELOG.md @@ -1,3 +1,11 @@ +## 1.6.6 + +### Minor Analysis Improvements + +- The queries that check for unmatchable `$` and `^` in regular expressions did not account correctly for occurrences inside lookahead and lookbehind assertions. These occurrences are now handled correctly, eliminating this source of false positives. +* The `py/inheritance/signature-mismatch` query has been modernized. It produces more precise results and more descriptive alert messages. +* The `py/inheritance/incorrect-overriding-signature` query has been deprecated. Its results have been consolidated into the `py/inheritance/signature-mismatch` query. + ## 1.6.5 ### Minor Analysis Improvements diff --git a/python/ql/src/change-notes/2025-08-19-signature-mismatch.md b/python/ql/src/change-notes/2025-08-19-signature-mismatch.md deleted file mode 100644 index 60c3efa32eb..00000000000 --- a/python/ql/src/change-notes/2025-08-19-signature-mismatch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- -* The `py/inheritance/signature-mismatch` query has been modernized. It produces more precise results and more descriptive alert messages. -* The `py/inheritance/incorrect-overriding-signature` query has been deprecated. Its results have been consolidated into the `py/inheritance/signature-mismatch` query. \ No newline at end of file diff --git a/python/ql/src/change-notes/2025-09-19-fix-unmatchable-dollar-and-caret-in-assertions.md b/python/ql/src/change-notes/2025-09-19-fix-unmatchable-dollar-and-caret-in-assertions.md deleted file mode 100644 index cf63dd9ed4d..00000000000 --- a/python/ql/src/change-notes/2025-09-19-fix-unmatchable-dollar-and-caret-in-assertions.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -category: minorAnalysis ---- - -- The queries that check for unmatchable `$` and `^` in regular expressions did not account correctly for occurrences inside lookahead and lookbehind assertions. These occurrences are now handled correctly, eliminating this source of false positives. diff --git a/python/ql/src/change-notes/released/1.6.6.md b/python/ql/src/change-notes/released/1.6.6.md new file mode 100644 index 00000000000..e1b0e3c4955 --- /dev/null +++ b/python/ql/src/change-notes/released/1.6.6.md @@ -0,0 +1,7 @@ +## 1.6.6 + +### Minor Analysis Improvements + +- The queries that check for unmatchable `$` and `^` in regular expressions did not account correctly for occurrences inside lookahead and lookbehind assertions. These occurrences are now handled correctly, eliminating this source of false positives. +* The `py/inheritance/signature-mismatch` query has been modernized. It produces more precise results and more descriptive alert messages. +* The `py/inheritance/incorrect-overriding-signature` query has been deprecated. Its results have been consolidated into the `py/inheritance/signature-mismatch` query. diff --git a/python/ql/src/codeql-pack.release.yml b/python/ql/src/codeql-pack.release.yml index 03153270557..f8e54f30a67 100644 --- a/python/ql/src/codeql-pack.release.yml +++ b/python/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.6.5 +lastReleaseVersion: 1.6.6 diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index edf6366c64b..b42e054bdad 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.6.6-dev +version: 1.6.6 groups: - python - queries diff --git a/ruby/ql/lib/CHANGELOG.md b/ruby/ql/lib/CHANGELOG.md index b9333de9c5d..a62232991b8 100644 --- a/ruby/ql/lib/CHANGELOG.md +++ b/ruby/ql/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 5.1.0 + +### New Features + +* Initial modeling for the Ruby Grape framework in `Grape.qll` has been added to detect API endpoints, parameters, and headers within Grape API classes. + ## 5.0.4 No user-facing changes. diff --git a/ruby/ql/lib/change-notes/2025-09-15-grape-framework-support.md b/ruby/ql/lib/change-notes/released/5.1.0.md similarity index 70% rename from ruby/ql/lib/change-notes/2025-09-15-grape-framework-support.md rename to ruby/ql/lib/change-notes/released/5.1.0.md index 08ceed887f2..4958aaac95f 100644 --- a/ruby/ql/lib/change-notes/2025-09-15-grape-framework-support.md +++ b/ruby/ql/lib/change-notes/released/5.1.0.md @@ -1,4 +1,5 @@ ---- -category: feature ---- -* Initial modeling for the Ruby Grape framework in `Grape.qll` has been added to detect API endpoints, parameters, and headers within Grape API classes. \ No newline at end of file +## 5.1.0 + +### New Features + +* Initial modeling for the Ruby Grape framework in `Grape.qll` has been added to detect API endpoints, parameters, and headers within Grape API classes. diff --git a/ruby/ql/lib/codeql-pack.release.yml b/ruby/ql/lib/codeql-pack.release.yml index 8cb0167caf0..dd8d287d010 100644 --- a/ruby/ql/lib/codeql-pack.release.yml +++ b/ruby/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.0.4 +lastReleaseVersion: 5.1.0 diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index a2288bd3799..6dd0db034c3 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 5.0.5-dev +version: 5.1.0 groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/CHANGELOG.md b/ruby/ql/src/CHANGELOG.md index 40209ec84bd..7811ea73f86 100644 --- a/ruby/ql/src/CHANGELOG.md +++ b/ruby/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.4.6 + +No user-facing changes. + ## 1.4.5 No user-facing changes. diff --git a/ruby/ql/src/change-notes/released/1.4.6.md b/ruby/ql/src/change-notes/released/1.4.6.md new file mode 100644 index 00000000000..5146f9e1cbf --- /dev/null +++ b/ruby/ql/src/change-notes/released/1.4.6.md @@ -0,0 +1,3 @@ +## 1.4.6 + +No user-facing changes. diff --git a/ruby/ql/src/codeql-pack.release.yml b/ruby/ql/src/codeql-pack.release.yml index a74b6b08d86..3b00bbce928 100644 --- a/ruby/ql/src/codeql-pack.release.yml +++ b/ruby/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.4.5 +lastReleaseVersion: 1.4.6 diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index 084d64e8b02..ce46bf8c37a 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.4.6-dev +version: 1.4.6 groups: - ruby - queries diff --git a/rust/ql/lib/CHANGELOG.md b/rust/ql/lib/CHANGELOG.md index 809479e5fec..ec04cd624a7 100644 --- a/rust/ql/lib/CHANGELOG.md +++ b/rust/ql/lib/CHANGELOG.md @@ -1,3 +1,12 @@ +## 0.1.17 + +### New Features + +* The models-as-data format for sources now supports access paths of the form + `Argument[i].Parameter[j]`. This denotes that the source passes tainted data to + the `j`th parameter of its `i`th argument (which must be a function or a + closure). + ## 0.1.16 ### Minor Analysis Improvements diff --git a/rust/ql/lib/change-notes/2025-09-19-parameter-mad.md b/rust/ql/lib/change-notes/released/0.1.17.md similarity index 85% rename from rust/ql/lib/change-notes/2025-09-19-parameter-mad.md rename to rust/ql/lib/change-notes/released/0.1.17.md index fa3970790fa..a2707c04150 100644 --- a/rust/ql/lib/change-notes/2025-09-19-parameter-mad.md +++ b/rust/ql/lib/change-notes/released/0.1.17.md @@ -1,7 +1,8 @@ ---- -category: feature ---- +## 0.1.17 + +### New Features + * The models-as-data format for sources now supports access paths of the form `Argument[i].Parameter[j]`. This denotes that the source passes tainted data to the `j`th parameter of its `i`th argument (which must be a function or a - closure). \ No newline at end of file + closure). diff --git a/rust/ql/lib/codeql-pack.release.yml b/rust/ql/lib/codeql-pack.release.yml index a01dca92161..eddeebba7bf 100644 --- a/rust/ql/lib/codeql-pack.release.yml +++ b/rust/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.16 +lastReleaseVersion: 0.1.17 diff --git a/rust/ql/lib/qlpack.yml b/rust/ql/lib/qlpack.yml index 421a604aa3d..3c3ba893b14 100644 --- a/rust/ql/lib/qlpack.yml +++ b/rust/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-all -version: 0.1.17-dev +version: 0.1.17 groups: rust extractor: rust dbscheme: rust.dbscheme diff --git a/rust/ql/src/CHANGELOG.md b/rust/ql/src/CHANGELOG.md index 48f64efbcdb..29117e66d4c 100644 --- a/rust/ql/src/CHANGELOG.md +++ b/rust/ql/src/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.1.17 + +### New Queries + +* Added a new query, `rust/non-https-url`, for detecting the use of non-HTTPS URLs that can be intercepted by third parties. + ## 0.1.16 ### New Queries diff --git a/rust/ql/src/change-notes/2025-09-15-non-https-url.md b/rust/ql/src/change-notes/2025-09-15-non-https-url.md deleted file mode 100644 index c4ab664f732..00000000000 --- a/rust/ql/src/change-notes/2025-09-15-non-https-url.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -category: newQuery ---- -* Added a new query, `rust/non-https-url`, for detecting the use of non-HTTPS URLs that can be intercepted by third parties. \ No newline at end of file diff --git a/rust/ql/src/change-notes/released/0.1.17.md b/rust/ql/src/change-notes/released/0.1.17.md new file mode 100644 index 00000000000..13cfb719c3c --- /dev/null +++ b/rust/ql/src/change-notes/released/0.1.17.md @@ -0,0 +1,5 @@ +## 0.1.17 + +### New Queries + +* Added a new query, `rust/non-https-url`, for detecting the use of non-HTTPS URLs that can be intercepted by third parties. diff --git a/rust/ql/src/codeql-pack.release.yml b/rust/ql/src/codeql-pack.release.yml index a01dca92161..eddeebba7bf 100644 --- a/rust/ql/src/codeql-pack.release.yml +++ b/rust/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.1.16 +lastReleaseVersion: 0.1.17 diff --git a/rust/ql/src/qlpack.yml b/rust/ql/src/qlpack.yml index 3c122e1853b..09d251a5cb1 100644 --- a/rust/ql/src/qlpack.yml +++ b/rust/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-queries -version: 0.1.17-dev +version: 0.1.17 groups: - rust - queries diff --git a/shared/concepts/CHANGELOG.md b/shared/concepts/CHANGELOG.md index bac19b9b77f..cfaa89c5ac2 100644 --- a/shared/concepts/CHANGELOG.md +++ b/shared/concepts/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.6 + +No user-facing changes. + ## 0.0.5 No user-facing changes. diff --git a/shared/concepts/change-notes/released/0.0.6.md b/shared/concepts/change-notes/released/0.0.6.md new file mode 100644 index 00000000000..ccbce856079 --- /dev/null +++ b/shared/concepts/change-notes/released/0.0.6.md @@ -0,0 +1,3 @@ +## 0.0.6 + +No user-facing changes. diff --git a/shared/concepts/codeql-pack.release.yml b/shared/concepts/codeql-pack.release.yml index bb45a1ab018..cf398ce02aa 100644 --- a/shared/concepts/codeql-pack.release.yml +++ b/shared/concepts/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.5 +lastReleaseVersion: 0.0.6 diff --git a/shared/concepts/qlpack.yml b/shared/concepts/qlpack.yml index 8b0fc6c6f7a..3924d67029d 100644 --- a/shared/concepts/qlpack.yml +++ b/shared/concepts/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/concepts -version: 0.0.6-dev +version: 0.0.6 groups: shared library: true dependencies: diff --git a/shared/controlflow/CHANGELOG.md b/shared/controlflow/CHANGELOG.md index 9b9c04fd8d8..df7e781268e 100644 --- a/shared/controlflow/CHANGELOG.md +++ b/shared/controlflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.16 + +No user-facing changes. + ## 2.0.15 No user-facing changes. diff --git a/shared/controlflow/change-notes/released/2.0.16.md b/shared/controlflow/change-notes/released/2.0.16.md new file mode 100644 index 00000000000..221400d393f --- /dev/null +++ b/shared/controlflow/change-notes/released/2.0.16.md @@ -0,0 +1,3 @@ +## 2.0.16 + +No user-facing changes. diff --git a/shared/controlflow/codeql-pack.release.yml b/shared/controlflow/codeql-pack.release.yml index 0377ae283a3..c10461a785c 100644 --- a/shared/controlflow/codeql-pack.release.yml +++ b/shared/controlflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.15 +lastReleaseVersion: 2.0.16 diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index 56945c0709d..a0158fea04f 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 2.0.16-dev +version: 2.0.16 groups: shared library: true dependencies: diff --git a/shared/dataflow/CHANGELOG.md b/shared/dataflow/CHANGELOG.md index 1a867888e89..13be0b19eb2 100644 --- a/shared/dataflow/CHANGELOG.md +++ b/shared/dataflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.16 + +No user-facing changes. + ## 2.0.15 No user-facing changes. diff --git a/shared/dataflow/change-notes/released/2.0.16.md b/shared/dataflow/change-notes/released/2.0.16.md new file mode 100644 index 00000000000..221400d393f --- /dev/null +++ b/shared/dataflow/change-notes/released/2.0.16.md @@ -0,0 +1,3 @@ +## 2.0.16 + +No user-facing changes. diff --git a/shared/dataflow/codeql-pack.release.yml b/shared/dataflow/codeql-pack.release.yml index 0377ae283a3..c10461a785c 100644 --- a/shared/dataflow/codeql-pack.release.yml +++ b/shared/dataflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.15 +lastReleaseVersion: 2.0.16 diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 4c0a9bdfe8c..3e46004181f 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 2.0.16-dev +version: 2.0.16 groups: shared library: true dependencies: diff --git a/shared/mad/CHANGELOG.md b/shared/mad/CHANGELOG.md index e6cf183a1d4..9979556a421 100644 --- a/shared/mad/CHANGELOG.md +++ b/shared/mad/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.32 + +No user-facing changes. + ## 1.0.31 No user-facing changes. diff --git a/shared/mad/change-notes/released/1.0.32.md b/shared/mad/change-notes/released/1.0.32.md new file mode 100644 index 00000000000..05c4073731c --- /dev/null +++ b/shared/mad/change-notes/released/1.0.32.md @@ -0,0 +1,3 @@ +## 1.0.32 + +No user-facing changes. diff --git a/shared/mad/codeql-pack.release.yml b/shared/mad/codeql-pack.release.yml index f5bdc98ffc8..7bc5c51ba7b 100644 --- a/shared/mad/codeql-pack.release.yml +++ b/shared/mad/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.31 +lastReleaseVersion: 1.0.32 diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index b6f4e8c2bc1..1aaa401b750 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.32-dev +version: 1.0.32 groups: shared library: true dependencies: diff --git a/shared/quantum/CHANGELOG.md b/shared/quantum/CHANGELOG.md index a59e560c415..1857b399fe8 100644 --- a/shared/quantum/CHANGELOG.md +++ b/shared/quantum/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.10 + +No user-facing changes. + ## 0.0.9 No user-facing changes. diff --git a/shared/quantum/change-notes/released/0.0.10.md b/shared/quantum/change-notes/released/0.0.10.md new file mode 100644 index 00000000000..22391080fd4 --- /dev/null +++ b/shared/quantum/change-notes/released/0.0.10.md @@ -0,0 +1,3 @@ +## 0.0.10 + +No user-facing changes. diff --git a/shared/quantum/codeql-pack.release.yml b/shared/quantum/codeql-pack.release.yml index ecdd64fbab8..b740014e5ae 100644 --- a/shared/quantum/codeql-pack.release.yml +++ b/shared/quantum/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.9 +lastReleaseVersion: 0.0.10 diff --git a/shared/quantum/qlpack.yml b/shared/quantum/qlpack.yml index 3741ff55855..bf877f51d5f 100644 --- a/shared/quantum/qlpack.yml +++ b/shared/quantum/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/quantum -version: 0.0.10-dev +version: 0.0.10 groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/CHANGELOG.md b/shared/rangeanalysis/CHANGELOG.md index 10466480900..50ea4c310f6 100644 --- a/shared/rangeanalysis/CHANGELOG.md +++ b/shared/rangeanalysis/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.32 + +No user-facing changes. + ## 1.0.31 No user-facing changes. diff --git a/shared/rangeanalysis/change-notes/released/1.0.32.md b/shared/rangeanalysis/change-notes/released/1.0.32.md new file mode 100644 index 00000000000..05c4073731c --- /dev/null +++ b/shared/rangeanalysis/change-notes/released/1.0.32.md @@ -0,0 +1,3 @@ +## 1.0.32 + +No user-facing changes. diff --git a/shared/rangeanalysis/codeql-pack.release.yml b/shared/rangeanalysis/codeql-pack.release.yml index f5bdc98ffc8..7bc5c51ba7b 100644 --- a/shared/rangeanalysis/codeql-pack.release.yml +++ b/shared/rangeanalysis/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.31 +lastReleaseVersion: 1.0.32 diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index e67c274bf51..5e9de8ad513 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.32-dev +version: 1.0.32 groups: shared library: true dependencies: diff --git a/shared/regex/CHANGELOG.md b/shared/regex/CHANGELOG.md index 3b3fcb5a55f..830e0da6f28 100644 --- a/shared/regex/CHANGELOG.md +++ b/shared/regex/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.32 + +No user-facing changes. + ## 1.0.31 No user-facing changes. diff --git a/shared/regex/change-notes/released/1.0.32.md b/shared/regex/change-notes/released/1.0.32.md new file mode 100644 index 00000000000..05c4073731c --- /dev/null +++ b/shared/regex/change-notes/released/1.0.32.md @@ -0,0 +1,3 @@ +## 1.0.32 + +No user-facing changes. diff --git a/shared/regex/codeql-pack.release.yml b/shared/regex/codeql-pack.release.yml index f5bdc98ffc8..7bc5c51ba7b 100644 --- a/shared/regex/codeql-pack.release.yml +++ b/shared/regex/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.31 +lastReleaseVersion: 1.0.32 diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index 5aebaf9bffb..f69602228c9 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.32-dev +version: 1.0.32 groups: shared library: true dependencies: diff --git a/shared/ssa/CHANGELOG.md b/shared/ssa/CHANGELOG.md index e7e17bf044b..8e4b1482e78 100644 --- a/shared/ssa/CHANGELOG.md +++ b/shared/ssa/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.8 + +No user-facing changes. + ## 2.0.7 No user-facing changes. diff --git a/shared/ssa/change-notes/released/2.0.8.md b/shared/ssa/change-notes/released/2.0.8.md new file mode 100644 index 00000000000..4d6867c721b --- /dev/null +++ b/shared/ssa/change-notes/released/2.0.8.md @@ -0,0 +1,3 @@ +## 2.0.8 + +No user-facing changes. diff --git a/shared/ssa/codeql-pack.release.yml b/shared/ssa/codeql-pack.release.yml index 08d5e959449..7ffb2d9f65b 100644 --- a/shared/ssa/codeql-pack.release.yml +++ b/shared/ssa/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.7 +lastReleaseVersion: 2.0.8 diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index 8337226f574..bbccd5e094c 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 2.0.8-dev +version: 2.0.8 groups: shared library: true dependencies: diff --git a/shared/threat-models/CHANGELOG.md b/shared/threat-models/CHANGELOG.md index d5040623557..331bb4c220e 100644 --- a/shared/threat-models/CHANGELOG.md +++ b/shared/threat-models/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.32 + +No user-facing changes. + ## 1.0.31 No user-facing changes. diff --git a/shared/threat-models/change-notes/released/1.0.32.md b/shared/threat-models/change-notes/released/1.0.32.md new file mode 100644 index 00000000000..05c4073731c --- /dev/null +++ b/shared/threat-models/change-notes/released/1.0.32.md @@ -0,0 +1,3 @@ +## 1.0.32 + +No user-facing changes. diff --git a/shared/threat-models/codeql-pack.release.yml b/shared/threat-models/codeql-pack.release.yml index f5bdc98ffc8..7bc5c51ba7b 100644 --- a/shared/threat-models/codeql-pack.release.yml +++ b/shared/threat-models/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.31 +lastReleaseVersion: 1.0.32 diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index 8f72fd8ad3f..10ca1546f9f 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.32-dev +version: 1.0.32 library: true groups: shared dataExtensions: diff --git a/shared/tutorial/CHANGELOG.md b/shared/tutorial/CHANGELOG.md index f4a80412ca8..6f6d29c2504 100644 --- a/shared/tutorial/CHANGELOG.md +++ b/shared/tutorial/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.32 + +No user-facing changes. + ## 1.0.31 No user-facing changes. diff --git a/shared/tutorial/change-notes/released/1.0.32.md b/shared/tutorial/change-notes/released/1.0.32.md new file mode 100644 index 00000000000..05c4073731c --- /dev/null +++ b/shared/tutorial/change-notes/released/1.0.32.md @@ -0,0 +1,3 @@ +## 1.0.32 + +No user-facing changes. diff --git a/shared/tutorial/codeql-pack.release.yml b/shared/tutorial/codeql-pack.release.yml index f5bdc98ffc8..7bc5c51ba7b 100644 --- a/shared/tutorial/codeql-pack.release.yml +++ b/shared/tutorial/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.31 +lastReleaseVersion: 1.0.32 diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index aabb0356b86..ce733dcd8b2 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 1.0.32-dev +version: 1.0.32 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/CHANGELOG.md b/shared/typeflow/CHANGELOG.md index bf429698022..592596c37d2 100644 --- a/shared/typeflow/CHANGELOG.md +++ b/shared/typeflow/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.32 + +No user-facing changes. + ## 1.0.31 No user-facing changes. diff --git a/shared/typeflow/change-notes/released/1.0.32.md b/shared/typeflow/change-notes/released/1.0.32.md new file mode 100644 index 00000000000..05c4073731c --- /dev/null +++ b/shared/typeflow/change-notes/released/1.0.32.md @@ -0,0 +1,3 @@ +## 1.0.32 + +No user-facing changes. diff --git a/shared/typeflow/codeql-pack.release.yml b/shared/typeflow/codeql-pack.release.yml index f5bdc98ffc8..7bc5c51ba7b 100644 --- a/shared/typeflow/codeql-pack.release.yml +++ b/shared/typeflow/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.31 +lastReleaseVersion: 1.0.32 diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index 98566858903..d665055f125 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.32-dev +version: 1.0.32 groups: shared library: true dependencies: diff --git a/shared/typeinference/CHANGELOG.md b/shared/typeinference/CHANGELOG.md index 83a42fb0551..29ece641a7e 100644 --- a/shared/typeinference/CHANGELOG.md +++ b/shared/typeinference/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.0.13 + +No user-facing changes. + ## 0.0.12 No user-facing changes. diff --git a/shared/typeinference/change-notes/released/0.0.13.md b/shared/typeinference/change-notes/released/0.0.13.md new file mode 100644 index 00000000000..f679eaf0313 --- /dev/null +++ b/shared/typeinference/change-notes/released/0.0.13.md @@ -0,0 +1,3 @@ +## 0.0.13 + +No user-facing changes. diff --git a/shared/typeinference/codeql-pack.release.yml b/shared/typeinference/codeql-pack.release.yml index 997fb8da83c..044e54e4f7e 100644 --- a/shared/typeinference/codeql-pack.release.yml +++ b/shared/typeinference/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 0.0.12 +lastReleaseVersion: 0.0.13 diff --git a/shared/typeinference/qlpack.yml b/shared/typeinference/qlpack.yml index 954a850cf0f..8a7bfdca975 100644 --- a/shared/typeinference/qlpack.yml +++ b/shared/typeinference/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeinference -version: 0.0.13-dev +version: 0.0.13 groups: shared library: true dependencies: diff --git a/shared/typetracking/CHANGELOG.md b/shared/typetracking/CHANGELOG.md index 1372c8c89ea..6b132f75a55 100644 --- a/shared/typetracking/CHANGELOG.md +++ b/shared/typetracking/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.16 + +No user-facing changes. + ## 2.0.15 No user-facing changes. diff --git a/shared/typetracking/change-notes/released/2.0.16.md b/shared/typetracking/change-notes/released/2.0.16.md new file mode 100644 index 00000000000..221400d393f --- /dev/null +++ b/shared/typetracking/change-notes/released/2.0.16.md @@ -0,0 +1,3 @@ +## 2.0.16 + +No user-facing changes. diff --git a/shared/typetracking/codeql-pack.release.yml b/shared/typetracking/codeql-pack.release.yml index 0377ae283a3..c10461a785c 100644 --- a/shared/typetracking/codeql-pack.release.yml +++ b/shared/typetracking/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.15 +lastReleaseVersion: 2.0.16 diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 2bf6f01d218..4e24584b50e 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 2.0.16-dev +version: 2.0.16 groups: shared library: true dependencies: diff --git a/shared/typos/CHANGELOG.md b/shared/typos/CHANGELOG.md index c44b941f9e3..2661fcc9308 100644 --- a/shared/typos/CHANGELOG.md +++ b/shared/typos/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.32 + +No user-facing changes. + ## 1.0.31 No user-facing changes. diff --git a/shared/typos/change-notes/released/1.0.32.md b/shared/typos/change-notes/released/1.0.32.md new file mode 100644 index 00000000000..05c4073731c --- /dev/null +++ b/shared/typos/change-notes/released/1.0.32.md @@ -0,0 +1,3 @@ +## 1.0.32 + +No user-facing changes. diff --git a/shared/typos/codeql-pack.release.yml b/shared/typos/codeql-pack.release.yml index f5bdc98ffc8..7bc5c51ba7b 100644 --- a/shared/typos/codeql-pack.release.yml +++ b/shared/typos/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.31 +lastReleaseVersion: 1.0.32 diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index b01883668b7..b13ab265b25 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.32-dev +version: 1.0.32 groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/CHANGELOG.md b/shared/util/CHANGELOG.md index d9169a8d5d8..3ded7f7af70 100644 --- a/shared/util/CHANGELOG.md +++ b/shared/util/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.0.19 + +No user-facing changes. + ## 2.0.18 No user-facing changes. diff --git a/shared/util/change-notes/released/2.0.19.md b/shared/util/change-notes/released/2.0.19.md new file mode 100644 index 00000000000..b37b6798b12 --- /dev/null +++ b/shared/util/change-notes/released/2.0.19.md @@ -0,0 +1,3 @@ +## 2.0.19 + +No user-facing changes. diff --git a/shared/util/codeql-pack.release.yml b/shared/util/codeql-pack.release.yml index 16342205c73..4aecf1e1f86 100644 --- a/shared/util/codeql-pack.release.yml +++ b/shared/util/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 2.0.18 +lastReleaseVersion: 2.0.19 diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 1c1f5670d3e..2352753b472 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 2.0.19-dev +version: 2.0.19 groups: shared library: true dependencies: null diff --git a/shared/xml/CHANGELOG.md b/shared/xml/CHANGELOG.md index 59ae3e2581a..2c1d2132c7e 100644 --- a/shared/xml/CHANGELOG.md +++ b/shared/xml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.32 + +No user-facing changes. + ## 1.0.31 No user-facing changes. diff --git a/shared/xml/change-notes/released/1.0.32.md b/shared/xml/change-notes/released/1.0.32.md new file mode 100644 index 00000000000..05c4073731c --- /dev/null +++ b/shared/xml/change-notes/released/1.0.32.md @@ -0,0 +1,3 @@ +## 1.0.32 + +No user-facing changes. diff --git a/shared/xml/codeql-pack.release.yml b/shared/xml/codeql-pack.release.yml index f5bdc98ffc8..7bc5c51ba7b 100644 --- a/shared/xml/codeql-pack.release.yml +++ b/shared/xml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.31 +lastReleaseVersion: 1.0.32 diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index 0908201b182..680cc4751ef 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.32-dev +version: 1.0.32 groups: shared library: true dependencies: diff --git a/shared/yaml/CHANGELOG.md b/shared/yaml/CHANGELOG.md index 2254f38fb9f..31243ec36be 100644 --- a/shared/yaml/CHANGELOG.md +++ b/shared/yaml/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.0.32 + +No user-facing changes. + ## 1.0.31 No user-facing changes. diff --git a/shared/yaml/change-notes/released/1.0.32.md b/shared/yaml/change-notes/released/1.0.32.md new file mode 100644 index 00000000000..05c4073731c --- /dev/null +++ b/shared/yaml/change-notes/released/1.0.32.md @@ -0,0 +1,3 @@ +## 1.0.32 + +No user-facing changes. diff --git a/shared/yaml/codeql-pack.release.yml b/shared/yaml/codeql-pack.release.yml index f5bdc98ffc8..7bc5c51ba7b 100644 --- a/shared/yaml/codeql-pack.release.yml +++ b/shared/yaml/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.0.31 +lastReleaseVersion: 1.0.32 diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index cbbdd896341..1c625bfdf4a 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.32-dev +version: 1.0.32 groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/CHANGELOG.md b/swift/ql/lib/CHANGELOG.md index 7138ed02a2b..eb3b3da9689 100644 --- a/swift/ql/lib/CHANGELOG.md +++ b/swift/ql/lib/CHANGELOG.md @@ -1,3 +1,7 @@ +## 5.0.8 + +No user-facing changes. + ## 5.0.7 ### Minor Analysis Improvements diff --git a/swift/ql/lib/change-notes/released/5.0.8.md b/swift/ql/lib/change-notes/released/5.0.8.md new file mode 100644 index 00000000000..9c73f4b1341 --- /dev/null +++ b/swift/ql/lib/change-notes/released/5.0.8.md @@ -0,0 +1,3 @@ +## 5.0.8 + +No user-facing changes. diff --git a/swift/ql/lib/codeql-pack.release.yml b/swift/ql/lib/codeql-pack.release.yml index accf4086d8a..c608aca6969 100644 --- a/swift/ql/lib/codeql-pack.release.yml +++ b/swift/ql/lib/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 5.0.7 +lastReleaseVersion: 5.0.8 diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index 88950de258f..a05b05e1eea 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 5.0.8-dev +version: 5.0.8 groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/CHANGELOG.md b/swift/ql/src/CHANGELOG.md index eac65864617..be2f79710a9 100644 --- a/swift/ql/src/CHANGELOG.md +++ b/swift/ql/src/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.2.6 + +No user-facing changes. + ## 1.2.5 No user-facing changes. diff --git a/swift/ql/src/change-notes/released/1.2.6.md b/swift/ql/src/change-notes/released/1.2.6.md new file mode 100644 index 00000000000..0832850ff8c --- /dev/null +++ b/swift/ql/src/change-notes/released/1.2.6.md @@ -0,0 +1,3 @@ +## 1.2.6 + +No user-facing changes. diff --git a/swift/ql/src/codeql-pack.release.yml b/swift/ql/src/codeql-pack.release.yml index 40355f0807f..24962f7ba24 100644 --- a/swift/ql/src/codeql-pack.release.yml +++ b/swift/ql/src/codeql-pack.release.yml @@ -1,2 +1,2 @@ --- -lastReleaseVersion: 1.2.5 +lastReleaseVersion: 1.2.6 diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index f49b81cec75..3dbc93c16d3 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.2.6-dev +version: 1.2.6 groups: - swift - queries From e0444c531b9925bb14f9aae15c4b185f472d2034 Mon Sep 17 00:00:00 2001 From: idrissrio Date: Mon, 29 Sep 2025 13:25:30 +0200 Subject: [PATCH 152/160] Java: Add integration test for constant expr detection --- .../ConstantExpAppearsNonConstant.expected | 1 + .../ConstantExpAppearsNonConstant.qlref | 1 + .../java/evaluation-to-constant-errortype/Test.java | 7 +++++++ .../java/evaluation-to-constant-errortype/test.py | 2 ++ 4 files changed, 11 insertions(+) create mode 100644 java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.expected create mode 100644 java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.qlref create mode 100644 java/ql/integration-tests/java/evaluation-to-constant-errortype/Test.java create mode 100644 java/ql/integration-tests/java/evaluation-to-constant-errortype/test.py diff --git a/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.expected b/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.expected new file mode 100644 index 00000000000..1dcec10c6ee --- /dev/null +++ b/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.expected @@ -0,0 +1 @@ +| Test.java:3:8:3:15 | | Expression always evaluates to the same value. | diff --git a/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.qlref b/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.qlref new file mode 100644 index 00000000000..6d7e1f5cb7f --- /dev/null +++ b/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.qlref @@ -0,0 +1 @@ +Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql \ No newline at end of file diff --git a/java/ql/integration-tests/java/evaluation-to-constant-errortype/Test.java b/java/ql/integration-tests/java/evaluation-to-constant-errortype/Test.java new file mode 100644 index 00000000000..913c7817c7f --- /dev/null +++ b/java/ql/integration-tests/java/evaluation-to-constant-errortype/Test.java @@ -0,0 +1,7 @@ +class Test { + public static void updateFlashlights(Minecraft mc){ + if(mc.world != null){ + + } + } +} \ No newline at end of file diff --git a/java/ql/integration-tests/java/evaluation-to-constant-errortype/test.py b/java/ql/integration-tests/java/evaluation-to-constant-errortype/test.py new file mode 100644 index 00000000000..759e4cf8b82 --- /dev/null +++ b/java/ql/integration-tests/java/evaluation-to-constant-errortype/test.py @@ -0,0 +1,2 @@ +def test(codeql, java): + codeql.database.create(build_mode="none") \ No newline at end of file From 659afb5f3049c934e03e6b5c1dc93af8e7bb2896 Mon Sep 17 00:00:00 2001 From: idrissrio Date: Mon, 29 Sep 2025 13:28:55 +0200 Subject: [PATCH 153/160] Java: Fix false positives in evaluation-to-constant query for ErrorType --- .../src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql b/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql index 50f50862631..094c8bbc70c 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql @@ -19,7 +19,7 @@ predicate isConstantExp(Expr e) { // A literal is constant. e instanceof Literal or - e instanceof TypeAccess + exists(TypeAccess ta | ta = e | not ta.getType() instanceof ErrorType) or e instanceof ArrayTypeAccess or From b82d8c22521ad141948077cabbde0a3e824edadb Mon Sep 17 00:00:00 2001 From: idrissrio Date: Mon, 29 Sep 2025 13:29:34 +0200 Subject: [PATCH 154/160] Java: Accept new test results after query change --- .../ConstantExpAppearsNonConstant.expected | 1 - 1 file changed, 1 deletion(-) diff --git a/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.expected b/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.expected index 1dcec10c6ee..e69de29bb2d 100644 --- a/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.expected +++ b/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.expected @@ -1 +0,0 @@ -| Test.java:3:8:3:15 | | Expression always evaluates to the same value. | From a76d736136b32570135d62649db39ba374627b1e Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Mon, 29 Sep 2025 15:32:52 +0100 Subject: [PATCH 155/160] C#: tweak changelog wording --- csharp/ql/src/CHANGELOG.md | 2 +- csharp/ql/src/change-notes/released/1.4.1.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/csharp/ql/src/CHANGELOG.md b/csharp/ql/src/CHANGELOG.md index e432045f72e..7fa8992c49a 100644 --- a/csharp/ql/src/CHANGELOG.md +++ b/csharp/ql/src/CHANGELOG.md @@ -3,7 +3,7 @@ ### Minor Analysis Improvements * The modeling of null guards based on complex pattern expressions has been improved, which in turn improves the query `cs/dereferenced-value-may-be-null` by removing false positives. -* Remove the query `cs/xmldoc/missing-summary` from the `code-quality` suite (align with other languages). +* The query `cs/xmldoc/missing-summary` has been removed from the `code-quality` suite, to align with other languages. ## 1.4.0 diff --git a/csharp/ql/src/change-notes/released/1.4.1.md b/csharp/ql/src/change-notes/released/1.4.1.md index 48b31092714..f161787a108 100644 --- a/csharp/ql/src/change-notes/released/1.4.1.md +++ b/csharp/ql/src/change-notes/released/1.4.1.md @@ -3,4 +3,4 @@ ### Minor Analysis Improvements * The modeling of null guards based on complex pattern expressions has been improved, which in turn improves the query `cs/dereferenced-value-may-be-null` by removing false positives. -* Remove the query `cs/xmldoc/missing-summary` from the `code-quality` suite (align with other languages). +* The query `cs/xmldoc/missing-summary` has been removed from the `code-quality` suite, to align with other languages. From a7a4e43991d0c2290e593d0c7355dad77afa3256 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 29 Sep 2025 15:10:19 +0000 Subject: [PATCH 156/160] Post-release preparation for codeql-cli-2.23.2 --- actions/ql/lib/qlpack.yml | 2 +- actions/ql/src/qlpack.yml | 2 +- cpp/ql/lib/qlpack.yml | 2 +- cpp/ql/src/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/lib/qlpack.yml | 2 +- csharp/ql/campaigns/Solorigate/src/qlpack.yml | 2 +- csharp/ql/lib/qlpack.yml | 2 +- csharp/ql/src/qlpack.yml | 2 +- go/ql/consistency-queries/qlpack.yml | 2 +- go/ql/lib/qlpack.yml | 2 +- go/ql/src/qlpack.yml | 2 +- java/ql/lib/qlpack.yml | 2 +- java/ql/src/qlpack.yml | 2 +- javascript/ql/lib/qlpack.yml | 2 +- javascript/ql/src/qlpack.yml | 2 +- misc/suite-helpers/qlpack.yml | 2 +- python/ql/lib/qlpack.yml | 2 +- python/ql/src/qlpack.yml | 2 +- ruby/ql/lib/qlpack.yml | 2 +- ruby/ql/src/qlpack.yml | 2 +- rust/ql/lib/qlpack.yml | 2 +- rust/ql/src/qlpack.yml | 2 +- shared/concepts/qlpack.yml | 2 +- shared/controlflow/qlpack.yml | 2 +- shared/dataflow/qlpack.yml | 2 +- shared/mad/qlpack.yml | 2 +- shared/quantum/qlpack.yml | 2 +- shared/rangeanalysis/qlpack.yml | 2 +- shared/regex/qlpack.yml | 2 +- shared/ssa/qlpack.yml | 2 +- shared/threat-models/qlpack.yml | 2 +- shared/tutorial/qlpack.yml | 2 +- shared/typeflow/qlpack.yml | 2 +- shared/typeinference/qlpack.yml | 2 +- shared/typetracking/qlpack.yml | 2 +- shared/typos/qlpack.yml | 2 +- shared/util/qlpack.yml | 2 +- shared/xml/qlpack.yml | 2 +- shared/yaml/qlpack.yml | 2 +- swift/ql/lib/qlpack.yml | 2 +- swift/ql/src/qlpack.yml | 2 +- 41 files changed, 41 insertions(+), 41 deletions(-) diff --git a/actions/ql/lib/qlpack.yml b/actions/ql/lib/qlpack.yml index bfebfa99d04..80eecfca28d 100644 --- a/actions/ql/lib/qlpack.yml +++ b/actions/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-all -version: 0.4.18 +version: 0.4.19-dev library: true warnOnImplicitThis: true dependencies: diff --git a/actions/ql/src/qlpack.yml b/actions/ql/src/qlpack.yml index 9dba67fea76..2de1276aa82 100644 --- a/actions/ql/src/qlpack.yml +++ b/actions/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/actions-queries -version: 0.6.10 +version: 0.6.11-dev library: false warnOnImplicitThis: true groups: [actions, queries] diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index 23bf4d8fc9e..435d013c47b 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-all -version: 5.6.1 +version: 5.6.2-dev groups: cpp dbscheme: semmlecode.cpp.dbscheme extractor: cpp diff --git a/cpp/ql/src/qlpack.yml b/cpp/ql/src/qlpack.yml index 7322e2571d1..f5193698fdb 100644 --- a/cpp/ql/src/qlpack.yml +++ b/cpp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/cpp-queries -version: 1.5.1 +version: 1.5.2-dev groups: - cpp - queries diff --git a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml index 02e6cddfc17..3c14c29940c 100644 --- a/csharp/ql/campaigns/Solorigate/lib/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-all -version: 1.7.49 +version: 1.7.50-dev groups: - csharp - solorigate diff --git a/csharp/ql/campaigns/Solorigate/src/qlpack.yml b/csharp/ql/campaigns/Solorigate/src/qlpack.yml index 84e6c8ef7e0..efb3216f3b9 100644 --- a/csharp/ql/campaigns/Solorigate/src/qlpack.yml +++ b/csharp/ql/campaigns/Solorigate/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-solorigate-queries -version: 1.7.49 +version: 1.7.50-dev groups: - csharp - solorigate diff --git a/csharp/ql/lib/qlpack.yml b/csharp/ql/lib/qlpack.yml index aba9ee98b5a..2f92b5edafd 100644 --- a/csharp/ql/lib/qlpack.yml +++ b/csharp/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-all -version: 5.2.5 +version: 5.2.6-dev groups: csharp dbscheme: semmlecode.csharp.dbscheme extractor: csharp diff --git a/csharp/ql/src/qlpack.yml b/csharp/ql/src/qlpack.yml index 7ecdec07f35..fad06a3e928 100644 --- a/csharp/ql/src/qlpack.yml +++ b/csharp/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/csharp-queries -version: 1.4.1 +version: 1.4.2-dev groups: - csharp - queries diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml index 3b1e2d9586b..70529ff4f90 100644 --- a/go/ql/consistency-queries/qlpack.yml +++ b/go/ql/consistency-queries/qlpack.yml @@ -1,5 +1,5 @@ name: codeql-go-consistency-queries -version: 1.0.32 +version: 1.0.33-dev groups: - go - queries diff --git a/go/ql/lib/qlpack.yml b/go/ql/lib/qlpack.yml index bc9bf12c80c..20ace6482e4 100644 --- a/go/ql/lib/qlpack.yml +++ b/go/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-all -version: 4.3.5 +version: 4.3.6-dev groups: go dbscheme: go.dbscheme extractor: go diff --git a/go/ql/src/qlpack.yml b/go/ql/src/qlpack.yml index 816d4b95867..c85a94a90f5 100644 --- a/go/ql/src/qlpack.yml +++ b/go/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/go-queries -version: 1.4.6 +version: 1.4.7-dev groups: - go - queries diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 7d0153cc566..dabb65e61ce 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-all -version: 7.7.1 +version: 7.7.2-dev groups: java dbscheme: config/semmlecode.dbscheme extractor: java diff --git a/java/ql/src/qlpack.yml b/java/ql/src/qlpack.yml index bbfafc65503..b1ee0395fb2 100644 --- a/java/ql/src/qlpack.yml +++ b/java/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/java-queries -version: 1.8.1 +version: 1.8.2-dev groups: - java - queries diff --git a/javascript/ql/lib/qlpack.yml b/javascript/ql/lib/qlpack.yml index 74ccf251956..da942ea28a8 100644 --- a/javascript/ql/lib/qlpack.yml +++ b/javascript/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-all -version: 2.6.12 +version: 2.6.13-dev groups: javascript dbscheme: semmlecode.javascript.dbscheme extractor: javascript diff --git a/javascript/ql/src/qlpack.yml b/javascript/ql/src/qlpack.yml index cafde25bbf9..2581f947629 100644 --- a/javascript/ql/src/qlpack.yml +++ b/javascript/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/javascript-queries -version: 2.1.1 +version: 2.1.2-dev groups: - javascript - queries diff --git a/misc/suite-helpers/qlpack.yml b/misc/suite-helpers/qlpack.yml index 7d71d83613d..7715f68107e 100644 --- a/misc/suite-helpers/qlpack.yml +++ b/misc/suite-helpers/qlpack.yml @@ -1,4 +1,4 @@ name: codeql/suite-helpers -version: 1.0.32 +version: 1.0.33-dev groups: shared warnOnImplicitThis: true diff --git a/python/ql/lib/qlpack.yml b/python/ql/lib/qlpack.yml index 5eba946c3cf..35ab576bf1a 100644 --- a/python/ql/lib/qlpack.yml +++ b/python/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-all -version: 4.0.16 +version: 4.0.17-dev groups: python dbscheme: semmlecode.python.dbscheme extractor: python diff --git a/python/ql/src/qlpack.yml b/python/ql/src/qlpack.yml index b42e054bdad..08336cbb3eb 100644 --- a/python/ql/src/qlpack.yml +++ b/python/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/python-queries -version: 1.6.6 +version: 1.6.7-dev groups: - python - queries diff --git a/ruby/ql/lib/qlpack.yml b/ruby/ql/lib/qlpack.yml index 6dd0db034c3..a503103b95d 100644 --- a/ruby/ql/lib/qlpack.yml +++ b/ruby/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-all -version: 5.1.0 +version: 5.1.1-dev groups: ruby extractor: ruby dbscheme: ruby.dbscheme diff --git a/ruby/ql/src/qlpack.yml b/ruby/ql/src/qlpack.yml index ce46bf8c37a..a01acd1d674 100644 --- a/ruby/ql/src/qlpack.yml +++ b/ruby/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ruby-queries -version: 1.4.6 +version: 1.4.7-dev groups: - ruby - queries diff --git a/rust/ql/lib/qlpack.yml b/rust/ql/lib/qlpack.yml index 3c3ba893b14..61c2ed8e81e 100644 --- a/rust/ql/lib/qlpack.yml +++ b/rust/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-all -version: 0.1.17 +version: 0.1.18-dev groups: rust extractor: rust dbscheme: rust.dbscheme diff --git a/rust/ql/src/qlpack.yml b/rust/ql/src/qlpack.yml index 09d251a5cb1..57d3e972fc6 100644 --- a/rust/ql/src/qlpack.yml +++ b/rust/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rust-queries -version: 0.1.17 +version: 0.1.18-dev groups: - rust - queries diff --git a/shared/concepts/qlpack.yml b/shared/concepts/qlpack.yml index 3924d67029d..452f932edef 100644 --- a/shared/concepts/qlpack.yml +++ b/shared/concepts/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/concepts -version: 0.0.6 +version: 0.0.7-dev groups: shared library: true dependencies: diff --git a/shared/controlflow/qlpack.yml b/shared/controlflow/qlpack.yml index a0158fea04f..660b1e12512 100644 --- a/shared/controlflow/qlpack.yml +++ b/shared/controlflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/controlflow -version: 2.0.16 +version: 2.0.17-dev groups: shared library: true dependencies: diff --git a/shared/dataflow/qlpack.yml b/shared/dataflow/qlpack.yml index 3e46004181f..166ef444b22 100644 --- a/shared/dataflow/qlpack.yml +++ b/shared/dataflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/dataflow -version: 2.0.16 +version: 2.0.17-dev groups: shared library: true dependencies: diff --git a/shared/mad/qlpack.yml b/shared/mad/qlpack.yml index 1aaa401b750..d9767452c27 100644 --- a/shared/mad/qlpack.yml +++ b/shared/mad/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/mad -version: 1.0.32 +version: 1.0.33-dev groups: shared library: true dependencies: diff --git a/shared/quantum/qlpack.yml b/shared/quantum/qlpack.yml index bf877f51d5f..7dfaa747962 100644 --- a/shared/quantum/qlpack.yml +++ b/shared/quantum/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/quantum -version: 0.0.10 +version: 0.0.11-dev groups: shared library: true dependencies: diff --git a/shared/rangeanalysis/qlpack.yml b/shared/rangeanalysis/qlpack.yml index 5e9de8ad513..85341d10420 100644 --- a/shared/rangeanalysis/qlpack.yml +++ b/shared/rangeanalysis/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/rangeanalysis -version: 1.0.32 +version: 1.0.33-dev groups: shared library: true dependencies: diff --git a/shared/regex/qlpack.yml b/shared/regex/qlpack.yml index f69602228c9..72347bcd160 100644 --- a/shared/regex/qlpack.yml +++ b/shared/regex/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/regex -version: 1.0.32 +version: 1.0.33-dev groups: shared library: true dependencies: diff --git a/shared/ssa/qlpack.yml b/shared/ssa/qlpack.yml index bbccd5e094c..3c1f3fe0278 100644 --- a/shared/ssa/qlpack.yml +++ b/shared/ssa/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/ssa -version: 2.0.8 +version: 2.0.9-dev groups: shared library: true dependencies: diff --git a/shared/threat-models/qlpack.yml b/shared/threat-models/qlpack.yml index 10ca1546f9f..e28c5f26dd8 100644 --- a/shared/threat-models/qlpack.yml +++ b/shared/threat-models/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/threat-models -version: 1.0.32 +version: 1.0.33-dev library: true groups: shared dataExtensions: diff --git a/shared/tutorial/qlpack.yml b/shared/tutorial/qlpack.yml index ce733dcd8b2..33dc89bc60c 100644 --- a/shared/tutorial/qlpack.yml +++ b/shared/tutorial/qlpack.yml @@ -1,7 +1,7 @@ name: codeql/tutorial description: Library for the CodeQL detective tutorials, helping new users learn to write CodeQL queries. -version: 1.0.32 +version: 1.0.33-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/typeflow/qlpack.yml b/shared/typeflow/qlpack.yml index d665055f125..5d257b81fc6 100644 --- a/shared/typeflow/qlpack.yml +++ b/shared/typeflow/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeflow -version: 1.0.32 +version: 1.0.33-dev groups: shared library: true dependencies: diff --git a/shared/typeinference/qlpack.yml b/shared/typeinference/qlpack.yml index 8a7bfdca975..5d8f8a6011f 100644 --- a/shared/typeinference/qlpack.yml +++ b/shared/typeinference/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typeinference -version: 0.0.13 +version: 0.0.14-dev groups: shared library: true dependencies: diff --git a/shared/typetracking/qlpack.yml b/shared/typetracking/qlpack.yml index 4e24584b50e..6bc1e76cfb4 100644 --- a/shared/typetracking/qlpack.yml +++ b/shared/typetracking/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typetracking -version: 2.0.16 +version: 2.0.17-dev groups: shared library: true dependencies: diff --git a/shared/typos/qlpack.yml b/shared/typos/qlpack.yml index b13ab265b25..a045761cd92 100644 --- a/shared/typos/qlpack.yml +++ b/shared/typos/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/typos -version: 1.0.32 +version: 1.0.33-dev groups: shared library: true warnOnImplicitThis: true diff --git a/shared/util/qlpack.yml b/shared/util/qlpack.yml index 2352753b472..33bf4527cf0 100644 --- a/shared/util/qlpack.yml +++ b/shared/util/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/util -version: 2.0.19 +version: 2.0.20-dev groups: shared library: true dependencies: null diff --git a/shared/xml/qlpack.yml b/shared/xml/qlpack.yml index 680cc4751ef..62fcccb2453 100644 --- a/shared/xml/qlpack.yml +++ b/shared/xml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/xml -version: 1.0.32 +version: 1.0.33-dev groups: shared library: true dependencies: diff --git a/shared/yaml/qlpack.yml b/shared/yaml/qlpack.yml index 1c625bfdf4a..6c49b5f27ba 100644 --- a/shared/yaml/qlpack.yml +++ b/shared/yaml/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/yaml -version: 1.0.32 +version: 1.0.33-dev groups: shared library: true warnOnImplicitThis: true diff --git a/swift/ql/lib/qlpack.yml b/swift/ql/lib/qlpack.yml index a05b05e1eea..4ad0623d0f3 100644 --- a/swift/ql/lib/qlpack.yml +++ b/swift/ql/lib/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-all -version: 5.0.8 +version: 5.0.9-dev groups: swift extractor: swift dbscheme: swift.dbscheme diff --git a/swift/ql/src/qlpack.yml b/swift/ql/src/qlpack.yml index 3dbc93c16d3..ea5431f192e 100644 --- a/swift/ql/src/qlpack.yml +++ b/swift/ql/src/qlpack.yml @@ -1,5 +1,5 @@ name: codeql/swift-queries -version: 1.2.6 +version: 1.2.7-dev groups: - swift - queries From 63771110a5dd2dd619ab97e37742ca4837b482ed Mon Sep 17 00:00:00 2001 From: idrissrio Date: Tue, 30 Sep 2025 11:46:37 +0200 Subject: [PATCH 157/160] Java: Address review comment --- .../ConstantExpAppearsNonConstant.qlref | 3 ++- .../Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.qlref b/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.qlref index 6d7e1f5cb7f..6d2b25768e5 100644 --- a/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.qlref +++ b/java/ql/integration-tests/java/evaluation-to-constant-errortype/ConstantExpAppearsNonConstant.qlref @@ -1 +1,2 @@ -Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql \ No newline at end of file +query: Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql +postprocess: utils/test/InlineExpectationsTestQuery.ql \ No newline at end of file diff --git a/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql b/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql index 094c8bbc70c..28ae63bfd36 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/ConstantExpAppearsNonConstant.ql @@ -19,7 +19,7 @@ predicate isConstantExp(Expr e) { // A literal is constant. e instanceof Literal or - exists(TypeAccess ta | ta = e | not ta.getType() instanceof ErrorType) + e instanceof TypeAccess and not e.(TypeAccess).getType() instanceof ErrorType or e instanceof ArrayTypeAccess or From 49efd574a09b71c24132d80acfe9fcd4d4841d64 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 30 Sep 2025 14:47:06 +0200 Subject: [PATCH 158/160] Rust: Add taint model for add on `String` --- .../frameworks/stdlib/lang-alloc.model.yml | 2 + .../strings/inline-taint-flow.expected | 41 ++++++++++++------- .../library-tests/dataflow/strings/main.rs | 4 +- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml index 8eb3788ab1e..1f14e222fd2 100644 --- a/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml +++ b/rust/ql/lib/codeql/rust/frameworks/stdlib/lang-alloc.model.yml @@ -46,5 +46,7 @@ extensions: - ["::to_string", "Argument[self]", "ReturnValue", "taint", "manual"] - ["::parse", "Argument[self]", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"] - ["::trim", "Argument[self]", "ReturnValue.Reference", "taint", "manual"] + - ["::add", "Argument[self]", "ReturnValue", "taint", "manual"] + - ["::add", "Argument[0].Reference", "ReturnValue", "taint", "manual"] # Vec - ["alloc::vec::from_elem", "Argument[0]", "ReturnValue.Element", "value", "manual"] diff --git a/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected b/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected index e6241590137..ef137d85103 100644 --- a/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected +++ b/rust/ql/test/library-tests/dataflow/strings/inline-taint-flow.expected @@ -1,11 +1,12 @@ models | 1 | Summary: <_ as core::convert::From>::from; Argument[0]; ReturnValue; taint | | 2 | Summary: ::from; Argument[0].Reference; ReturnValue; value | -| 3 | Summary: ::add; Argument[self]; ReturnValue; value | -| 4 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 5 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 6 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | -| 7 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value | +| 3 | Summary: ::add; Argument[0].Reference; ReturnValue; taint | +| 4 | Summary: ::add; Argument[self]; ReturnValue; value | +| 5 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 6 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 7 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | +| 8 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value | edges | main.rs:26:9:26:9 | s | main.rs:27:19:27:25 | s[...] | provenance | | | main.rs:26:13:26:22 | source(...) | main.rs:26:9:26:9 | s | provenance | | @@ -16,8 +17,12 @@ edges | main.rs:32:9:32:10 | s1 | main.rs:35:14:35:15 | s1 | provenance | | | main.rs:32:14:32:23 | source(...) | main.rs:32:9:32:10 | s1 | provenance | | | main.rs:35:9:35:10 | s4 | main.rs:38:10:38:11 | s4 | provenance | | -| main.rs:35:14:35:15 | s1 | main.rs:35:14:35:20 | ... + ... | provenance | MaD:3 | +| main.rs:35:14:35:15 | s1 | main.rs:35:14:35:20 | ... + ... | provenance | MaD:4 | | main.rs:35:14:35:20 | ... + ... | main.rs:35:9:35:10 | s4 | provenance | | +| main.rs:43:9:43:10 | s1 | main.rs:46:34:46:35 | s1 | provenance | | +| main.rs:43:14:43:23 | source(...) | main.rs:43:9:43:10 | s1 | provenance | | +| main.rs:46:33:46:35 | &s1 [&ref] | main.rs:46:10:46:35 | ... + ... | provenance | MaD:3 | +| main.rs:46:34:46:35 | s1 | main.rs:46:33:46:35 | &s1 [&ref] | provenance | | | main.rs:51:9:51:10 | s1 | main.rs:52:27:52:28 | s1 | provenance | | | main.rs:51:14:51:29 | source_slice(...) | main.rs:51:9:51:10 | s1 | provenance | | | main.rs:52:9:52:10 | s2 | main.rs:53:10:53:11 | s2 | provenance | | @@ -25,38 +30,38 @@ edges | main.rs:52:27:52:28 | s1 | main.rs:52:14:52:29 | ...::from(...) | provenance | MaD:1 | | main.rs:52:27:52:28 | s1 | main.rs:52:14:52:29 | ...::from(...) | provenance | MaD:2 | | main.rs:63:9:63:9 | s | main.rs:64:16:64:16 | s | provenance | | -| main.rs:63:9:63:9 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:4 | | main.rs:63:9:63:9 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:5 | +| main.rs:63:9:63:9 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:6 | | main.rs:63:13:63:22 | source(...) | main.rs:63:9:63:9 | s | provenance | | -| main.rs:64:16:64:16 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:4 | | main.rs:64:16:64:16 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:5 | +| main.rs:64:16:64:16 | s | main.rs:64:16:64:25 | s.as_str() | provenance | MaD:6 | | main.rs:68:9:68:9 | s | main.rs:70:34:70:61 | MacroExpr | provenance | | | main.rs:68:9:68:9 | s | main.rs:73:34:73:59 | MacroExpr | provenance | | | main.rs:68:13:68:22 | source(...) | main.rs:68:9:68:9 | s | provenance | | | main.rs:70:9:70:18 | formatted1 | main.rs:71:10:71:19 | formatted1 | provenance | | | main.rs:70:22:70:62 | ...::format(...) | main.rs:70:9:70:18 | formatted1 | provenance | | -| main.rs:70:34:70:61 | MacroExpr | main.rs:70:22:70:62 | ...::format(...) | provenance | MaD:6 | +| main.rs:70:34:70:61 | MacroExpr | main.rs:70:22:70:62 | ...::format(...) | provenance | MaD:7 | | main.rs:73:9:73:18 | formatted2 | main.rs:74:10:74:19 | formatted2 | provenance | | | main.rs:73:22:73:60 | ...::format(...) | main.rs:73:9:73:18 | formatted2 | provenance | | -| main.rs:73:34:73:59 | MacroExpr | main.rs:73:22:73:60 | ...::format(...) | provenance | MaD:6 | +| main.rs:73:34:73:59 | MacroExpr | main.rs:73:22:73:60 | ...::format(...) | provenance | MaD:7 | | main.rs:76:9:76:13 | width | main.rs:77:34:77:74 | MacroExpr | provenance | | | main.rs:76:17:76:32 | source_usize(...) | main.rs:76:9:76:13 | width | provenance | | | main.rs:77:9:77:18 | formatted3 | main.rs:78:10:78:19 | formatted3 | provenance | | | main.rs:77:22:77:75 | ...::format(...) | main.rs:77:9:77:18 | formatted3 | provenance | | -| main.rs:77:34:77:74 | MacroExpr | main.rs:77:22:77:75 | ...::format(...) | provenance | MaD:6 | +| main.rs:77:34:77:74 | MacroExpr | main.rs:77:22:77:75 | ...::format(...) | provenance | MaD:7 | | main.rs:82:9:82:10 | s1 | main.rs:86:18:86:25 | MacroExpr | provenance | | | main.rs:82:9:82:10 | s1 | main.rs:87:18:87:32 | MacroExpr | provenance | | | main.rs:82:14:82:23 | source(...) | main.rs:82:9:82:10 | s1 | provenance | | | main.rs:86:10:86:16 | res | main.rs:86:18:86:25 | { ... } | provenance | | | main.rs:86:18:86:25 | ...::format(...) | main.rs:86:10:86:16 | res | provenance | | | main.rs:86:18:86:25 | ...::must_use(...) | main.rs:86:10:86:26 | MacroExpr | provenance | | -| main.rs:86:18:86:25 | MacroExpr | main.rs:86:18:86:25 | ...::format(...) | provenance | MaD:6 | -| main.rs:86:18:86:25 | { ... } | main.rs:86:18:86:25 | ...::must_use(...) | provenance | MaD:7 | +| main.rs:86:18:86:25 | MacroExpr | main.rs:86:18:86:25 | ...::format(...) | provenance | MaD:7 | +| main.rs:86:18:86:25 | { ... } | main.rs:86:18:86:25 | ...::must_use(...) | provenance | MaD:8 | | main.rs:87:10:87:16 | res | main.rs:87:18:87:32 | { ... } | provenance | | | main.rs:87:18:87:32 | ...::format(...) | main.rs:87:10:87:16 | res | provenance | | | main.rs:87:18:87:32 | ...::must_use(...) | main.rs:87:10:87:33 | MacroExpr | provenance | | -| main.rs:87:18:87:32 | MacroExpr | main.rs:87:18:87:32 | ...::format(...) | provenance | MaD:6 | -| main.rs:87:18:87:32 | { ... } | main.rs:87:18:87:32 | ...::must_use(...) | provenance | MaD:7 | +| main.rs:87:18:87:32 | MacroExpr | main.rs:87:18:87:32 | ...::format(...) | provenance | MaD:7 | +| main.rs:87:18:87:32 | { ... } | main.rs:87:18:87:32 | ...::must_use(...) | provenance | MaD:8 | nodes | main.rs:26:9:26:9 | s | semmle.label | s | | main.rs:26:13:26:22 | source(...) | semmle.label | source(...) | @@ -70,6 +75,11 @@ nodes | main.rs:35:14:35:15 | s1 | semmle.label | s1 | | main.rs:35:14:35:20 | ... + ... | semmle.label | ... + ... | | main.rs:38:10:38:11 | s4 | semmle.label | s4 | +| main.rs:43:9:43:10 | s1 | semmle.label | s1 | +| main.rs:43:14:43:23 | source(...) | semmle.label | source(...) | +| main.rs:46:10:46:35 | ... + ... | semmle.label | ... + ... | +| main.rs:46:33:46:35 | &s1 [&ref] | semmle.label | &s1 [&ref] | +| main.rs:46:34:46:35 | s1 | semmle.label | s1 | | main.rs:51:9:51:10 | s1 | semmle.label | s1 | | main.rs:51:14:51:29 | source_slice(...) | semmle.label | source_slice(...) | | main.rs:52:9:52:10 | s2 | semmle.label | s2 | @@ -115,6 +125,7 @@ testFailures #select | main.rs:28:16:28:21 | sliced | main.rs:26:13:26:22 | source(...) | main.rs:28:16:28:21 | sliced | $@ | main.rs:26:13:26:22 | source(...) | source(...) | | main.rs:38:10:38:11 | s4 | main.rs:32:14:32:23 | source(...) | main.rs:38:10:38:11 | s4 | $@ | main.rs:32:14:32:23 | source(...) | source(...) | +| main.rs:46:10:46:35 | ... + ... | main.rs:43:14:43:23 | source(...) | main.rs:46:10:46:35 | ... + ... | $@ | main.rs:43:14:43:23 | source(...) | source(...) | | main.rs:53:10:53:11 | s2 | main.rs:51:14:51:29 | source_slice(...) | main.rs:53:10:53:11 | s2 | $@ | main.rs:51:14:51:29 | source_slice(...) | source_slice(...) | | main.rs:64:16:64:25 | s.as_str() | main.rs:63:13:63:22 | source(...) | main.rs:64:16:64:25 | s.as_str() | $@ | main.rs:63:13:63:22 | source(...) | source(...) | | main.rs:71:10:71:19 | formatted1 | main.rs:68:13:68:22 | source(...) | main.rs:71:10:71:19 | formatted1 | $@ | main.rs:68:13:68:22 | source(...) | source(...) | diff --git a/rust/ql/test/library-tests/dataflow/strings/main.rs b/rust/ql/test/library-tests/dataflow/strings/main.rs index ca9db9a9026..40f62946832 100644 --- a/rust/ql/test/library-tests/dataflow/strings/main.rs +++ b/rust/ql/test/library-tests/dataflow/strings/main.rs @@ -43,7 +43,7 @@ fn string_add_reference() { let s1 = source(37); let s2 = "1".to_string(); - sink("Hello ".to_string() + &s1); // $ MISSING: hasTaintFlow=37 + sink("Hello ".to_string() + &s1); // $ hasTaintFlow=37 sink("Hello ".to_string() + &s2); } @@ -56,7 +56,7 @@ fn string_from() { fn string_to_string() { let s1 = source_slice(22); let s2 = s1.to_string(); - sink(s2); // $ MISSING: hasTaintFlow=22 - we are not currently able to resolve the `to_string` call above, which comes from `impl ToString for T` + sink(s2); // $ MISSING: hasTaintFlow=22 } fn as_str() { From f88daff45f5d9cf1a1f57d7f69b9c3a30863db99 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Tue, 30 Sep 2025 13:56:27 +0100 Subject: [PATCH 159/160] Java: note that classes with entirely private constructors can't be subclassed --- .../Concurrency/StartInConstructor.ql | 10 +++++++++- .../query-tests/StartInConstructor/Test.java | 16 +++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql b/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql index 3c80e451951..700b1fab896 100644 --- a/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql +++ b/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql @@ -15,6 +15,10 @@ import java +private predicate hasASubclass(RefType t) { + exists(RefType sub | sub != t | sub.getAnAncestor() = t) +} + /** * Holds if this type is either `final` or * `private` and without subtypes. @@ -24,7 +28,11 @@ private predicate cannotBeExtended(RefType t) { or // If the class is private, all possible subclasses are known. t.isPrivate() and - not exists(RefType sub | sub != t | sub.getAnAncestor() = t) + not hasASubclass(t) + or + // If the class only has private constructors, all possible subclasses are known. + forex(Constructor c | c.getDeclaringType() = t | c.isPrivate()) and + not hasASubclass(t) } from MethodCall m, Constructor c, Class clazz diff --git a/java/ql/test/query-tests/StartInConstructor/Test.java b/java/ql/test/query-tests/StartInConstructor/Test.java index 4c5a57d8b4b..ae8148af787 100644 --- a/java/ql/test/query-tests/StartInConstructor/Test.java +++ b/java/ql/test/query-tests/StartInConstructor/Test.java @@ -30,4 +30,18 @@ public class Test { } } -} \ No newline at end of file + + public static class AllPrivateConstructors { + Thread myThread; + + private AllPrivateConstructors() { + myThread = new Thread("myThread"); + // OK - class cannot be extended outside this file, and is not in fact extended + myThread.start(); + } + + public static AllPrivateConstructors create() { + return new AllPrivateConstructors(); + } + } +} From 19871a2653cc8f9712d9f0a9d416203fc41031b6 Mon Sep 17 00:00:00 2001 From: Simon Friis Vindum Date: Tue, 30 Sep 2025 15:26:30 +0200 Subject: [PATCH 160/160] Rust: Accept test changes --- .../security/CWE-089/SqlInjection.expected | 247 +++++++++++++++--- .../test/query-tests/security/CWE-089/sqlx.rs | 20 +- .../CWE-312/CleartextLogging.expected | 95 +++---- .../CWE-312/CleartextStorageDatabase.expected | 65 +++-- .../CWE-825/AccessAfterLifetime.expected | 8 +- 5 files changed, 315 insertions(+), 120 deletions(-) diff --git a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected index 329138efa24..46c49c8071d 100644 --- a/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected +++ b/rust/ql/test/query-tests/security/CWE-089/SqlInjection.expected @@ -2,79 +2,191 @@ | sqlx.rs:77:13:77:23 | ...::query | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:77:13:77:23 | ...::query | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | | sqlx.rs:78:13:78:23 | ...::query | sqlx.rs:47:22:47:35 | ...::args | sqlx.rs:78:13:78:23 | ...::query | This query depends on a $@. | sqlx.rs:47:22:47:35 | ...::args | user-provided value | | sqlx.rs:80:17:80:27 | ...::query | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:80:17:80:27 | ...::query | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | +| sqlx.rs:81:17:81:27 | ...::query | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:81:17:81:27 | ...::query | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | | sqlx.rs:82:17:82:27 | ...::query | sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:82:17:82:27 | ...::query | This query depends on a $@. | sqlx.rs:48:25:48:46 | ...::get | user-provided value | +| sqlx.rs:113:17:113:29 | ...::raw_sql | sqlx.rs:100:25:100:46 | ...::get | sqlx.rs:113:17:113:29 | ...::raw_sql | This query depends on a $@. | sqlx.rs:100:25:100:46 | ...::get | user-provided value | +| sqlx.rs:120:17:120:27 | ...::query | sqlx.rs:100:25:100:46 | ...::get | sqlx.rs:120:17:120:27 | ...::query | This query depends on a $@. | sqlx.rs:100:25:100:46 | ...::get | user-provided value | +| sqlx.rs:127:17:127:27 | ...::query | sqlx.rs:100:25:100:46 | ...::get | sqlx.rs:127:17:127:27 | ...::query | This query depends on a $@. | sqlx.rs:100:25:100:46 | ...::get | user-provided value | +| sqlx.rs:136:40:136:53 | ...::query_as | sqlx.rs:100:25:100:46 | ...::get | sqlx.rs:136:40:136:53 | ...::query_as | This query depends on a $@. | sqlx.rs:100:25:100:46 | ...::get | user-provided value | +| sqlx.rs:145:40:145:53 | ...::query_as | sqlx.rs:100:25:100:46 | ...::get | sqlx.rs:145:40:145:53 | ...::query_as | This query depends on a $@. | sqlx.rs:100:25:100:46 | ...::get | user-provided value | +| sqlx.rs:153:17:153:27 | ...::query | sqlx.rs:100:25:100:46 | ...::get | sqlx.rs:153:17:153:27 | ...::query | This query depends on a $@. | sqlx.rs:100:25:100:46 | ...::get | user-provided value | +| sqlx.rs:188:17:188:27 | ...::query | sqlx.rs:173:25:173:46 | ...::get | sqlx.rs:188:17:188:27 | ...::query | This query depends on a $@. | sqlx.rs:173:25:173:46 | ...::get | user-provided value | edges | sqlx.rs:47:9:47:18 | arg_string | sqlx.rs:53:27:53:36 | arg_string | provenance | | -| sqlx.rs:47:22:47:35 | ...::args | sqlx.rs:47:22:47:37 | ...::args(...) [element] | provenance | Src:MaD:3 | -| sqlx.rs:47:22:47:37 | ...::args(...) [element] | sqlx.rs:47:22:47:44 | ... .nth(...) [Some] | provenance | MaD:4 | -| sqlx.rs:47:22:47:44 | ... .nth(...) [Some] | sqlx.rs:47:22:47:77 | ... .unwrap_or(...) | provenance | MaD:6 | +| sqlx.rs:47:22:47:35 | ...::args | sqlx.rs:47:22:47:37 | ...::args(...) [element] | provenance | Src:MaD:5 | +| sqlx.rs:47:22:47:37 | ...::args(...) [element] | sqlx.rs:47:22:47:44 | ... .nth(...) [Some] | provenance | MaD:6 | +| sqlx.rs:47:22:47:44 | ... .nth(...) [Some] | sqlx.rs:47:22:47:77 | ... .unwrap_or(...) | provenance | MaD:10 | | sqlx.rs:47:22:47:77 | ... .unwrap_or(...) | sqlx.rs:47:9:47:18 | arg_string | provenance | | -| sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:49:25:49:52 | remote_string.parse() [Ok] | provenance | MaD:10 | -| sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:49:25:49:52 | remote_string.parse() [Ok] | provenance | MaD:10 | +| sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:49:25:49:52 | remote_string.parse() [Ok] | provenance | MaD:14 | +| sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:49:25:49:52 | remote_string.parse() [Ok] | provenance | MaD:14 | | sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:54:27:54:39 | remote_string | provenance | | +| sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:55:84:55:96 | remote_string | provenance | | | sqlx.rs:48:9:48:21 | remote_string | sqlx.rs:59:17:59:72 | MacroExpr | provenance | | -| sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | provenance | Src:MaD:2 | -| sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | sqlx.rs:48:25:48:78 | ... .unwrap() | provenance | MaD:7 | -| sqlx.rs:48:25:48:78 | ... .unwrap() | sqlx.rs:48:25:48:85 | ... .text() [Ok] | provenance | MaD:11 | -| sqlx.rs:48:25:48:85 | ... .text() [Ok] | sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | provenance | MaD:8 | +| sqlx.rs:48:25:48:46 | ...::get | sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | provenance | Src:MaD:4 | +| sqlx.rs:48:25:48:69 | ...::get(...) [Ok] | sqlx.rs:48:25:48:78 | ... .unwrap() | provenance | MaD:11 | +| sqlx.rs:48:25:48:78 | ... .unwrap() | sqlx.rs:48:25:48:85 | ... .text() [Ok] | provenance | MaD:15 | +| sqlx.rs:48:25:48:85 | ... .text() [Ok] | sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | provenance | MaD:12 | | sqlx.rs:48:25:48:118 | ... .unwrap_or(...) | sqlx.rs:48:9:48:21 | remote_string | provenance | | | sqlx.rs:49:9:49:21 | remote_number | sqlx.rs:52:32:52:87 | MacroExpr | provenance | | -| sqlx.rs:49:25:49:52 | remote_string.parse() [Ok] | sqlx.rs:49:25:49:65 | ... .unwrap_or(...) | provenance | MaD:8 | +| sqlx.rs:49:25:49:52 | remote_string.parse() [Ok] | sqlx.rs:49:25:49:65 | ... .unwrap_or(...) | provenance | MaD:12 | | sqlx.rs:49:25:49:65 | ... .unwrap_or(...) | sqlx.rs:49:9:49:21 | remote_number | provenance | | | sqlx.rs:52:9:52:20 | safe_query_3 | sqlx.rs:77:25:77:36 | safe_query_3 | provenance | | +| sqlx.rs:52:9:52:20 | safe_query_3 | sqlx.rs:77:25:77:45 | safe_query_3.as_str() | provenance | MaD:13 | | sqlx.rs:52:9:52:20 | safe_query_3 | sqlx.rs:77:25:77:45 | safe_query_3.as_str() | provenance | MaD:9 | -| sqlx.rs:52:9:52:20 | safe_query_3 | sqlx.rs:77:25:77:45 | safe_query_3.as_str() | provenance | MaD:5 | -| sqlx.rs:52:9:52:20 | safe_query_3 | sqlx.rs:77:25:77:45 | safe_query_3.as_str() | provenance | MaD:9 | +| sqlx.rs:52:9:52:20 | safe_query_3 | sqlx.rs:77:25:77:45 | safe_query_3.as_str() | provenance | MaD:13 | | sqlx.rs:52:24:52:30 | res | sqlx.rs:52:32:52:87 | { ... } | provenance | | | sqlx.rs:52:32:52:87 | ...::format(...) | sqlx.rs:52:24:52:30 | res | provenance | | | sqlx.rs:52:32:52:87 | ...::must_use(...) | sqlx.rs:52:9:52:20 | safe_query_3 | provenance | | -| sqlx.rs:52:32:52:87 | MacroExpr | sqlx.rs:52:32:52:87 | ...::format(...) | provenance | MaD:12 | -| sqlx.rs:52:32:52:87 | { ... } | sqlx.rs:52:32:52:87 | ...::must_use(...) | provenance | MaD:13 | -| sqlx.rs:53:9:53:22 | unsafe_query_1 [&ref] | sqlx.rs:78:25:78:47 | unsafe_query_1.as_str() [&ref] | provenance | MaD:9 | -| sqlx.rs:53:9:53:22 | unsafe_query_1 [&ref] | sqlx.rs:78:25:78:47 | unsafe_query_1.as_str() [&ref] | provenance | MaD:5 | +| sqlx.rs:52:32:52:87 | MacroExpr | sqlx.rs:52:32:52:87 | ...::format(...) | provenance | MaD:16 | +| sqlx.rs:52:32:52:87 | { ... } | sqlx.rs:52:32:52:87 | ...::must_use(...) | provenance | MaD:17 | +| sqlx.rs:53:9:53:22 | unsafe_query_1 [&ref] | sqlx.rs:78:25:78:47 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | | sqlx.rs:53:9:53:22 | unsafe_query_1 [&ref] | sqlx.rs:78:25:78:47 | unsafe_query_1.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:53:9:53:22 | unsafe_query_1 [&ref] | sqlx.rs:78:25:78:47 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | | sqlx.rs:53:26:53:36 | &arg_string [&ref] | sqlx.rs:53:9:53:22 | unsafe_query_1 [&ref] | provenance | | | sqlx.rs:53:27:53:36 | arg_string | sqlx.rs:53:26:53:36 | &arg_string [&ref] | provenance | | +| sqlx.rs:54:9:54:22 | unsafe_query_2 [&ref] | sqlx.rs:80:29:80:51 | unsafe_query_2.as_str() [&ref] | provenance | MaD:13 | | sqlx.rs:54:9:54:22 | unsafe_query_2 [&ref] | sqlx.rs:80:29:80:51 | unsafe_query_2.as_str() [&ref] | provenance | MaD:9 | -| sqlx.rs:54:9:54:22 | unsafe_query_2 [&ref] | sqlx.rs:80:29:80:51 | unsafe_query_2.as_str() [&ref] | provenance | MaD:5 | -| sqlx.rs:54:9:54:22 | unsafe_query_2 [&ref] | sqlx.rs:80:29:80:51 | unsafe_query_2.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:54:9:54:22 | unsafe_query_2 [&ref] | sqlx.rs:80:29:80:51 | unsafe_query_2.as_str() [&ref] | provenance | MaD:13 | | sqlx.rs:54:26:54:39 | &remote_string [&ref] | sqlx.rs:54:9:54:22 | unsafe_query_2 [&ref] | provenance | | | sqlx.rs:54:27:54:39 | remote_string | sqlx.rs:54:26:54:39 | &remote_string [&ref] | provenance | | +| sqlx.rs:55:9:55:22 | unsafe_query_3 | sqlx.rs:81:29:81:42 | unsafe_query_3 | provenance | | +| sqlx.rs:55:9:55:22 | unsafe_query_3 | sqlx.rs:81:29:81:51 | unsafe_query_3.as_str() | provenance | MaD:13 | +| sqlx.rs:55:9:55:22 | unsafe_query_3 | sqlx.rs:81:29:81:51 | unsafe_query_3.as_str() | provenance | MaD:9 | +| sqlx.rs:55:9:55:22 | unsafe_query_3 | sqlx.rs:81:29:81:51 | unsafe_query_3.as_str() | provenance | MaD:13 | +| sqlx.rs:55:26:55:96 | ... + ... | sqlx.rs:55:9:55:22 | unsafe_query_3 | provenance | | +| sqlx.rs:55:26:55:96 | ... + ... | sqlx.rs:55:26:55:102 | ... + ... | provenance | MaD:8 | +| sqlx.rs:55:26:55:102 | ... + ... | sqlx.rs:55:9:55:22 | unsafe_query_3 | provenance | | +| sqlx.rs:55:83:55:96 | &remote_string [&ref] | sqlx.rs:55:26:55:96 | ... + ... | provenance | MaD:7 | +| sqlx.rs:55:84:55:96 | remote_string | sqlx.rs:55:83:55:96 | &remote_string [&ref] | provenance | | | sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:82:29:82:42 | unsafe_query_4 | provenance | | +| sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() | provenance | MaD:13 | | sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() | provenance | MaD:9 | -| sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() | provenance | MaD:5 | -| sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() | provenance | MaD:9 | +| sqlx.rs:56:9:56:22 | unsafe_query_4 | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() | provenance | MaD:13 | | sqlx.rs:59:9:59:15 | res | sqlx.rs:59:17:59:72 | { ... } | provenance | | | sqlx.rs:59:17:59:72 | ...::format(...) | sqlx.rs:59:9:59:15 | res | provenance | | | sqlx.rs:59:17:59:72 | ...::must_use(...) | sqlx.rs:56:9:56:22 | unsafe_query_4 | provenance | | -| sqlx.rs:59:17:59:72 | MacroExpr | sqlx.rs:59:17:59:72 | ...::format(...) | provenance | MaD:12 | -| sqlx.rs:59:17:59:72 | { ... } | sqlx.rs:59:17:59:72 | ...::must_use(...) | provenance | MaD:13 | -| sqlx.rs:77:25:77:36 | safe_query_3 | sqlx.rs:77:25:77:45 | safe_query_3.as_str() [&ref] | provenance | MaD:9 | -| sqlx.rs:77:25:77:36 | safe_query_3 | sqlx.rs:77:25:77:45 | safe_query_3.as_str() [&ref] | provenance | MaD:5 | +| sqlx.rs:59:17:59:72 | MacroExpr | sqlx.rs:59:17:59:72 | ...::format(...) | provenance | MaD:16 | +| sqlx.rs:59:17:59:72 | { ... } | sqlx.rs:59:17:59:72 | ...::must_use(...) | provenance | MaD:17 | +| sqlx.rs:77:25:77:36 | safe_query_3 | sqlx.rs:77:25:77:45 | safe_query_3.as_str() [&ref] | provenance | MaD:13 | | sqlx.rs:77:25:77:36 | safe_query_3 | sqlx.rs:77:25:77:45 | safe_query_3.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:77:25:77:36 | safe_query_3 | sqlx.rs:77:25:77:45 | safe_query_3.as_str() [&ref] | provenance | MaD:13 | | sqlx.rs:77:25:77:45 | safe_query_3.as_str() | sqlx.rs:77:13:77:23 | ...::query | provenance | MaD:1 Sink:MaD:1 | | sqlx.rs:77:25:77:45 | safe_query_3.as_str() [&ref] | sqlx.rs:77:13:77:23 | ...::query | provenance | MaD:1 Sink:MaD:1 | | sqlx.rs:78:25:78:47 | unsafe_query_1.as_str() [&ref] | sqlx.rs:78:13:78:23 | ...::query | provenance | MaD:1 Sink:MaD:1 | | sqlx.rs:80:29:80:51 | unsafe_query_2.as_str() [&ref] | sqlx.rs:80:17:80:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | +| sqlx.rs:81:29:81:42 | unsafe_query_3 | sqlx.rs:81:29:81:51 | unsafe_query_3.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:81:29:81:42 | unsafe_query_3 | sqlx.rs:81:29:81:51 | unsafe_query_3.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:81:29:81:42 | unsafe_query_3 | sqlx.rs:81:29:81:51 | unsafe_query_3.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:81:29:81:51 | unsafe_query_3.as_str() | sqlx.rs:81:17:81:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | +| sqlx.rs:81:29:81:51 | unsafe_query_3.as_str() [&ref] | sqlx.rs:81:17:81:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | +| sqlx.rs:82:29:82:42 | unsafe_query_4 | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() [&ref] | provenance | MaD:13 | | sqlx.rs:82:29:82:42 | unsafe_query_4 | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() [&ref] | provenance | MaD:9 | -| sqlx.rs:82:29:82:42 | unsafe_query_4 | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() [&ref] | provenance | MaD:5 | -| sqlx.rs:82:29:82:42 | unsafe_query_4 | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:82:29:82:42 | unsafe_query_4 | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() [&ref] | provenance | MaD:13 | | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() | sqlx.rs:82:17:82:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() [&ref] | sqlx.rs:82:17:82:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | +| sqlx.rs:100:9:100:21 | remote_string | sqlx.rs:102:84:102:96 | remote_string | provenance | | +| sqlx.rs:100:25:100:46 | ...::get | sqlx.rs:100:25:100:69 | ...::get(...) [Ok] | provenance | Src:MaD:4 | +| sqlx.rs:100:25:100:69 | ...::get(...) [Ok] | sqlx.rs:100:25:100:78 | ... .unwrap() | provenance | MaD:11 | +| sqlx.rs:100:25:100:78 | ... .unwrap() | sqlx.rs:100:25:100:85 | ... .text() [Ok] | provenance | MaD:15 | +| sqlx.rs:100:25:100:85 | ... .text() [Ok] | sqlx.rs:100:25:100:118 | ... .unwrap_or(...) | provenance | MaD:12 | +| sqlx.rs:100:25:100:118 | ... .unwrap_or(...) | sqlx.rs:100:9:100:21 | remote_string | provenance | | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:113:31:113:44 | unsafe_query_1 | provenance | | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:113:31:113:53 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:113:31:113:53 | unsafe_query_1.as_str() | provenance | MaD:9 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:113:31:113:53 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:120:29:120:42 | unsafe_query_1 | provenance | | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:120:29:120:51 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:120:29:120:51 | unsafe_query_1.as_str() | provenance | MaD:9 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:120:29:120:51 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:127:29:127:42 | unsafe_query_1 | provenance | | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:127:29:127:51 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:127:29:127:51 | unsafe_query_1.as_str() | provenance | MaD:9 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:127:29:127:51 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:136:55:136:68 | unsafe_query_1 | provenance | | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:136:55:136:77 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:136:55:136:77 | unsafe_query_1.as_str() | provenance | MaD:9 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:136:55:136:77 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:145:55:145:68 | unsafe_query_1 | provenance | | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:145:55:145:77 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:145:55:145:77 | unsafe_query_1.as_str() | provenance | MaD:9 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:145:55:145:77 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:153:29:153:42 | unsafe_query_1 | provenance | | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:153:29:153:51 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:153:29:153:51 | unsafe_query_1.as_str() | provenance | MaD:9 | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | sqlx.rs:153:29:153:51 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:102:26:102:96 | ... + ... | sqlx.rs:102:9:102:22 | unsafe_query_1 | provenance | | +| sqlx.rs:102:26:102:96 | ... + ... | sqlx.rs:102:26:102:102 | ... + ... | provenance | MaD:8 | +| sqlx.rs:102:26:102:102 | ... + ... | sqlx.rs:102:9:102:22 | unsafe_query_1 | provenance | | +| sqlx.rs:102:83:102:96 | &remote_string [&ref] | sqlx.rs:102:26:102:96 | ... + ... | provenance | MaD:7 | +| sqlx.rs:102:84:102:96 | remote_string | sqlx.rs:102:83:102:96 | &remote_string [&ref] | provenance | | +| sqlx.rs:113:31:113:44 | unsafe_query_1 | sqlx.rs:113:31:113:53 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:113:31:113:44 | unsafe_query_1 | sqlx.rs:113:31:113:53 | unsafe_query_1.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:113:31:113:44 | unsafe_query_1 | sqlx.rs:113:31:113:53 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:113:31:113:53 | unsafe_query_1.as_str() | sqlx.rs:113:17:113:29 | ...::raw_sql | provenance | MaD:3 Sink:MaD:3 | +| sqlx.rs:113:31:113:53 | unsafe_query_1.as_str() [&ref] | sqlx.rs:113:17:113:29 | ...::raw_sql | provenance | MaD:3 Sink:MaD:3 | +| sqlx.rs:120:29:120:42 | unsafe_query_1 | sqlx.rs:120:29:120:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:120:29:120:42 | unsafe_query_1 | sqlx.rs:120:29:120:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:120:29:120:42 | unsafe_query_1 | sqlx.rs:120:29:120:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:120:29:120:51 | unsafe_query_1.as_str() | sqlx.rs:120:17:120:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | +| sqlx.rs:120:29:120:51 | unsafe_query_1.as_str() [&ref] | sqlx.rs:120:17:120:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | +| sqlx.rs:127:29:127:42 | unsafe_query_1 | sqlx.rs:127:29:127:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:127:29:127:42 | unsafe_query_1 | sqlx.rs:127:29:127:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:127:29:127:42 | unsafe_query_1 | sqlx.rs:127:29:127:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:127:29:127:51 | unsafe_query_1.as_str() | sqlx.rs:127:17:127:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | +| sqlx.rs:127:29:127:51 | unsafe_query_1.as_str() [&ref] | sqlx.rs:127:17:127:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | +| sqlx.rs:136:55:136:68 | unsafe_query_1 | sqlx.rs:136:55:136:77 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:136:55:136:68 | unsafe_query_1 | sqlx.rs:136:55:136:77 | unsafe_query_1.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:136:55:136:68 | unsafe_query_1 | sqlx.rs:136:55:136:77 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:136:55:136:77 | unsafe_query_1.as_str() | sqlx.rs:136:40:136:53 | ...::query_as | provenance | MaD:2 Sink:MaD:2 | +| sqlx.rs:136:55:136:77 | unsafe_query_1.as_str() [&ref] | sqlx.rs:136:40:136:53 | ...::query_as | provenance | MaD:2 Sink:MaD:2 | +| sqlx.rs:145:55:145:68 | unsafe_query_1 | sqlx.rs:145:55:145:77 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:145:55:145:68 | unsafe_query_1 | sqlx.rs:145:55:145:77 | unsafe_query_1.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:145:55:145:68 | unsafe_query_1 | sqlx.rs:145:55:145:77 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:145:55:145:77 | unsafe_query_1.as_str() | sqlx.rs:145:40:145:53 | ...::query_as | provenance | MaD:2 Sink:MaD:2 | +| sqlx.rs:145:55:145:77 | unsafe_query_1.as_str() [&ref] | sqlx.rs:145:40:145:53 | ...::query_as | provenance | MaD:2 Sink:MaD:2 | +| sqlx.rs:153:29:153:42 | unsafe_query_1 | sqlx.rs:153:29:153:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:153:29:153:42 | unsafe_query_1 | sqlx.rs:153:29:153:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:153:29:153:42 | unsafe_query_1 | sqlx.rs:153:29:153:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:153:29:153:51 | unsafe_query_1.as_str() | sqlx.rs:153:17:153:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | +| sqlx.rs:153:29:153:51 | unsafe_query_1.as_str() [&ref] | sqlx.rs:153:17:153:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | +| sqlx.rs:173:9:173:21 | remote_string | sqlx.rs:175:84:175:96 | remote_string | provenance | | +| sqlx.rs:173:25:173:46 | ...::get | sqlx.rs:173:25:173:69 | ...::get(...) [Ok] | provenance | Src:MaD:4 | +| sqlx.rs:173:25:173:69 | ...::get(...) [Ok] | sqlx.rs:173:25:173:78 | ... .unwrap() | provenance | MaD:11 | +| sqlx.rs:173:25:173:78 | ... .unwrap() | sqlx.rs:173:25:173:85 | ... .text() [Ok] | provenance | MaD:15 | +| sqlx.rs:173:25:173:85 | ... .text() [Ok] | sqlx.rs:173:25:173:118 | ... .unwrap_or(...) | provenance | MaD:12 | +| sqlx.rs:173:25:173:118 | ... .unwrap_or(...) | sqlx.rs:173:9:173:21 | remote_string | provenance | | +| sqlx.rs:175:9:175:22 | unsafe_query_1 | sqlx.rs:188:29:188:42 | unsafe_query_1 | provenance | | +| sqlx.rs:175:9:175:22 | unsafe_query_1 | sqlx.rs:188:29:188:51 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:175:9:175:22 | unsafe_query_1 | sqlx.rs:188:29:188:51 | unsafe_query_1.as_str() | provenance | MaD:9 | +| sqlx.rs:175:9:175:22 | unsafe_query_1 | sqlx.rs:188:29:188:51 | unsafe_query_1.as_str() | provenance | MaD:13 | +| sqlx.rs:175:26:175:96 | ... + ... | sqlx.rs:175:9:175:22 | unsafe_query_1 | provenance | | +| sqlx.rs:175:26:175:96 | ... + ... | sqlx.rs:175:26:175:102 | ... + ... | provenance | MaD:8 | +| sqlx.rs:175:26:175:102 | ... + ... | sqlx.rs:175:9:175:22 | unsafe_query_1 | provenance | | +| sqlx.rs:175:83:175:96 | &remote_string [&ref] | sqlx.rs:175:26:175:96 | ... + ... | provenance | MaD:7 | +| sqlx.rs:175:84:175:96 | remote_string | sqlx.rs:175:83:175:96 | &remote_string [&ref] | provenance | | +| sqlx.rs:188:29:188:42 | unsafe_query_1 | sqlx.rs:188:29:188:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:188:29:188:42 | unsafe_query_1 | sqlx.rs:188:29:188:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:9 | +| sqlx.rs:188:29:188:42 | unsafe_query_1 | sqlx.rs:188:29:188:51 | unsafe_query_1.as_str() [&ref] | provenance | MaD:13 | +| sqlx.rs:188:29:188:51 | unsafe_query_1.as_str() | sqlx.rs:188:17:188:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | +| sqlx.rs:188:29:188:51 | unsafe_query_1.as_str() [&ref] | sqlx.rs:188:17:188:27 | ...::query | provenance | MaD:1 Sink:MaD:1 | models | 1 | Sink: sqlx_core::query::query; Argument[0]; sql-injection | -| 2 | Source: reqwest::blocking::get; ReturnValue.Field[core::result::Result::Ok(0)]; remote | -| 3 | Source: std::env::args; ReturnValue.Element; commandargs | -| 4 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Element; ReturnValue.Field[core::option::Option::Some(0)]; value | -| 5 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 6 | Summary: ::unwrap_or; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | -| 7 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 8 | Summary: ::unwrap_or; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | -| 9 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 10 | Summary: ::parse; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 11 | Summary: ::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | -| 12 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | -| 13 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value | +| 2 | Sink: sqlx_core::query_as::query_as; Argument[0]; sql-injection | +| 3 | Sink: sqlx_core::raw_sql::raw_sql; Argument[0]; sql-injection | +| 4 | Source: reqwest::blocking::get; ReturnValue.Field[core::result::Result::Ok(0)]; remote | +| 5 | Source: std::env::args; ReturnValue.Element; commandargs | +| 6 | Summary: <_ as core::iter::traits::iterator::Iterator>::nth; Argument[self].Element; ReturnValue.Field[core::option::Option::Some(0)]; value | +| 7 | Summary: ::add; Argument[0].Reference; ReturnValue; taint | +| 8 | Summary: ::add; Argument[self]; ReturnValue; value | +| 9 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 10 | Summary: ::unwrap_or; Argument[self].Field[core::option::Option::Some(0)]; ReturnValue; value | +| 11 | Summary: ::unwrap; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | +| 12 | Summary: ::unwrap_or; Argument[self].Field[core::result::Result::Ok(0)]; ReturnValue; value | +| 13 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 14 | Summary: ::parse; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 15 | Summary: ::text; Argument[self]; ReturnValue.Field[core::result::Result::Ok(0)]; taint | +| 16 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | +| 17 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value | nodes | sqlx.rs:47:9:47:18 | arg_string | semmle.label | arg_string | | sqlx.rs:47:22:47:35 | ...::args | semmle.label | ...::args | @@ -102,6 +214,11 @@ nodes | sqlx.rs:54:9:54:22 | unsafe_query_2 [&ref] | semmle.label | unsafe_query_2 [&ref] | | sqlx.rs:54:26:54:39 | &remote_string [&ref] | semmle.label | &remote_string [&ref] | | sqlx.rs:54:27:54:39 | remote_string | semmle.label | remote_string | +| sqlx.rs:55:9:55:22 | unsafe_query_3 | semmle.label | unsafe_query_3 | +| sqlx.rs:55:26:55:96 | ... + ... | semmle.label | ... + ... | +| sqlx.rs:55:26:55:102 | ... + ... | semmle.label | ... + ... | +| sqlx.rs:55:83:55:96 | &remote_string [&ref] | semmle.label | &remote_string [&ref] | +| sqlx.rs:55:84:55:96 | remote_string | semmle.label | remote_string | | sqlx.rs:56:9:56:22 | unsafe_query_4 | semmle.label | unsafe_query_4 | | sqlx.rs:59:9:59:15 | res | semmle.label | res | | sqlx.rs:59:17:59:72 | ...::format(...) | semmle.label | ...::format(...) | @@ -116,8 +233,62 @@ nodes | sqlx.rs:78:25:78:47 | unsafe_query_1.as_str() [&ref] | semmle.label | unsafe_query_1.as_str() [&ref] | | sqlx.rs:80:17:80:27 | ...::query | semmle.label | ...::query | | sqlx.rs:80:29:80:51 | unsafe_query_2.as_str() [&ref] | semmle.label | unsafe_query_2.as_str() [&ref] | +| sqlx.rs:81:17:81:27 | ...::query | semmle.label | ...::query | +| sqlx.rs:81:29:81:42 | unsafe_query_3 | semmle.label | unsafe_query_3 | +| sqlx.rs:81:29:81:51 | unsafe_query_3.as_str() | semmle.label | unsafe_query_3.as_str() | +| sqlx.rs:81:29:81:51 | unsafe_query_3.as_str() [&ref] | semmle.label | unsafe_query_3.as_str() [&ref] | | sqlx.rs:82:17:82:27 | ...::query | semmle.label | ...::query | | sqlx.rs:82:29:82:42 | unsafe_query_4 | semmle.label | unsafe_query_4 | | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() | semmle.label | unsafe_query_4.as_str() | | sqlx.rs:82:29:82:51 | unsafe_query_4.as_str() [&ref] | semmle.label | unsafe_query_4.as_str() [&ref] | +| sqlx.rs:100:9:100:21 | remote_string | semmle.label | remote_string | +| sqlx.rs:100:25:100:46 | ...::get | semmle.label | ...::get | +| sqlx.rs:100:25:100:69 | ...::get(...) [Ok] | semmle.label | ...::get(...) [Ok] | +| sqlx.rs:100:25:100:78 | ... .unwrap() | semmle.label | ... .unwrap() | +| sqlx.rs:100:25:100:85 | ... .text() [Ok] | semmle.label | ... .text() [Ok] | +| sqlx.rs:100:25:100:118 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) | +| sqlx.rs:102:9:102:22 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:102:26:102:96 | ... + ... | semmle.label | ... + ... | +| sqlx.rs:102:26:102:102 | ... + ... | semmle.label | ... + ... | +| sqlx.rs:102:83:102:96 | &remote_string [&ref] | semmle.label | &remote_string [&ref] | +| sqlx.rs:102:84:102:96 | remote_string | semmle.label | remote_string | +| sqlx.rs:113:17:113:29 | ...::raw_sql | semmle.label | ...::raw_sql | +| sqlx.rs:113:31:113:44 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:113:31:113:53 | unsafe_query_1.as_str() | semmle.label | unsafe_query_1.as_str() | +| sqlx.rs:113:31:113:53 | unsafe_query_1.as_str() [&ref] | semmle.label | unsafe_query_1.as_str() [&ref] | +| sqlx.rs:120:17:120:27 | ...::query | semmle.label | ...::query | +| sqlx.rs:120:29:120:42 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:120:29:120:51 | unsafe_query_1.as_str() | semmle.label | unsafe_query_1.as_str() | +| sqlx.rs:120:29:120:51 | unsafe_query_1.as_str() [&ref] | semmle.label | unsafe_query_1.as_str() [&ref] | +| sqlx.rs:127:17:127:27 | ...::query | semmle.label | ...::query | +| sqlx.rs:127:29:127:42 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:127:29:127:51 | unsafe_query_1.as_str() | semmle.label | unsafe_query_1.as_str() | +| sqlx.rs:127:29:127:51 | unsafe_query_1.as_str() [&ref] | semmle.label | unsafe_query_1.as_str() [&ref] | +| sqlx.rs:136:40:136:53 | ...::query_as | semmle.label | ...::query_as | +| sqlx.rs:136:55:136:68 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:136:55:136:77 | unsafe_query_1.as_str() | semmle.label | unsafe_query_1.as_str() | +| sqlx.rs:136:55:136:77 | unsafe_query_1.as_str() [&ref] | semmle.label | unsafe_query_1.as_str() [&ref] | +| sqlx.rs:145:40:145:53 | ...::query_as | semmle.label | ...::query_as | +| sqlx.rs:145:55:145:68 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:145:55:145:77 | unsafe_query_1.as_str() | semmle.label | unsafe_query_1.as_str() | +| sqlx.rs:145:55:145:77 | unsafe_query_1.as_str() [&ref] | semmle.label | unsafe_query_1.as_str() [&ref] | +| sqlx.rs:153:17:153:27 | ...::query | semmle.label | ...::query | +| sqlx.rs:153:29:153:42 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:153:29:153:51 | unsafe_query_1.as_str() | semmle.label | unsafe_query_1.as_str() | +| sqlx.rs:153:29:153:51 | unsafe_query_1.as_str() [&ref] | semmle.label | unsafe_query_1.as_str() [&ref] | +| sqlx.rs:173:9:173:21 | remote_string | semmle.label | remote_string | +| sqlx.rs:173:25:173:46 | ...::get | semmle.label | ...::get | +| sqlx.rs:173:25:173:69 | ...::get(...) [Ok] | semmle.label | ...::get(...) [Ok] | +| sqlx.rs:173:25:173:78 | ... .unwrap() | semmle.label | ... .unwrap() | +| sqlx.rs:173:25:173:85 | ... .text() [Ok] | semmle.label | ... .text() [Ok] | +| sqlx.rs:173:25:173:118 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) | +| sqlx.rs:175:9:175:22 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:175:26:175:96 | ... + ... | semmle.label | ... + ... | +| sqlx.rs:175:26:175:102 | ... + ... | semmle.label | ... + ... | +| sqlx.rs:175:83:175:96 | &remote_string [&ref] | semmle.label | &remote_string [&ref] | +| sqlx.rs:175:84:175:96 | remote_string | semmle.label | remote_string | +| sqlx.rs:188:17:188:27 | ...::query | semmle.label | ...::query | +| sqlx.rs:188:29:188:42 | unsafe_query_1 | semmle.label | unsafe_query_1 | +| sqlx.rs:188:29:188:51 | unsafe_query_1.as_str() | semmle.label | unsafe_query_1.as_str() | +| sqlx.rs:188:29:188:51 | unsafe_query_1.as_str() [&ref] | semmle.label | unsafe_query_1.as_str() [&ref] | subpaths diff --git a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs index 7f244c4b4cb..151f9fa7c82 100644 --- a/rust/ql/test/query-tests/security/CWE-089/sqlx.rs +++ b/rust/ql/test/query-tests/security/CWE-089/sqlx.rs @@ -78,7 +78,7 @@ async fn test_sqlx_mysql(url: &str, enable_remote: bool) -> Result<(), sqlx::Err let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ sql-sink Alert[rust/sql-injection]=args1 if enable_remote { let _ = sqlx::query(unsafe_query_2.as_str()).execute(&pool).await?; // $ sql-sink Alert[rust/sql-injection]=remote1 - let _ = sqlx::query(unsafe_query_3.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote1 + let _ = sqlx::query(unsafe_query_3.as_str()).execute(&pool).await?; // $ sql-sink Alert[rust/sql-injection]=remote1 let _ = sqlx::query(unsafe_query_4.as_str()).execute(&pool).await?; // $ sql-sink Alert[rust/sql-injection]=remote1 } let _ = sqlx::query(prepared_query_1.as_str()).bind(const_string).execute(&pool).await?; // $ sql-sink @@ -97,7 +97,7 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er // construct queries let const_string = String::from("Alice"); - let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING: Source=remote2 + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ Source=remote2 let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'"; let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=?"); // (prepared arguments are safe) @@ -110,21 +110,21 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er // ... let _ = sqlx::raw_sql(safe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink if enable_remote { - let _ = sqlx::raw_sql(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote2 + let _ = sqlx::raw_sql(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink Alert[rust/sql-injection]=remote2 } // prepared queries (with extra variants) let _ = sqlx::query(safe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&mut conn).await?; // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote2 + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&mut conn).await?; // $ sql-sink Alert[rust/sql-injection]=remote2 let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&mut conn).await?; // $ sql-sink } // ... let _ = sqlx::query(safe_query_1.as_str()).fetch(&mut conn); // $ sql-sink let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch(&mut conn); // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).fetch(&mut conn); // $ sql-sink MISSING: Alert[rust/sql-injection]=remote2 + let _ = sqlx::query(unsafe_query_1.as_str()).fetch(&mut conn); // $ sql-sink Alert[rust/sql-injection]=remote2 let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch(&mut conn); // $ sql-sink } // ... @@ -133,7 +133,7 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er let row2: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_one(&mut conn).await?; // $ sql-sink println!(" row2 = {:?}", row2); if enable_remote { - let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_one(&mut conn).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote2 + let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_one(&mut conn).await?; // $ sql-sink Alert[rust/sql-injection]=remote2 let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_one(&mut conn).await?; // $ sql-sink } // ... @@ -142,7 +142,7 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er let row4: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&const_string).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink println!(" row4 = {:?}", row4); if enable_remote { - let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink $ MISSING: Alert[rust/sql-injection]=remote2 + let _: (i64, String, String) = sqlx::query_as(unsafe_query_1.as_str()).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink $ Alert[rust/sql-injection]=remote2 let _: (i64, String, String) = sqlx::query_as(prepared_query_1.as_str()).bind(&remote_string).fetch_optional(&mut conn).await?.expect("no data"); // $ sql-sink } // ... @@ -150,7 +150,7 @@ async fn test_sqlx_sqlite(url: &str, enable_remote: bool) -> Result<(), sqlx::Er let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).fetch_all(&mut conn).await?; // $ sql-sink let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&const_string).fetch_all(&mut conn).await?; // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).fetch_all(&mut conn).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote2 + let _ = sqlx::query(unsafe_query_1.as_str()).fetch_all(&mut conn).await?; // $ sql-sink Alert[rust/sql-injection]=remote2 let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).fetch_all(&mut conn).await?; // $ sql-sink let _ = sqlx::query("SELECT * FROM people WHERE firstname=?").bind(&remote_string).fetch_all(&mut conn).await?; // $ sql-sink } @@ -170,7 +170,7 @@ async fn test_sqlx_postgres(url: &str, enable_remote: bool) -> Result<(), sqlx:: // construct queries let const_string = String::from("Alice"); - let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ MISSING: Source=remote3 + let remote_string = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap_or(String::from("Alice")); // $ Source=remote3 let safe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &const_string + "'"; let unsafe_query_1 = String::from("SELECT * FROM people WHERE firstname='") + &remote_string + "'"; let prepared_query_1 = String::from("SELECT * FROM people WHERE firstname=$1"); // (prepared arguments are safe) @@ -185,7 +185,7 @@ async fn test_sqlx_postgres(url: &str, enable_remote: bool) -> Result<(), sqlx:: let _ = sqlx::query(safe_query_1.as_str()).execute(&pool).await?; // $ sql-sink let _ = sqlx::query(prepared_query_1.as_str()).bind(&const_string).execute(&pool).await?; // $ sql-sink if enable_remote { - let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ sql-sink MISSING: Alert[rust/sql-injection]=remote3 + let _ = sqlx::query(unsafe_query_1.as_str()).execute(&pool).await?; // $ sql-sink Alert[rust/sql-injection]=remote3 let _ = sqlx::query(prepared_query_1.as_str()).bind(&remote_string).execute(&pool).await?; // $ sql-sink } diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected index 01d3b06a854..3e7264cf02f 100644 --- a/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected +++ b/rust/ql/test/query-tests/security/CWE-312/CleartextLogging.expected @@ -136,15 +136,19 @@ edges | test_logging.rs:93:15:93:22 | password | test_logging.rs:93:14:93:22 | &password | provenance | Config | | test_logging.rs:94:11:94:28 | MacroExpr | test_logging.rs:94:5:94:9 | ...::log | provenance | MaD:12 Sink:MaD:12 | | test_logging.rs:96:9:96:10 | m2 | test_logging.rs:97:11:97:18 | MacroExpr | provenance | | +| test_logging.rs:96:14:96:49 | ... + ... | test_logging.rs:96:9:96:10 | m2 | provenance | | | test_logging.rs:96:41:96:49 | &password | test_logging.rs:96:9:96:10 | m2 | provenance | | +| test_logging.rs:96:41:96:49 | &password | test_logging.rs:96:14:96:49 | ... + ... | provenance | MaD:17 | +| test_logging.rs:96:41:96:49 | &password [&ref] | test_logging.rs:96:14:96:49 | ... + ... | provenance | MaD:17 | | test_logging.rs:96:42:96:49 | password | test_logging.rs:96:41:96:49 | &password | provenance | Config | +| test_logging.rs:96:42:96:49 | password | test_logging.rs:96:41:96:49 | &password [&ref] | provenance | | | test_logging.rs:97:11:97:18 | MacroExpr | test_logging.rs:97:5:97:9 | ...::log | provenance | MaD:12 Sink:MaD:12 | | test_logging.rs:99:9:99:10 | m3 | test_logging.rs:100:11:100:18 | MacroExpr | provenance | | | test_logging.rs:99:14:99:20 | res | test_logging.rs:99:22:99:45 | { ... } | provenance | | | test_logging.rs:99:22:99:45 | ...::format(...) | test_logging.rs:99:14:99:20 | res | provenance | | | test_logging.rs:99:22:99:45 | ...::must_use(...) | test_logging.rs:99:9:99:10 | m3 | provenance | | -| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:21 | -| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:22 | +| test_logging.rs:99:22:99:45 | MacroExpr | test_logging.rs:99:22:99:45 | ...::format(...) | provenance | MaD:22 | +| test_logging.rs:99:22:99:45 | { ... } | test_logging.rs:99:22:99:45 | ...::must_use(...) | provenance | MaD:23 | | test_logging.rs:99:38:99:45 | password | test_logging.rs:99:22:99:45 | MacroExpr | provenance | | | test_logging.rs:100:11:100:18 | MacroExpr | test_logging.rs:100:5:100:9 | ...::log | provenance | MaD:12 Sink:MaD:12 | | test_logging.rs:118:12:118:41 | MacroExpr | test_logging.rs:118:5:118:10 | ...::log | provenance | MaD:12 Sink:MaD:12 | @@ -166,8 +170,8 @@ edges | test_logging.rs:176:34:176:79 | MacroExpr | test_logging.rs:176:33:176:79 | &... [&ref] | provenance | | | test_logging.rs:176:42:176:78 | ...::format(...) | test_logging.rs:176:34:176:40 | res | provenance | | | test_logging.rs:176:42:176:78 | ...::must_use(...) | test_logging.rs:176:34:176:79 | MacroExpr | provenance | | -| test_logging.rs:176:42:176:78 | MacroExpr | test_logging.rs:176:42:176:78 | ...::format(...) | provenance | MaD:21 | -| test_logging.rs:176:42:176:78 | { ... } | test_logging.rs:176:42:176:78 | ...::must_use(...) | provenance | MaD:22 | +| test_logging.rs:176:42:176:78 | MacroExpr | test_logging.rs:176:42:176:78 | ...::format(...) | provenance | MaD:22 | +| test_logging.rs:176:42:176:78 | { ... } | test_logging.rs:176:42:176:78 | ...::must_use(...) | provenance | MaD:23 | | test_logging.rs:176:70:176:78 | password2 | test_logging.rs:176:42:176:78 | MacroExpr | provenance | | | test_logging.rs:180:35:180:81 | &... | test_logging.rs:180:24:180:33 | log_expect | provenance | MaD:3 Sink:MaD:3 | | test_logging.rs:180:35:180:81 | &... [&ref] | test_logging.rs:180:24:180:33 | log_expect | provenance | MaD:3 Sink:MaD:3 | @@ -176,8 +180,8 @@ edges | test_logging.rs:180:36:180:81 | MacroExpr | test_logging.rs:180:35:180:81 | &... [&ref] | provenance | | | test_logging.rs:180:44:180:80 | ...::format(...) | test_logging.rs:180:36:180:42 | res | provenance | | | test_logging.rs:180:44:180:80 | ...::must_use(...) | test_logging.rs:180:36:180:81 | MacroExpr | provenance | | -| test_logging.rs:180:44:180:80 | MacroExpr | test_logging.rs:180:44:180:80 | ...::format(...) | provenance | MaD:21 | -| test_logging.rs:180:44:180:80 | { ... } | test_logging.rs:180:44:180:80 | ...::must_use(...) | provenance | MaD:22 | +| test_logging.rs:180:44:180:80 | MacroExpr | test_logging.rs:180:44:180:80 | ...::format(...) | provenance | MaD:22 | +| test_logging.rs:180:44:180:80 | { ... } | test_logging.rs:180:44:180:80 | ...::must_use(...) | provenance | MaD:23 | | test_logging.rs:180:72:180:80 | password2 | test_logging.rs:180:44:180:80 | MacroExpr | provenance | | | test_logging.rs:183:9:183:19 | err_result2 [Err] | test_logging.rs:184:13:184:23 | err_result2 [Err] | provenance | | | test_logging.rs:183:47:183:68 | Err(...) [Err] | test_logging.rs:183:9:183:19 | err_result2 [Err] | provenance | | @@ -229,68 +233,68 @@ edges | test_logging.rs:226:36:226:59 | MacroExpr | test_logging.rs:226:36:226:59 | ...::Some(...) [Some] | provenance | | | test_logging.rs:226:52:226:59 | password | test_logging.rs:226:36:226:59 | MacroExpr | provenance | | | test_logging.rs:229:30:229:36 | res | test_logging.rs:229:38:229:61 | { ... } | provenance | | -| test_logging.rs:229:30:229:62 | MacroExpr | test_logging.rs:229:30:229:71 | ... .as_str() [&ref] | provenance | MaD:20 | -| test_logging.rs:229:30:229:62 | MacroExpr | test_logging.rs:229:30:229:71 | ... .as_str() [&ref] | provenance | MaD:18 | -| test_logging.rs:229:30:229:62 | MacroExpr | test_logging.rs:229:30:229:71 | ... .as_str() [&ref] | provenance | MaD:20 | +| test_logging.rs:229:30:229:62 | MacroExpr | test_logging.rs:229:30:229:71 | ... .as_str() [&ref] | provenance | MaD:21 | +| test_logging.rs:229:30:229:62 | MacroExpr | test_logging.rs:229:30:229:71 | ... .as_str() [&ref] | provenance | MaD:19 | +| test_logging.rs:229:30:229:62 | MacroExpr | test_logging.rs:229:30:229:71 | ... .as_str() [&ref] | provenance | MaD:21 | | test_logging.rs:229:30:229:71 | ... .as_str() | test_logging.rs:229:23:229:28 | expect | provenance | MaD:2 Sink:MaD:2 | | test_logging.rs:229:30:229:71 | ... .as_str() | test_logging.rs:229:23:229:28 | expect | provenance | MaD:2 Sink:MaD:2 | | test_logging.rs:229:30:229:71 | ... .as_str() [&ref] | test_logging.rs:229:23:229:28 | expect | provenance | MaD:2 Sink:MaD:2 | | test_logging.rs:229:30:229:71 | ... .as_str() [&ref] | test_logging.rs:229:23:229:28 | expect | provenance | MaD:2 Sink:MaD:2 | | test_logging.rs:229:38:229:61 | ...::format(...) | test_logging.rs:229:30:229:36 | res | provenance | | | test_logging.rs:229:38:229:61 | ...::must_use(...) | test_logging.rs:229:30:229:62 | MacroExpr | provenance | | -| test_logging.rs:229:38:229:61 | ...::must_use(...) | test_logging.rs:229:30:229:71 | ... .as_str() | provenance | MaD:20 | -| test_logging.rs:229:38:229:61 | ...::must_use(...) | test_logging.rs:229:30:229:71 | ... .as_str() | provenance | MaD:18 | -| test_logging.rs:229:38:229:61 | ...::must_use(...) | test_logging.rs:229:30:229:71 | ... .as_str() | provenance | MaD:20 | -| test_logging.rs:229:38:229:61 | MacroExpr | test_logging.rs:229:38:229:61 | ...::format(...) | provenance | MaD:21 | -| test_logging.rs:229:38:229:61 | { ... } | test_logging.rs:229:38:229:61 | ...::must_use(...) | provenance | MaD:22 | +| test_logging.rs:229:38:229:61 | ...::must_use(...) | test_logging.rs:229:30:229:71 | ... .as_str() | provenance | MaD:21 | +| test_logging.rs:229:38:229:61 | ...::must_use(...) | test_logging.rs:229:30:229:71 | ... .as_str() | provenance | MaD:19 | +| test_logging.rs:229:38:229:61 | ...::must_use(...) | test_logging.rs:229:30:229:71 | ... .as_str() | provenance | MaD:21 | +| test_logging.rs:229:38:229:61 | MacroExpr | test_logging.rs:229:38:229:61 | ...::format(...) | provenance | MaD:22 | +| test_logging.rs:229:38:229:61 | { ... } | test_logging.rs:229:38:229:61 | ...::must_use(...) | provenance | MaD:23 | | test_logging.rs:229:54:229:61 | password | test_logging.rs:229:38:229:61 | MacroExpr | provenance | | | test_logging.rs:242:16:242:22 | res | test_logging.rs:242:24:242:49 | { ... } | provenance | | -| test_logging.rs:242:16:242:50 | MacroExpr | test_logging.rs:242:16:242:61 | ... .as_bytes() [&ref] | provenance | MaD:19 | -| test_logging.rs:242:16:242:50 | MacroExpr | test_logging.rs:242:16:242:61 | ... .as_bytes() [&ref] | provenance | MaD:17 | +| test_logging.rs:242:16:242:50 | MacroExpr | test_logging.rs:242:16:242:61 | ... .as_bytes() [&ref] | provenance | MaD:20 | +| test_logging.rs:242:16:242:50 | MacroExpr | test_logging.rs:242:16:242:61 | ... .as_bytes() [&ref] | provenance | MaD:18 | | test_logging.rs:242:16:242:61 | ... .as_bytes() | test_logging.rs:242:10:242:14 | write | provenance | MaD:7 Sink:MaD:7 | | test_logging.rs:242:16:242:61 | ... .as_bytes() [&ref] | test_logging.rs:242:10:242:14 | write | provenance | MaD:7 Sink:MaD:7 | | test_logging.rs:242:24:242:49 | ...::format(...) | test_logging.rs:242:16:242:22 | res | provenance | | | test_logging.rs:242:24:242:49 | ...::must_use(...) | test_logging.rs:242:16:242:50 | MacroExpr | provenance | | -| test_logging.rs:242:24:242:49 | ...::must_use(...) | test_logging.rs:242:16:242:61 | ... .as_bytes() | provenance | MaD:19 | -| test_logging.rs:242:24:242:49 | ...::must_use(...) | test_logging.rs:242:16:242:61 | ... .as_bytes() | provenance | MaD:17 | -| test_logging.rs:242:24:242:49 | MacroExpr | test_logging.rs:242:24:242:49 | ...::format(...) | provenance | MaD:21 | -| test_logging.rs:242:24:242:49 | { ... } | test_logging.rs:242:24:242:49 | ...::must_use(...) | provenance | MaD:22 | +| test_logging.rs:242:24:242:49 | ...::must_use(...) | test_logging.rs:242:16:242:61 | ... .as_bytes() | provenance | MaD:20 | +| test_logging.rs:242:24:242:49 | ...::must_use(...) | test_logging.rs:242:16:242:61 | ... .as_bytes() | provenance | MaD:18 | +| test_logging.rs:242:24:242:49 | MacroExpr | test_logging.rs:242:24:242:49 | ...::format(...) | provenance | MaD:22 | +| test_logging.rs:242:24:242:49 | { ... } | test_logging.rs:242:24:242:49 | ...::must_use(...) | provenance | MaD:23 | | test_logging.rs:242:42:242:49 | password | test_logging.rs:242:24:242:49 | MacroExpr | provenance | | | test_logging.rs:245:20:245:26 | res | test_logging.rs:245:28:245:53 | { ... } | provenance | | -| test_logging.rs:245:20:245:54 | MacroExpr | test_logging.rs:245:20:245:65 | ... .as_bytes() [&ref] | provenance | MaD:19 | -| test_logging.rs:245:20:245:54 | MacroExpr | test_logging.rs:245:20:245:65 | ... .as_bytes() [&ref] | provenance | MaD:17 | +| test_logging.rs:245:20:245:54 | MacroExpr | test_logging.rs:245:20:245:65 | ... .as_bytes() [&ref] | provenance | MaD:20 | +| test_logging.rs:245:20:245:54 | MacroExpr | test_logging.rs:245:20:245:65 | ... .as_bytes() [&ref] | provenance | MaD:18 | | test_logging.rs:245:20:245:65 | ... .as_bytes() | test_logging.rs:245:10:245:18 | write_all | provenance | MaD:8 Sink:MaD:8 | | test_logging.rs:245:20:245:65 | ... .as_bytes() [&ref] | test_logging.rs:245:10:245:18 | write_all | provenance | MaD:8 Sink:MaD:8 | | test_logging.rs:245:28:245:53 | ...::format(...) | test_logging.rs:245:20:245:26 | res | provenance | | | test_logging.rs:245:28:245:53 | ...::must_use(...) | test_logging.rs:245:20:245:54 | MacroExpr | provenance | | -| test_logging.rs:245:28:245:53 | ...::must_use(...) | test_logging.rs:245:20:245:65 | ... .as_bytes() | provenance | MaD:19 | -| test_logging.rs:245:28:245:53 | ...::must_use(...) | test_logging.rs:245:20:245:65 | ... .as_bytes() | provenance | MaD:17 | -| test_logging.rs:245:28:245:53 | MacroExpr | test_logging.rs:245:28:245:53 | ...::format(...) | provenance | MaD:21 | -| test_logging.rs:245:28:245:53 | { ... } | test_logging.rs:245:28:245:53 | ...::must_use(...) | provenance | MaD:22 | +| test_logging.rs:245:28:245:53 | ...::must_use(...) | test_logging.rs:245:20:245:65 | ... .as_bytes() | provenance | MaD:20 | +| test_logging.rs:245:28:245:53 | ...::must_use(...) | test_logging.rs:245:20:245:65 | ... .as_bytes() | provenance | MaD:18 | +| test_logging.rs:245:28:245:53 | MacroExpr | test_logging.rs:245:28:245:53 | ...::format(...) | provenance | MaD:22 | +| test_logging.rs:245:28:245:53 | { ... } | test_logging.rs:245:28:245:53 | ...::must_use(...) | provenance | MaD:23 | | test_logging.rs:245:46:245:53 | password | test_logging.rs:245:28:245:53 | MacroExpr | provenance | | | test_logging.rs:248:15:248:21 | res | test_logging.rs:248:23:248:48 | { ... } | provenance | | -| test_logging.rs:248:15:248:49 | MacroExpr | test_logging.rs:248:15:248:60 | ... .as_bytes() [&ref] | provenance | MaD:19 | -| test_logging.rs:248:15:248:49 | MacroExpr | test_logging.rs:248:15:248:60 | ... .as_bytes() [&ref] | provenance | MaD:17 | +| test_logging.rs:248:15:248:49 | MacroExpr | test_logging.rs:248:15:248:60 | ... .as_bytes() [&ref] | provenance | MaD:20 | +| test_logging.rs:248:15:248:49 | MacroExpr | test_logging.rs:248:15:248:60 | ... .as_bytes() [&ref] | provenance | MaD:18 | | test_logging.rs:248:15:248:60 | ... .as_bytes() | test_logging.rs:248:9:248:13 | write | provenance | MaD:7 Sink:MaD:7 | | test_logging.rs:248:15:248:60 | ... .as_bytes() [&ref] | test_logging.rs:248:9:248:13 | write | provenance | MaD:7 Sink:MaD:7 | | test_logging.rs:248:23:248:48 | ...::format(...) | test_logging.rs:248:15:248:21 | res | provenance | | | test_logging.rs:248:23:248:48 | ...::must_use(...) | test_logging.rs:248:15:248:49 | MacroExpr | provenance | | -| test_logging.rs:248:23:248:48 | ...::must_use(...) | test_logging.rs:248:15:248:60 | ... .as_bytes() | provenance | MaD:19 | -| test_logging.rs:248:23:248:48 | ...::must_use(...) | test_logging.rs:248:15:248:60 | ... .as_bytes() | provenance | MaD:17 | -| test_logging.rs:248:23:248:48 | MacroExpr | test_logging.rs:248:23:248:48 | ...::format(...) | provenance | MaD:21 | -| test_logging.rs:248:23:248:48 | { ... } | test_logging.rs:248:23:248:48 | ...::must_use(...) | provenance | MaD:22 | +| test_logging.rs:248:23:248:48 | ...::must_use(...) | test_logging.rs:248:15:248:60 | ... .as_bytes() | provenance | MaD:20 | +| test_logging.rs:248:23:248:48 | ...::must_use(...) | test_logging.rs:248:15:248:60 | ... .as_bytes() | provenance | MaD:18 | +| test_logging.rs:248:23:248:48 | MacroExpr | test_logging.rs:248:23:248:48 | ...::format(...) | provenance | MaD:22 | +| test_logging.rs:248:23:248:48 | { ... } | test_logging.rs:248:23:248:48 | ...::must_use(...) | provenance | MaD:23 | | test_logging.rs:248:41:248:48 | password | test_logging.rs:248:23:248:48 | MacroExpr | provenance | | | test_logging.rs:251:15:251:21 | res | test_logging.rs:251:23:251:48 | { ... } | provenance | | -| test_logging.rs:251:15:251:49 | MacroExpr | test_logging.rs:251:15:251:60 | ... .as_bytes() [&ref] | provenance | MaD:19 | -| test_logging.rs:251:15:251:49 | MacroExpr | test_logging.rs:251:15:251:60 | ... .as_bytes() [&ref] | provenance | MaD:17 | +| test_logging.rs:251:15:251:49 | MacroExpr | test_logging.rs:251:15:251:60 | ... .as_bytes() [&ref] | provenance | MaD:20 | +| test_logging.rs:251:15:251:49 | MacroExpr | test_logging.rs:251:15:251:60 | ... .as_bytes() [&ref] | provenance | MaD:18 | | test_logging.rs:251:15:251:60 | ... .as_bytes() | test_logging.rs:251:9:251:13 | write | provenance | MaD:6 Sink:MaD:6 | | test_logging.rs:251:15:251:60 | ... .as_bytes() [&ref] | test_logging.rs:251:9:251:13 | write | provenance | MaD:6 Sink:MaD:6 | | test_logging.rs:251:23:251:48 | ...::format(...) | test_logging.rs:251:15:251:21 | res | provenance | | | test_logging.rs:251:23:251:48 | ...::must_use(...) | test_logging.rs:251:15:251:49 | MacroExpr | provenance | | -| test_logging.rs:251:23:251:48 | ...::must_use(...) | test_logging.rs:251:15:251:60 | ... .as_bytes() | provenance | MaD:19 | -| test_logging.rs:251:23:251:48 | ...::must_use(...) | test_logging.rs:251:15:251:60 | ... .as_bytes() | provenance | MaD:17 | -| test_logging.rs:251:23:251:48 | MacroExpr | test_logging.rs:251:23:251:48 | ...::format(...) | provenance | MaD:21 | -| test_logging.rs:251:23:251:48 | { ... } | test_logging.rs:251:23:251:48 | ...::must_use(...) | provenance | MaD:22 | +| test_logging.rs:251:23:251:48 | ...::must_use(...) | test_logging.rs:251:15:251:60 | ... .as_bytes() | provenance | MaD:20 | +| test_logging.rs:251:23:251:48 | ...::must_use(...) | test_logging.rs:251:15:251:60 | ... .as_bytes() | provenance | MaD:18 | +| test_logging.rs:251:23:251:48 | MacroExpr | test_logging.rs:251:23:251:48 | ...::format(...) | provenance | MaD:22 | +| test_logging.rs:251:23:251:48 | { ... } | test_logging.rs:251:23:251:48 | ...::must_use(...) | provenance | MaD:23 | | test_logging.rs:251:41:251:48 | password | test_logging.rs:251:23:251:48 | MacroExpr | provenance | | models | 1 | Sink: ::log_expect; Argument[0]; log-injection | @@ -309,12 +313,13 @@ models | 14 | Sink: std::io::stdio::_eprint; Argument[0]; log-injection | | 15 | Sink: std::io::stdio::_print; Argument[0]; log-injection | | 16 | Summary: <_ as core::clone::Clone>::clone; Argument[self].Reference; ReturnValue; value | -| 17 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | -| 18 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 19 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | -| 20 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 21 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | -| 22 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value | +| 17 | Summary: ::add; Argument[0].Reference; ReturnValue; taint | +| 18 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | +| 19 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 20 | Summary: ::as_bytes; Argument[self]; ReturnValue; value | +| 21 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 22 | Summary: alloc::fmt::format; Argument[0]; ReturnValue; taint | +| 23 | Summary: core::hint::must_use; Argument[0]; ReturnValue; value | nodes | test_logging.rs:42:5:42:10 | ...::log | semmle.label | ...::log | | test_logging.rs:42:12:42:35 | MacroExpr | semmle.label | MacroExpr | @@ -414,7 +419,9 @@ nodes | test_logging.rs:94:5:94:9 | ...::log | semmle.label | ...::log | | test_logging.rs:94:11:94:28 | MacroExpr | semmle.label | MacroExpr | | test_logging.rs:96:9:96:10 | m2 | semmle.label | m2 | +| test_logging.rs:96:14:96:49 | ... + ... | semmle.label | ... + ... | | test_logging.rs:96:41:96:49 | &password | semmle.label | &password | +| test_logging.rs:96:41:96:49 | &password [&ref] | semmle.label | &password [&ref] | | test_logging.rs:96:42:96:49 | password | semmle.label | password | | test_logging.rs:97:5:97:9 | ...::log | semmle.label | ...::log | | test_logging.rs:97:11:97:18 | MacroExpr | semmle.label | MacroExpr | diff --git a/rust/ql/test/query-tests/security/CWE-312/CleartextStorageDatabase.expected b/rust/ql/test/query-tests/security/CWE-312/CleartextStorageDatabase.expected index 028b2d88ac3..3f0171042a1 100644 --- a/rust/ql/test/query-tests/security/CWE-312/CleartextStorageDatabase.expected +++ b/rust/ql/test/query-tests/security/CWE-312/CleartextStorageDatabase.expected @@ -9,70 +9,79 @@ | test_storage.rs:204:31:204:37 | prepare | test_storage.rs:190:86:190:103 | get_phone_number(...) | test_storage.rs:204:31:204:37 | prepare | This database operation may read or write unencrypted sensitive data from $@. | test_storage.rs:190:86:190:103 | get_phone_number(...) | get_phone_number(...) | edges | test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:100:25:100:37 | insert_query2 | provenance | | +| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:100:25:100:46 | insert_query2.as_str() | provenance | MaD:9 | | test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:100:25:100:46 | insert_query2.as_str() | provenance | MaD:8 | -| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:100:25:100:46 | insert_query2.as_str() | provenance | MaD:7 | -| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:100:25:100:46 | insert_query2.as_str() | provenance | MaD:8 | +| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:100:25:100:46 | insert_query2.as_str() | provenance | MaD:9 | | test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:115:27:115:39 | insert_query2 | provenance | | +| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:115:27:115:48 | insert_query2.as_str() | provenance | MaD:9 | | test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:115:27:115:48 | insert_query2.as_str() | provenance | MaD:8 | -| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:115:27:115:48 | insert_query2.as_str() | provenance | MaD:7 | -| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:115:27:115:48 | insert_query2.as_str() | provenance | MaD:8 | +| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:115:27:115:48 | insert_query2.as_str() | provenance | MaD:9 | | test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:119:25:119:37 | insert_query2 | provenance | | +| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:119:25:119:46 | insert_query2.as_str() | provenance | MaD:9 | | test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:119:25:119:46 | insert_query2.as_str() | provenance | MaD:8 | -| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:119:25:119:46 | insert_query2.as_str() | provenance | MaD:7 | -| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:119:25:119:46 | insert_query2.as_str() | provenance | MaD:8 | +| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:119:25:119:46 | insert_query2.as_str() | provenance | MaD:9 | | test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:125:25:125:37 | insert_query2 | provenance | | +| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:125:25:125:46 | insert_query2.as_str() | provenance | MaD:9 | | test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:125:25:125:46 | insert_query2.as_str() | provenance | MaD:8 | -| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:125:25:125:46 | insert_query2.as_str() | provenance | MaD:7 | -| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:125:25:125:46 | insert_query2.as_str() | provenance | MaD:8 | +| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:125:25:125:46 | insert_query2.as_str() | provenance | MaD:9 | | test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:139:25:139:37 | insert_query2 | provenance | | +| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:139:25:139:46 | insert_query2.as_str() | provenance | MaD:9 | | test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:139:25:139:46 | insert_query2.as_str() | provenance | MaD:8 | -| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:139:25:139:46 | insert_query2.as_str() | provenance | MaD:7 | -| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:139:25:139:46 | insert_query2.as_str() | provenance | MaD:8 | +| test_storage.rs:71:9:71:21 | insert_query2 | test_storage.rs:139:25:139:46 | insert_query2.as_str() | provenance | MaD:9 | | test_storage.rs:71:25:71:114 | ... + ... | test_storage.rs:71:9:71:21 | insert_query2 | provenance | | -| test_storage.rs:71:25:71:114 | ... + ... | test_storage.rs:71:25:71:121 | ... + ... | provenance | MaD:6 | +| test_storage.rs:71:25:71:114 | ... + ... | test_storage.rs:71:25:71:121 | ... + ... | provenance | MaD:7 | | test_storage.rs:71:25:71:121 | ... + ... | test_storage.rs:71:9:71:21 | insert_query2 | provenance | | | test_storage.rs:71:96:71:114 | &... | test_storage.rs:71:9:71:21 | insert_query2 | provenance | | | test_storage.rs:71:96:71:114 | &... | test_storage.rs:71:25:71:114 | ... + ... | provenance | | +| test_storage.rs:71:96:71:114 | &... | test_storage.rs:71:25:71:114 | ... + ... | provenance | MaD:6 | +| test_storage.rs:71:96:71:114 | &... [&ref] | test_storage.rs:71:25:71:114 | ... + ... | provenance | MaD:6 | | test_storage.rs:71:97:71:114 | get_phone_number(...) | test_storage.rs:71:96:71:114 | &... | provenance | Config | +| test_storage.rs:71:97:71:114 | get_phone_number(...) | test_storage.rs:71:96:71:114 | &... [&ref] | provenance | | +| test_storage.rs:100:25:100:37 | insert_query2 | test_storage.rs:100:25:100:46 | insert_query2.as_str() [&ref] | provenance | MaD:9 | | test_storage.rs:100:25:100:37 | insert_query2 | test_storage.rs:100:25:100:46 | insert_query2.as_str() [&ref] | provenance | MaD:8 | -| test_storage.rs:100:25:100:37 | insert_query2 | test_storage.rs:100:25:100:46 | insert_query2.as_str() [&ref] | provenance | MaD:7 | -| test_storage.rs:100:25:100:37 | insert_query2 | test_storage.rs:100:25:100:46 | insert_query2.as_str() [&ref] | provenance | MaD:8 | +| test_storage.rs:100:25:100:37 | insert_query2 | test_storage.rs:100:25:100:46 | insert_query2.as_str() [&ref] | provenance | MaD:9 | | test_storage.rs:100:25:100:46 | insert_query2.as_str() | test_storage.rs:100:13:100:23 | ...::query | provenance | MaD:4 Sink:MaD:4 | | test_storage.rs:100:25:100:46 | insert_query2.as_str() [&ref] | test_storage.rs:100:13:100:23 | ...::query | provenance | MaD:4 Sink:MaD:4 | +| test_storage.rs:115:27:115:39 | insert_query2 | test_storage.rs:115:27:115:48 | insert_query2.as_str() [&ref] | provenance | MaD:9 | | test_storage.rs:115:27:115:39 | insert_query2 | test_storage.rs:115:27:115:48 | insert_query2.as_str() [&ref] | provenance | MaD:8 | -| test_storage.rs:115:27:115:39 | insert_query2 | test_storage.rs:115:27:115:48 | insert_query2.as_str() [&ref] | provenance | MaD:7 | -| test_storage.rs:115:27:115:39 | insert_query2 | test_storage.rs:115:27:115:48 | insert_query2.as_str() [&ref] | provenance | MaD:8 | +| test_storage.rs:115:27:115:39 | insert_query2 | test_storage.rs:115:27:115:48 | insert_query2.as_str() [&ref] | provenance | MaD:9 | | test_storage.rs:115:27:115:48 | insert_query2.as_str() | test_storage.rs:115:13:115:25 | ...::raw_sql | provenance | MaD:5 Sink:MaD:5 | | test_storage.rs:115:27:115:48 | insert_query2.as_str() [&ref] | test_storage.rs:115:13:115:25 | ...::raw_sql | provenance | MaD:5 Sink:MaD:5 | +| test_storage.rs:119:25:119:37 | insert_query2 | test_storage.rs:119:25:119:46 | insert_query2.as_str() [&ref] | provenance | MaD:9 | | test_storage.rs:119:25:119:37 | insert_query2 | test_storage.rs:119:25:119:46 | insert_query2.as_str() [&ref] | provenance | MaD:8 | -| test_storage.rs:119:25:119:37 | insert_query2 | test_storage.rs:119:25:119:46 | insert_query2.as_str() [&ref] | provenance | MaD:7 | -| test_storage.rs:119:25:119:37 | insert_query2 | test_storage.rs:119:25:119:46 | insert_query2.as_str() [&ref] | provenance | MaD:8 | +| test_storage.rs:119:25:119:37 | insert_query2 | test_storage.rs:119:25:119:46 | insert_query2.as_str() [&ref] | provenance | MaD:9 | | test_storage.rs:119:25:119:46 | insert_query2.as_str() | test_storage.rs:119:13:119:23 | ...::query | provenance | MaD:4 Sink:MaD:4 | | test_storage.rs:119:25:119:46 | insert_query2.as_str() [&ref] | test_storage.rs:119:13:119:23 | ...::query | provenance | MaD:4 Sink:MaD:4 | +| test_storage.rs:125:25:125:37 | insert_query2 | test_storage.rs:125:25:125:46 | insert_query2.as_str() [&ref] | provenance | MaD:9 | | test_storage.rs:125:25:125:37 | insert_query2 | test_storage.rs:125:25:125:46 | insert_query2.as_str() [&ref] | provenance | MaD:8 | -| test_storage.rs:125:25:125:37 | insert_query2 | test_storage.rs:125:25:125:46 | insert_query2.as_str() [&ref] | provenance | MaD:7 | -| test_storage.rs:125:25:125:37 | insert_query2 | test_storage.rs:125:25:125:46 | insert_query2.as_str() [&ref] | provenance | MaD:8 | +| test_storage.rs:125:25:125:37 | insert_query2 | test_storage.rs:125:25:125:46 | insert_query2.as_str() [&ref] | provenance | MaD:9 | | test_storage.rs:125:25:125:46 | insert_query2.as_str() | test_storage.rs:125:13:125:23 | ...::query | provenance | MaD:4 Sink:MaD:4 | | test_storage.rs:125:25:125:46 | insert_query2.as_str() [&ref] | test_storage.rs:125:13:125:23 | ...::query | provenance | MaD:4 Sink:MaD:4 | +| test_storage.rs:139:25:139:37 | insert_query2 | test_storage.rs:139:25:139:46 | insert_query2.as_str() [&ref] | provenance | MaD:9 | | test_storage.rs:139:25:139:37 | insert_query2 | test_storage.rs:139:25:139:46 | insert_query2.as_str() [&ref] | provenance | MaD:8 | -| test_storage.rs:139:25:139:37 | insert_query2 | test_storage.rs:139:25:139:46 | insert_query2.as_str() [&ref] | provenance | MaD:7 | -| test_storage.rs:139:25:139:37 | insert_query2 | test_storage.rs:139:25:139:46 | insert_query2.as_str() [&ref] | provenance | MaD:8 | +| test_storage.rs:139:25:139:37 | insert_query2 | test_storage.rs:139:25:139:46 | insert_query2.as_str() [&ref] | provenance | MaD:9 | | test_storage.rs:139:25:139:46 | insert_query2.as_str() | test_storage.rs:139:13:139:23 | ...::query | provenance | MaD:4 Sink:MaD:4 | | test_storage.rs:139:25:139:46 | insert_query2.as_str() [&ref] | test_storage.rs:139:13:139:23 | ...::query | provenance | MaD:4 Sink:MaD:4 | | test_storage.rs:189:9:189:24 | insert_query_bad | test_storage.rs:194:25:194:40 | insert_query_bad | provenance | | | test_storage.rs:189:28:189:117 | ... + ... | test_storage.rs:189:9:189:24 | insert_query_bad | provenance | | -| test_storage.rs:189:28:189:117 | ... + ... | test_storage.rs:189:28:189:124 | ... + ... | provenance | MaD:6 | +| test_storage.rs:189:28:189:117 | ... + ... | test_storage.rs:189:28:189:124 | ... + ... | provenance | MaD:7 | | test_storage.rs:189:28:189:124 | ... + ... | test_storage.rs:189:9:189:24 | insert_query_bad | provenance | | | test_storage.rs:189:99:189:117 | &... | test_storage.rs:189:9:189:24 | insert_query_bad | provenance | | | test_storage.rs:189:99:189:117 | &... | test_storage.rs:189:28:189:117 | ... + ... | provenance | | +| test_storage.rs:189:99:189:117 | &... | test_storage.rs:189:28:189:117 | ... + ... | provenance | MaD:6 | +| test_storage.rs:189:99:189:117 | &... [&ref] | test_storage.rs:189:28:189:117 | ... + ... | provenance | MaD:6 | | test_storage.rs:189:100:189:117 | get_phone_number(...) | test_storage.rs:189:99:189:117 | &... | provenance | Config | +| test_storage.rs:189:100:189:117 | get_phone_number(...) | test_storage.rs:189:99:189:117 | &... [&ref] | provenance | | | test_storage.rs:190:9:190:24 | select_query_bad | test_storage.rs:196:35:196:50 | select_query_bad | provenance | | | test_storage.rs:190:28:190:103 | ... + ... | test_storage.rs:190:9:190:24 | select_query_bad | provenance | | -| test_storage.rs:190:28:190:103 | ... + ... | test_storage.rs:190:28:190:109 | ... + ... | provenance | MaD:6 | +| test_storage.rs:190:28:190:103 | ... + ... | test_storage.rs:190:28:190:109 | ... + ... | provenance | MaD:7 | | test_storage.rs:190:28:190:109 | ... + ... | test_storage.rs:190:9:190:24 | select_query_bad | provenance | | | test_storage.rs:190:85:190:103 | &... | test_storage.rs:190:9:190:24 | select_query_bad | provenance | | | test_storage.rs:190:85:190:103 | &... | test_storage.rs:190:28:190:103 | ... + ... | provenance | | +| test_storage.rs:190:85:190:103 | &... | test_storage.rs:190:28:190:103 | ... + ... | provenance | MaD:6 | +| test_storage.rs:190:85:190:103 | &... [&ref] | test_storage.rs:190:28:190:103 | ... + ... | provenance | MaD:6 | | test_storage.rs:190:86:190:103 | get_phone_number(...) | test_storage.rs:190:85:190:103 | &... | provenance | Config | +| test_storage.rs:190:86:190:103 | get_phone_number(...) | test_storage.rs:190:85:190:103 | &... [&ref] | provenance | | | test_storage.rs:194:24:194:40 | &insert_query_bad | test_storage.rs:194:16:194:22 | execute | provenance | MaD:1 Sink:MaD:1 | | test_storage.rs:194:24:194:40 | &insert_query_bad [&ref] | test_storage.rs:194:16:194:22 | execute | provenance | MaD:1 Sink:MaD:1 | | test_storage.rs:194:25:194:40 | insert_query_bad | test_storage.rs:194:24:194:40 | &insert_query_bad | provenance | Config | @@ -92,14 +101,16 @@ models | 3 | Sink: ::query_row; Argument[0]; sql-injection | | 4 | Sink: sqlx_core::query::query; Argument[0]; sql-injection | | 5 | Sink: sqlx_core::raw_sql::raw_sql; Argument[0]; sql-injection | -| 6 | Summary: ::add; Argument[self]; ReturnValue; value | -| 7 | Summary: ::as_str; Argument[self]; ReturnValue; value | -| 8 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 6 | Summary: ::add; Argument[0].Reference; ReturnValue; taint | +| 7 | Summary: ::add; Argument[self]; ReturnValue; value | +| 8 | Summary: ::as_str; Argument[self]; ReturnValue; value | +| 9 | Summary: ::as_str; Argument[self]; ReturnValue; value | nodes | test_storage.rs:71:9:71:21 | insert_query2 | semmle.label | insert_query2 | | test_storage.rs:71:25:71:114 | ... + ... | semmle.label | ... + ... | | test_storage.rs:71:25:71:121 | ... + ... | semmle.label | ... + ... | | test_storage.rs:71:96:71:114 | &... | semmle.label | &... | +| test_storage.rs:71:96:71:114 | &... [&ref] | semmle.label | &... [&ref] | | test_storage.rs:71:97:71:114 | get_phone_number(...) | semmle.label | get_phone_number(...) | | test_storage.rs:100:13:100:23 | ...::query | semmle.label | ...::query | | test_storage.rs:100:25:100:37 | insert_query2 | semmle.label | insert_query2 | @@ -125,11 +136,13 @@ nodes | test_storage.rs:189:28:189:117 | ... + ... | semmle.label | ... + ... | | test_storage.rs:189:28:189:124 | ... + ... | semmle.label | ... + ... | | test_storage.rs:189:99:189:117 | &... | semmle.label | &... | +| test_storage.rs:189:99:189:117 | &... [&ref] | semmle.label | &... [&ref] | | test_storage.rs:189:100:189:117 | get_phone_number(...) | semmle.label | get_phone_number(...) | | test_storage.rs:190:9:190:24 | select_query_bad | semmle.label | select_query_bad | | test_storage.rs:190:28:190:103 | ... + ... | semmle.label | ... + ... | | test_storage.rs:190:28:190:109 | ... + ... | semmle.label | ... + ... | | test_storage.rs:190:85:190:103 | &... | semmle.label | &... | +| test_storage.rs:190:85:190:103 | &... [&ref] | semmle.label | &... [&ref] | | test_storage.rs:190:86:190:103 | get_phone_number(...) | semmle.label | get_phone_number(...) | | test_storage.rs:194:16:194:22 | execute | semmle.label | execute | | test_storage.rs:194:24:194:40 | &insert_query_bad | semmle.label | &insert_query_bad | diff --git a/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected b/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected index 0010127c5bb..e1e2ba70026 100644 --- a/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected +++ b/rust/ql/test/query-tests/security/CWE-825/AccessAfterLifetime.expected @@ -164,7 +164,7 @@ edges | lifetime.rs:443:6:443:7 | p1 | lifetime.rs:446:13:446:14 | p1 | provenance | | | lifetime.rs:443:6:443:7 | p1 | lifetime.rs:450:2:450:10 | return p1 | provenance | | | lifetime.rs:443:23:443:44 | ...::from_ref(...) | lifetime.rs:443:6:443:7 | p1 | provenance | | -| lifetime.rs:443:42:443:43 | r1 | lifetime.rs:443:23:443:44 | ...::from_ref(...) | provenance | MaD:3 | +| lifetime.rs:443:42:443:43 | r1 | lifetime.rs:443:23:443:44 | ...::from_ref(...) | provenance | MaD:4 | | lifetime.rs:450:2:450:10 | return p1 | lifetime.rs:454:11:454:29 | get_ptr_from_ref(...) | provenance | | | lifetime.rs:450:2:450:10 | return p1 | lifetime.rs:460:13:460:31 | get_ptr_from_ref(...) | provenance | | | lifetime.rs:454:6:454:7 | p1 | lifetime.rs:459:13:459:14 | p1 | provenance | | @@ -175,7 +175,9 @@ edges | lifetime.rs:630:3:630:6 | str2 | lifetime.rs:641:14:641:17 | str2 | provenance | | | lifetime.rs:630:10:630:25 | &... | lifetime.rs:630:3:630:6 | str2 | provenance | | | lifetime.rs:654:4:654:7 | str2 | lifetime.rs:655:22:655:25 | str2 | provenance | | +| lifetime.rs:654:11:654:35 | ... + ... | lifetime.rs:654:4:654:7 | str2 | provenance | | | lifetime.rs:654:31:654:35 | &str1 | lifetime.rs:654:4:654:7 | str2 | provenance | | +| lifetime.rs:654:31:654:35 | &str1 | lifetime.rs:654:11:654:35 | ... + ... | provenance | MaD:3 | | lifetime.rs:655:4:655:7 | ref1 | lifetime.rs:659:15:659:18 | ref1 | provenance | | | lifetime.rs:655:4:655:7 | ref1 | lifetime.rs:667:14:667:17 | ref1 | provenance | | | lifetime.rs:655:4:655:7 | ref1 [&ref] | lifetime.rs:659:15:659:18 | ref1 | provenance | | @@ -227,7 +229,8 @@ edges models | 1 | Summary: ::as_mut_ptr; Argument[0].Reference.Reference; ReturnValue.Reference; value | | 2 | Summary: ::as_ptr; Argument[0].Reference.Reference; ReturnValue.Reference; value | -| 3 | Summary: core::ptr::from_ref; Argument[0]; ReturnValue; value | +| 3 | Summary: ::add; Argument[0].Reference; ReturnValue; taint | +| 4 | Summary: core::ptr::from_ref; Argument[0]; ReturnValue; value | nodes | deallocation.rs:148:6:148:7 | p1 | semmle.label | p1 | | deallocation.rs:148:30:148:38 | &raw const my_buffer | semmle.label | &raw const my_buffer | @@ -407,6 +410,7 @@ nodes | lifetime.rs:633:15:633:18 | str2 | semmle.label | str2 | | lifetime.rs:641:14:641:17 | str2 | semmle.label | str2 | | lifetime.rs:654:4:654:7 | str2 | semmle.label | str2 | +| lifetime.rs:654:11:654:35 | ... + ... | semmle.label | ... + ... | | lifetime.rs:654:31:654:35 | &str1 | semmle.label | &str1 | | lifetime.rs:655:4:655:7 | ref1 | semmle.label | ref1 | | lifetime.rs:655:4:655:7 | ref1 [&ref] | semmle.label | ref1 [&ref] |