Skip to content

Commit

Permalink
.(: Don't unescape macro args (#4450)
Browse files Browse the repository at this point in the history
  • Loading branch information
kazarmy authored Apr 21, 2024
1 parent 61c634a commit 688c2bb
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 9 deletions.
29 changes: 21 additions & 8 deletions librz/core/cmd/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -3293,16 +3293,22 @@ static bool handle_substitution_args(struct tsr2cmd_state *state, TSNode args, R
return true;
}

static char *do_handle_ts_unescape_arg(struct tsr2cmd_state *state, TSNode arg, bool do_unwrap) {
static char *do_handle_ts_unescape_arg(struct tsr2cmd_state *state, TSNode arg, bool raw, bool do_unwrap) {
if (is_ts_arg(arg)) {
return do_handle_ts_unescape_arg(state, ts_node_named_child(arg, 0), do_unwrap);
return do_handle_ts_unescape_arg(state, ts_node_named_child(arg, 0), raw, do_unwrap);
} else if (is_ts_arg_identifier(arg)) {
char *arg_str = ts_node_sub_string(arg, state->input);
if (raw) {
return arg_str;
}
char *unescaped_arg = rz_cmd_unescape_arg(arg_str, RZ_CMD_ESCAPE_ONE_ARG);
free(arg_str);
return unescaped_arg;
} else if (is_ts_single_quoted_arg(arg) || is_ts_double_quoted_arg(arg)) {
char *o_arg_str = ts_node_sub_string(arg, state->input);
if (raw) {
return o_arg_str;
}
char *arg_str = o_arg_str;
if (do_unwrap) {
// remove quotes
Expand All @@ -3322,7 +3328,7 @@ static char *do_handle_ts_unescape_arg(struct tsr2cmd_state *state, TSNode arg,
RzStrBuf *sb = rz_strbuf_new(NULL);
for (i = 0; i < n_children; i++) {
TSNode sub_arg = ts_node_named_child(arg, i);
char *s = do_handle_ts_unescape_arg(state, sub_arg, do_unwrap);
char *s = do_handle_ts_unescape_arg(state, sub_arg, raw, do_unwrap);
rz_strbuf_append(sb, s);
free(s);
}
Expand All @@ -3333,6 +3339,9 @@ static char *do_handle_ts_unescape_arg(struct tsr2cmd_state *state, TSNode arg,
}

static bool is_arg_raw(const RzCmdDesc *cd, size_t i) {
if (!cd) {
return false;
}
const RzCmdDescArg *arg = rz_cmd_desc_get_arg(cd, i);
return arg && arg->type == RZ_CMD_ARG_TYPE_RAW;
}
Expand All @@ -3346,11 +3355,12 @@ static RzCmdParsedArgs *parse_args(struct tsr2cmd_state *state, TSNode args, boo
char **unescaped_args = RZ_NEWS0(char *, n_children);
for (i = 0; i < n_children; i++) {
TSNode arg = ts_node_named_child(args, i);
bool arg_raw = is_arg_raw(cd, i);
bool do_unwrap_arg = do_unwrap;
if (!do_unwrap && cd && cd->type != RZ_CMD_DESC_TYPE_OLDINPUT && !is_arg_raw(cd, i)) {
if (!do_unwrap && cd && cd->type != RZ_CMD_DESC_TYPE_OLDINPUT && !arg_raw) {
do_unwrap_arg = true;
}
unescaped_args[i] = do_handle_ts_unescape_arg(state, arg, do_unwrap_arg);
unescaped_args[i] = do_handle_ts_unescape_arg(state, arg, arg_raw, do_unwrap_arg);
}
RzCmdParsedArgs *res = rz_cmd_parsed_args_newargs(n_children, unescaped_args);
for (i = 0; i < n_children; i++) {
Expand All @@ -3359,10 +3369,11 @@ static RzCmdParsedArgs *parse_args(struct tsr2cmd_state *state, TSNode args, boo
free(unescaped_args);
return res;
} else {
if (!do_unwrap && cd && cd->type != RZ_CMD_DESC_TYPE_OLDINPUT && !is_arg_raw(cd, 0)) {
bool arg_raw = is_arg_raw(cd, 0);
if (!do_unwrap && cd && cd->type != RZ_CMD_DESC_TYPE_OLDINPUT && !arg_raw) {
do_unwrap = true;
}
char *unescaped_args[] = { do_handle_ts_unescape_arg(state, args, do_unwrap) };
char *unescaped_args[] = { do_handle_ts_unescape_arg(state, args, arg_raw, do_unwrap) };
RzCmdParsedArgs *res = rz_cmd_parsed_args_newargs(1, unescaped_args);
free(unescaped_args[0]);
return res;
Expand Down Expand Up @@ -3437,7 +3448,9 @@ static bool substitute_args(struct tsr2cmd_state *state, TSNode args, TSNode *ne
return res;
}

// If do_unwrap is true, then quote unwrapping is always done, else cd is checked
// If do_unwrap is true, then quote unwrapping is always done, else cd is
// checked. An arg of raw type (this can be determined if cd is available)
// prevents unescaping and quote unwrapping regardless.
static RzCmdParsedArgs *ts_node_handle_arg_prargs(struct tsr2cmd_state *state, TSNode command, TSNode arg, uint32_t child_idx, bool do_unwrap, const RzCmdDesc *cd) {
RzCmdParsedArgs *res = NULL;
TSNode new_command;
Expand Down
2 changes: 1 addition & 1 deletion librz/include/rz_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ typedef enum rz_cmd_arg_type_t {
RZ_CMD_ARG_TYPE_NUM, ///< Argument is a number
RZ_CMD_ARG_TYPE_RZNUM, ///< Argument that can be interpreted by RzNum (numbers, flags, operations, etc.)
RZ_CMD_ARG_TYPE_STRING, ///< Argument that can be an arbitrary string
RZ_CMD_ARG_TYPE_RAW, ///< Like RZ_CMD_ARG_TYPE_STRING, but quote unwrapping and unescaping is not done. TODO: currently only quote unwrapping is prevented.
RZ_CMD_ARG_TYPE_RAW, ///< Like RZ_CMD_ARG_TYPE_STRING, but unescaping and quote unwrapping is not done
RZ_CMD_ARG_TYPE_ENV, ///< Argument can be the name of an existing rizin variable
RZ_CMD_ARG_TYPE_CHOICES, ///< Argument can be one of the provided choices
RZ_CMD_ARG_TYPE_FCN, ///< Argument can be the name of an existing function
Expand Down
6 changes: 6 additions & 0 deletions test/db/cmd/write
Original file line number Diff line number Diff line change
Expand Up @@ -460,13 +460,19 @@ $new_addr=%v \`$addr\`+16
.(wz16 \\a)
.(wz16 "a \\ b")
.(wz16 a\\)
.(wz16 "c `%vi 123+1` d")
.(wz16 \`)
.(wz16 "e \` f")
EOF
EXPECT=<<EOF
0x00000000 5c00 0000 0000 0000 0000 0000 0000 0000 \...............
0x00000010 5c5c 0000 0000 0000 0000 0000 0000 0000 \\..............
0x00000020 5c61 0000 0000 0000 0000 0000 0000 0000 \a..............
0x00000030 6120 5c20 6200 0000 0000 0000 0000 0000 a \ b...........
0x00000040 615c 0000 0000 0000 0000 0000 0000 0000 a\..............
0x00000050 6320 3132 3420 6400 0000 0000 0000 0000 c 124 d.........
0x00000060 6000 0000 0000 0000 0000 0000 0000 0000 `...............
0x00000070 6520 6020 6600 0000 0000 0000 0000 0000 e ` f...........
EOF
RUN

Expand Down

0 comments on commit 688c2bb

Please sign in to comment.