Add rzshell_which script to look for the handler of a rzshell cmd (#1839)

* remove isort linter on CI
This commit is contained in:
Riccardo Schirone 2021-10-19 15:43:11 +02:00 committed by GitHub
parent a3ccc64912
commit 86f6fec835
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 201 additions and 89 deletions

View file

@ -112,11 +112,6 @@ jobs:
export PATH=${HOME}/Library/Python/3.8/bin:${HOME}/Library/Python/3.9/bin:${HOME}/.local/bin:${PATH}
find . -name "*.py" | grep -v "subprojects" | xargs black --check
- name: Run isort
run: |
export PATH=${HOME}/Library/Python/3.8/bin:${HOME}/Library/Python/3.9/bin:${HOME}/.local/bin:${PATH}
find . -name "*.py" | grep -v "subprojects" | xargs isort --check
- name: Run pylint
run: |
export PATH=${HOME}/Library/Python/3.8/bin:${HOME}/Library/Python/3.9/bin:${HOME}/.local/bin:${PATH}

View file

@ -138,13 +138,16 @@ files: `cmd_descs.c` and `cmd_descs.h`.
## Where is the handler of command `x`?
If you are looking for the handler of command `x`, you just have to look at
the file
You can use the script `librz/core/cmd_descs/rzshell_find_handler.py` to get the
name of the function handling the specified command.
If that doesn't work, please report the problem to us! However, you can still
find the handler yourself by looking at the file
[`librz/core/cmd_descs.yaml`](https://github.com/rizinorg/rizin/blob/9ce5003ca647cdfc181ac3c0f6206762ebb9e3e9/librz/core/cmd_descs.yaml).
By looking at the `cname` field of the command descriptor, you can see what
is the name of the handler of the `x` command. If the `cname` is `hex` and
the type is `RZ_CMD_DESC_TYPE_OLDINPUT`, then the handler will be named
`rz_hex`. In all other cases, the handler will be named `rz_hex_handler`.
By looking at the `cname` field of the command descriptor, you can see what is
the name of the handler of the `x` command. If the `cname` is `hex` and the type
is `RZ_CMD_DESC_TYPE_OLDINPUT`, then the handler will be named `rz_hex`. In all
other cases, the handler will be named `rz_hex_handler`.
Some examples:
- command: `wv`, type: unspecified (default to `RZ_CMD_DESC_TYPE_ARGV`), handler: `rz_write_value_handler`

View file

@ -7,6 +7,19 @@ import os
import sys
import yaml
from cmd_descs_util import (
CD_ARG_LAST_TYPES,
CD_TYPE_ARGV,
CD_TYPE_ARGV_MODES,
CD_TYPE_ARGV_STATE,
CD_TYPE_FAKE,
CD_TYPE_GROUP,
CD_TYPE_INNER,
CD_TYPE_OLDINPUT,
CD_VALID_TYPES,
compute_cname,
get_handler_cname,
)
CMDDESCS_C_TEMPLATE = """// SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
// SPDX-License-Identifier: LGPL-3.0-only
@ -120,88 +133,19 @@ DEFINE_FAKE_TEMPLATE = """
SET_DEFAULT_MODE_TEMPLATE = """
\trz_cmd_desc_set_default_mode({cname}_cd, {default_mode});"""
CD_TYPE_OLDINPUT = "RZ_CMD_DESC_TYPE_OLDINPUT"
CD_TYPE_GROUP = "RZ_CMD_DESC_TYPE_GROUP"
CD_TYPE_ARGV = "RZ_CMD_DESC_TYPE_ARGV"
CD_TYPE_ARGV_MODES = "RZ_CMD_DESC_TYPE_ARGV_MODES"
CD_TYPE_ARGV_STATE = "RZ_CMD_DESC_TYPE_ARGV_STATE"
CD_TYPE_FAKE = "RZ_CMD_DESC_TYPE_FAKE"
CD_TYPE_INNER = "RZ_CMD_DESC_TYPE_INNER"
CD_VALID_TYPES = [
CD_TYPE_OLDINPUT,
CD_TYPE_GROUP,
CD_TYPE_ARGV,
CD_TYPE_ARGV_MODES,
CD_TYPE_ARGV_STATE,
CD_TYPE_FAKE,
CD_TYPE_INNER,
]
CD_ARG_LAST_TYPES = [
"RZ_CMD_ARG_TYPE_RZNUM",
"RZ_CMD_ARG_TYPE_STRING",
"RZ_CMD_ARG_TYPE_CMD",
]
def escape(s):
def _escape(s):
return s.replace("\\", "\\\\").replace('"', '\\"')
def strornull(s):
return '"' + escape(s) + '"' if s is not None else "NULL"
return '"' + _escape(s) + '"' if s is not None else "NULL"
def strip(s):
return s.strip("\n") if s is not None else None
def compute_cname(name):
if name == "":
return "empty"
name = name.translate(
str.maketrans(
{
".": "_dot_",
"*": "_star_",
">": "_greater_",
"<": "_minor_",
"-": "_minus_",
"+": "_plus_",
"=": "_equal_",
"$": "_dollar_",
"?": "_question_",
"/": "_slash_",
"\\": "_backslash_",
"&": "_and_",
"!": "_escl_",
"#": "_hash_",
" ": "_space_",
"(": "_oparen_",
")": "_cparen_",
}
)
)
if name.startswith("_"):
name = name[1:]
return name
def flat(l):
if l is None:
return []
if not isinstance(l, list):
return [l]
out = []
for i in l:
out += flat(i)
return out
class Arg:
def __init__(self, cd, c):
if "name" not in c or "type" not in c:
@ -512,13 +456,14 @@ class CmdDesc:
sys.exit(1)
def get_handler_cname(self):
if self.type in [CD_TYPE_ARGV, CD_TYPE_ARGV_MODES, CD_TYPE_ARGV_STATE]:
return "rz_" + (self.handler or self.cname) + "_handler"
if self.type == CD_TYPE_OLDINPUT:
return "rz_" + (self.handler or self.cname)
return None
if self.type not in [
CD_TYPE_OLDINPUT,
CD_TYPE_ARGV,
CD_TYPE_ARGV_MODES,
CD_TYPE_ARGV_STATE,
]:
return None
return get_handler_cname(self.type, self.handler, self.cname)
@classmethod
def get_arg_cname(cls, cd):

View file

@ -0,0 +1,67 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: 2020-2021 ret2libc <sirmy15@gmail.com>
# SPDX-License-Identifier: LGPL-3.0-only
CD_TYPE_OLDINPUT = "RZ_CMD_DESC_TYPE_OLDINPUT"
CD_TYPE_GROUP = "RZ_CMD_DESC_TYPE_GROUP"
CD_TYPE_ARGV = "RZ_CMD_DESC_TYPE_ARGV"
CD_TYPE_ARGV_MODES = "RZ_CMD_DESC_TYPE_ARGV_MODES"
CD_TYPE_ARGV_STATE = "RZ_CMD_DESC_TYPE_ARGV_STATE"
CD_TYPE_FAKE = "RZ_CMD_DESC_TYPE_FAKE"
CD_TYPE_INNER = "RZ_CMD_DESC_TYPE_INNER"
CD_VALID_TYPES = [
CD_TYPE_OLDINPUT,
CD_TYPE_GROUP,
CD_TYPE_ARGV,
CD_TYPE_ARGV_MODES,
CD_TYPE_ARGV_STATE,
CD_TYPE_FAKE,
CD_TYPE_INNER,
]
CD_ARG_LAST_TYPES = [
"RZ_CMD_ARG_TYPE_RZNUM",
"RZ_CMD_ARG_TYPE_STRING",
"RZ_CMD_ARG_TYPE_CMD",
]
def compute_cname(name):
if name == "":
return "empty"
name = name.translate(
str.maketrans(
{
".": "_dot_",
"*": "_star_",
">": "_greater_",
"<": "_minor_",
"-": "_minus_",
"+": "_plus_",
"=": "_equal_",
"$": "_dollar_",
"?": "_question_",
"/": "_slash_",
"\\": "_backslash_",
"&": "_and_",
"!": "_escl_",
"#": "_hash_",
" ": "_space_",
"(": "_oparen_",
")": "_cparen_",
}
)
)
if name.startswith("_"):
name = name[1:]
return name
def get_handler_cname(ty, handler, cname):
if ty == CD_TYPE_OLDINPUT:
return "rz_" + (handler or cname)
return "rz_" + (handler or cname) + "_handler"

View file

@ -0,0 +1,88 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: 2021 ret2libc <sirmy15@gmail.com>
# SPDX-License-Identifier: LGPL-3.0-only
import argparse
import glob
import os
import sys
import yaml
from cmd_descs_util import CD_TYPE_OLDINPUT, compute_cname, get_handler_cname
def get_yaml_files(basedir):
for file in glob.glob(os.path.join(basedir, "*.yaml")):
yield file
def find_entry(commands, rzcommand):
for c in commands:
if "subcommands" in c and isinstance(c["subcommands"], list):
e = find_entry(c["subcommands"], rzcommand)
if e is not None:
return e
if c["name"] == rzcommand:
return c
return None
def get_c_handler_name_from_entry(e):
name = e["cname"]
if "handler" in e and e["handler"]:
name = e["handler"]
if "type" in e and e["type"] == CD_TYPE_OLDINPUT:
return f"rz_{name}"
return f"rz_{name}_handler"
def find_c_name_handler(basedir, rzcommand):
for f in get_yaml_files(basedir):
with open(f, "r", encoding="utf8") as of:
y = yaml.safe_load(of)
e = find_entry(y["commands"], rzcommand)
if e is not None:
cname = e.get("cname", compute_cname(e["name"]))
return get_handler_cname(
e.get("type", None), e.get("handler", None), cname
)
return None
def main():
parser = argparse.ArgumentParser(
description="Find the C handler of a rizin command"
)
parser.add_argument(
"--cmddescs-dir",
default=os.path.join("librz", "core", "cmd_descs"),
type=str,
help="Path to the cmd_descs directory containing the *.yaml files",
)
parser.add_argument("rzcommand", type=str, help="Name of the rizin command")
args = parser.parse_args()
c_name = find_c_name_handler(args.cmddescs_dir, args.rzcommand)
if c_name is None:
print(
f"Command {args.rzcommand} does not exist or it is not converted to rzshell yet."
)
sys.exit(1)
CRED = "\033[91m"
CEND = "\033[0m"
print(f"Rizin Command: {CRED}{args.rzcommand}{CEND}")
print(f"C handler: {CRED}{c_name}{CEND}")
print(
f'Git command to get it: {CRED}git grep -nWG "^[^[:blank:]].*{c_name}(" *.c{CEND}'
)
if __name__ == "__main__":
main()

14
sys/rzshell_which.py Executable file
View file

@ -0,0 +1,14 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: 2021 ret2libc <sirmy15@gmail.com>
# SPDX-License-Identifier: LGPL-3.0-only
import os
import subprocess
import sys
current_path = os.path.dirname(os.path.realpath(__file__))
shell_finder_py = os.path.join(
current_path, "..", "librz", "core", "cmd_descs", "rzshell_which.py"
)
subprocess.run([shell_finder_py] + sys.argv[1:], check=False)