8000 Add support for multiple input lines by yotamN · Pull Request #118 · frida/frida-tools · GitHub
[go: up one dir, main page]

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions frida_tools/repl.py
8000
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@
from urllib.request import build_opener

import frida
import tree_sitter_javascript
from colorama import Fore, Style
from prompt_toolkit import PromptSession
from prompt_toolkit.completion import CompleteEvent, Completer, Completion
from prompt_toolkit.document import Document
from prompt_toolkit.filters import Condition, Filter
from prompt_toolkit.history import FileHistory
from prompt_toolkit.lexers import PygmentsLexer
from prompt_toolkit.shortcuts import prompt
from prompt_toolkit.styles import Style as PromptToolkitStyle
from pygments.lexers.javascript import JavascriptLexer
from pygments.token import Token
from tree_sitter import Language, Parser, Query, QueryCursor

from frida_tools import _repl_magic
from frida_tools.application import ConsoleApplication
Expand All @@ -35,6 +38,15 @@

T = TypeVar("T")

try:
JS_LANGUAGE = Language(tree_sitter_javascript.language())
ERROR_QUERY = Query(JS_LANGUAGE, "(_ (ERROR) @error)")
MISSING_QUERY = Query(JS_LANGUAGE, "(_ (MISSING) @missing)")
except Exception:
JS_LANGUAGE = None
ERROR_QUERY = None
MISSING_QUERY = None


class REPLApplication(ConsoleApplication):
def __init__(self) -> None:
Expand All @@ -54,6 +66,11 @@ def __init__(self) -> None:

super().__init__(self._process_input, self._on_stop)

try:
self._parser = Parser(JS_LANGUAGE)
except Exception:
self._parser = None

if self._have_terminal and not self._plain_terminal:
style = PromptToolkitStyle(
[
Expand All @@ -70,6 +87,7 @@ def __init__(self) -> None:
complete_in_thread=True,
enable_open_in_editor=True,
tempfile_suffix=".js",
multiline=self._input_complete(),
)
self._dumb_stdin_reader = None
else:
Expand Down Expand Up @@ -356,6 +374,24 @@ def _monitor(self, path: AnyStr) -> None:
monitor.enable()
self._monitored_files[path] = monitor

def _input_complete(self) -> Filter:
"""
check if the current input is a valid javascript code
"""

@Condition
def inner() -> bool:
assert self._cli is not None
if self._parser is None or ERROR_QUERY is None or MISSING_QUERY is None:
return False

tree = self._parser.parse(self._cli.default_buffer.document.text.encode())
error_query_results = QueryCursor(ERROR_QUERY).captures(tree.root_node)
missing_query_results = QueryCursor(MISSING_QUERY).captures(tree.root_node)
return len(error_query_results) or len(missing_query_results)

return inner

def _process_input(self, reactor: Reactor) -> None:
if not self._quiet:
self._print_startup_message()
Expand Down
8 changes: 6 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,25 @@ classifiers = [
"Operating System :: Microsoft :: Windows",
"Operating System :: POSIX :: Linux",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: JavaScript",
"Topic :: Software Development :: Debuggers",
"Topic :: Software Development :: Libraries :: Python Modules",
]

requires-python = ">=3.7"
requires-python = ">=3.10"
dependencies = [
"colorama >= 0.2.7, < 1.0.0",
"frida >= 17.2.8, < 18.0.0",
"prompt-toolkit >= 2.0.0, < 4.0.0",
"pygments >= 2.0.2, < 3.0.0",
"tree-sitter==0.25.1",
"tree-sitter-javascript==0.23.1",
"websockets >= 13.0.0, < 14.0.0",
]

Expand Down
0