(stmt: SimpleStmt, result: dict[SimpleStmt, EscapingCall])
| 752 | raise analysis_error(f"Escaping call '{error.text} in condition", error) |
| 753 | |
| 754 | def escaping_call_in_simple_stmt(stmt: SimpleStmt, result: dict[SimpleStmt, EscapingCall]) -> None: |
| 755 | tokens = stmt.contents |
| 756 | for idx, tkn in enumerate(tokens): |
| 757 | try: |
| 758 | next_tkn = tokens[idx+1] |
| 759 | except IndexError: |
| 760 | break |
| 761 | if next_tkn.kind != lexer.LPAREN: |
| 762 | continue |
| 763 | if tkn.kind == lexer.IDENTIFIER: |
| 764 | if tkn.text.upper() == tkn.text: |
| 765 | # simple macro |
| 766 | continue |
| 767 | #if not tkn.text.startswith(("Py", "_Py", "monitor")): |
| 768 | # continue |
| 769 | if tkn.text.startswith(("sym_", "optimize_", "PyJitRef")): |
| 770 | # Optimize functions |
| 771 | continue |
| 772 | if tkn.text.endswith("Check"): |
| 773 | continue |
| 774 | if tkn.text.startswith("Py_Is"): |
| 775 | continue |
| 776 | if tkn.text.endswith("CheckExact"): |
| 777 | continue |
| 778 | if tkn.text in NON_ESCAPING_FUNCTIONS: |
| 779 | continue |
| 780 | elif tkn.kind == "RPAREN": |
| 781 | prev = tokens[idx-1] |
| 782 | if prev.text.endswith("_t") or prev.text == "*" or prev.text == "int": |
| 783 | #cast |
| 784 | continue |
| 785 | elif tkn.kind != "RBRACKET": |
| 786 | continue |
| 787 | if tkn.text in ("PyStackRef_CLOSE", "PyStackRef_XCLOSE"): |
| 788 | if len(tokens) <= idx+2: |
| 789 | raise analysis_error("Unexpected end of file", next_tkn) |
| 790 | kills = tokens[idx+2] |
| 791 | if kills.kind != "IDENTIFIER": |
| 792 | raise analysis_error(f"Expected identifier, got '{kills.text}'", kills) |
| 793 | else: |
| 794 | kills = None |
| 795 | result[stmt] = EscapingCall(stmt, tkn, kills) |
| 796 | |
| 797 | |
| 798 | def find_escaping_api_calls(instr: parser.CodeDef) -> dict[SimpleStmt, EscapingCall]: |
no test coverage detected
searching dependent graphs…