Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Convert pj to RzShell #4726

Merged
merged 8 commits into from
Nov 24, 2024
Merged
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
60 changes: 16 additions & 44 deletions librz/core/cmd/cmd_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <rz_types.h>

#include "../core_private.h"
#include "rz_util/rz_strbuf.h"
#include <rz_util/rz_strbuf.h>

#define PF_USAGE_STR "pf[.k[.f[=v]]|[v]]|[n]|[0|cnt][fmt] [a0 a1 ...]"

Expand Down Expand Up @@ -131,7 +131,6 @@ static const char *help_msg_p[] = {
"ph", "[?][=|hash] ([len])", "calculate hash for a block",
"pi", "[?][bdefrj] [num]", "print instructions",
"pI", "[?][iI][df] [len]", "print N instructions/bytes (f=func)",
"pj", "[?] [len]", "print as indented JSON",
"pm", "[?] [magic]", "print libmagic data (see pm? and /m?)",
"po", "[?] hex", "print operation applied to block (see po?)",
"pp", "[?][sz] [len]", "print patterns, see pp? for more help",
Expand All @@ -145,14 +144,6 @@ static const char *help_msg_p[] = {
NULL
};

static const char *help_msg_pj[] = {
"Usage:", "pj[..] [size]", "",
"pj", "", "print current block as indented JSON",
"pj.", "", "print as indented JSON from 0 to the current offset",
"pj..", "", "print JSON path from 0 to the current offset",
NULL
};

static const char *help_msg_px[] = {
"Usage:", "px[0afoswqWqQ][f]", " # Print heXadecimal",
"px", "", "show hexdump",
Expand Down Expand Up @@ -2507,40 +2498,6 @@ RZ_IPI int rz_cmd_print(void *data, const char *input) {
rz_core_block_read(core);
}
switch (*input) {
case 'j': // "pj"
if (input[1] == '?') {
rz_core_cmd_help(core, help_msg_pj);
} else if (input[1] == '.') {
if (input[2] == '.') {
ut8 *data = calloc(core->offset + 1, 1);
if (data) {
data[core->offset] = 0;
(void)rz_io_read_at(core->io, 0, data, core->offset);
char *res = rz_print_json_path((const char *)data, core->offset);
if (res) {
rz_cons_printf("-> res(%s)\n", res);
}
/*
char *res = rz_print_json_indent ((char*)data, false, " ", NULL);
print_json_path (core, res);
free (res);
*/
} else {
RZ_LOG_ERROR("core: Cannot allocate %d\n", (int)(core->offset));
}
} else {
rz_core_cmdf(core, "pj %" PFMT64u " @ 0", core->offset);
}
} else {
if (core->blocksize < 4 || !memcmp(core->block, "\xff\xff\xff\xff", 4)) {
RZ_LOG_ERROR("core: Cannot read\n");
} else {
char *res = rz_print_json_indent((const char *)core->block, true, " ", NULL);
rz_cons_printf("%s\n", res);
free(res);
}
}
break;
case 'x': // "px"
{
bool show_offset = rz_config_get_i(core->config, "hex.offset");
Expand Down Expand Up @@ -3517,6 +3474,21 @@ RZ_IPI RzCmdStatus rz_cmd_disassembly_function_handler(RzCore *core, int argc, c
return RZ_CMD_STATUS_OK;
}

RZ_IPI RzCmdStatus rz_print_current_block_json_handler(RzCore *core, int argc, const char **argv) {
rz_return_val_if_fail(core, RZ_CMD_STATUS_ERROR);
bool enable_color = rz_config_get_i(core->config, "escr.color") != 0;
char *res = rz_print_json_indent((const char *)core->block, enable_color, " ", NULL);
if (RZ_STR_ISEMPTY(res)) {
free(res);
RZ_LOG_ERROR("Couldn't find a JSON string.\n");
return RZ_CMD_STATUS_ERROR;
} else {
rz_cons_printf("%s\n", res);
}
free(res);
return RZ_CMD_STATUS_OK;
}

RZ_IPI RzCmdStatus rz_print_function_rzil_handler(RzCore *core, int argc, const char **argv) {
RzAnalysisFunction *f = rz_analysis_first_function_in(core->analysis, core->offset);
if (!f) {
Expand Down
11 changes: 11 additions & 0 deletions librz/core/cmd_descs/cmd_descs.c
Original file line number Diff line number Diff line change
Expand Up @@ -13994,6 +13994,14 @@ static const RzCmdDescHelp print_instructions_function_help = {
.args = print_instructions_function_args,
};

static const RzCmdDescArg print_current_block_json_args[] = {
{ 0 },
};
static const RzCmdDescHelp print_current_block_json_help = {
.summary = "Parse, format and print JSON at current offset.",
.args = print_current_block_json_args,
};

static const RzCmdDescArg print_function_rzil_args[] = {
{ 0 },
};
Expand Down Expand Up @@ -21975,6 +21983,9 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
RzCmdDesc *print_instructions_function_cd = rz_cmd_desc_argv_new(core->rcmd, pI_cd, "pIf", rz_print_instructions_function_handler, &print_instructions_function_help);
rz_warn_if_fail(print_instructions_function_cd);

RzCmdDesc *print_current_block_json_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_print_cd, "pj", rz_print_current_block_json_handler, &print_current_block_json_help);
rz_warn_if_fail(print_current_block_json_cd);

RzCmdDesc *print_function_rzil_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_print_cd, "plf", rz_print_function_rzil_handler, &print_function_rzil_help);
rz_warn_if_fail(print_function_rzil_cd);

Expand Down
2 changes: 2 additions & 0 deletions librz/core/cmd_descs/cmd_descs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1920,6 +1920,8 @@ RZ_IPI RzCmdStatus rz_assembly_of_hex_alias_handler(RzCore *core, int argc, cons
RZ_IPI RzCmdStatus rz_print_instructions_handler(RzCore *core, int argc, const char **argv);
// "pIf"
RZ_IPI RzCmdStatus rz_print_instructions_function_handler(RzCore *core, int argc, const char **argv);
// "pj"
RZ_IPI RzCmdStatus rz_print_current_block_json_handler(RzCore *core, int argc, const char **argv);
// "plf"
RZ_IPI RzCmdStatus rz_print_function_rzil_handler(RzCore *core, int argc, const char **argv);
// "pp0"
Expand Down
4 changes: 4 additions & 0 deletions librz/core/cmd_descs/cmd_print.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,10 @@ commands:
summary: Print all instructions at the current function
cname: print_instructions_function
args: []
- name: pj
summary: Parse, format and print JSON at current offset.
cname: print_current_block_json
args: []
- name: plf
summary: Print the RzIL of the function
cname: print_function_rzil
Expand Down
3 changes: 1 addition & 2 deletions librz/include/rz_util/rz_print.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,9 +231,8 @@ RZ_API int rz_print_row_at_off(RzPrint *p, ut32 offset);

// WIP
RZ_API void rz_print_set_screenbounds(RzPrint *p, ut64 addr);
RZ_API char *rz_print_json_indent(const char *s, bool color, const char *tab, const char **colors);
RZ_API RZ_OWN char *rz_print_json_indent(RZ_NULLABLE const char *s, bool color, const char *tab, RZ_NULLABLE const char **palette);
RZ_API char *rz_print_json_human(const char *s);
RZ_API char *rz_print_json_path(const char *s, int pos);

RZ_API RZ_OWN RzStrBuf *rz_print_colorize_asm_str(RZ_BORROW RzPrint *p, const RzAsmTokenString *toks);
RZ_API void rz_print_colored_help_option(const char *option, const char *arg, const char *description, size_t maxOptionAndArgLength);
Expand Down
135 changes: 18 additions & 117 deletions librz/util/json_indent.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,126 +31,16 @@ enum {
JC_RESET,
};

static const char *origColors[] = {
/**
* \brief Default colors for json printing.
*/
static const char *default_colors[] = {
"\x1b[31m",
"\x1b[32m",
"\x1b[33m",
"\x1b[34m",
"\x1b[0m",
};
// static const char colors

RZ_API char *rz_print_json_path(const char *s, int pos) {
int indent = 0;
#define DSZ 128
const char *words[DSZ] = { NULL };
int lengths[DSZ] = { 0 };
int indexs[DSZ] = { 0 };
int instr = 0;
bool isarr = false;
if (!s) {
return NULL;
}
int arrpos = 0;
const char *os = s;
int osz = (1 + strlen(s)) * 20;
if (osz < 1) {
return NULL;
}

const char *str_a = NULL;
for (; *s; s++) {
if (instr) {
if (s[0] == '"') {
instr = 0;
ut64 cur = str_a - os;
if (cur > pos) {
break;
}
if (indent < DSZ) {
words[indent - 1] = str_a;
lengths[indent - 1] = s - str_a;
indexs[indent - 1] = 0;
}
}
continue;
}

if (s[0] == '"') {
instr = 1;
str_a = s + 1;
}
if (*s == '\n' || *s == '\r' || *s == '\t' || *s == ' ') {
continue;
}
switch (*s) {
case ':':
break;
case ',':
if (isarr) {
arrpos++;
if (indent < DSZ) {
indexs[indent - 1] = arrpos;
lengths[indent - 1] = (s - os);
}
}
break;
case '{':
case '[':
if (*s == '[') {
isarr = true;
arrpos = 0;
}
if (indent > 128) {
eprintf("JSON indentation is too deep\n");
indent = 0;
} else {
indent++;
}
break;
case '}':
case ']':
if (*s == ']') {
isarr = false;
}
indent--;
break;
}
}
int i;
ut64 opos = 0;
for (i = 0; i < DSZ && i < indent; i++) {
if ((int)(size_t)words[i] < DSZ) {
ut64 cur = lengths[i];
if (cur < opos) {
continue;
}
opos = cur;
if (cur > pos) {
break;
}
eprintf("0x%08" PFMT64x " %d [%d]\n", cur, i, indexs[i]);
} else {
ut64 cur = words[i] - os - 1;
if (cur < opos) {
continue;
}
opos = cur;
if (cur > pos) {
break;
}
char *a = rz_str_ndup(words[i], lengths[i]);
char *q = strchr(a, '"');
if (q) {
*q = 0;
}
eprintf("0x%08" PFMT64x " %d %s\n", cur, i, a);
free(a);
}
}
// TODO return something
return NULL;
}

RZ_API char *rz_print_json_human(const char *s) {
int indent = 0;
Expand Down Expand Up @@ -251,7 +141,18 @@ RZ_API char *rz_print_json_human(const char *s) {
return O;
}

RZ_API char *rz_print_json_indent(const char *s, bool color, const char *tab, const char **palette) {
/**
* \brief Formats the JSON string at \p s with indentation.
*
* \param s The JSON string to format.
* \param color Format with color?
* \param tab The string to use as indentation tab.
* \param palette The color palette to use. If NULL and \p color == true, a default color palatte is used.
*
* \return The formatted JSON string or NULL in case of failure.
*/
RZ_API RZ_OWN char *rz_print_json_indent(RZ_NULLABLE const char *s, bool color, const char *tab, RZ_NULLABLE const char **palette) {
rz_return_val_if_fail(tab, NULL);
int indent = 0;
const int indentSize = strlen(tab);
int instr = 0;
Expand All @@ -260,13 +161,13 @@ RZ_API char *rz_print_json_indent(const char *s, bool color, const char *tab, co
if (!s) {
return NULL;
}
const char **colors = palette ? palette : origColors;
const char **colors = palette ? palette : default_colors;
int osz = (1 + strlen(s)) * 20;
if (osz < 1) {
return NULL;
}

char *O = malloc(osz);
char *O = RZ_NEWS0(char, osz);
if (!O) {
return NULL;
}
Expand Down
46 changes: 45 additions & 1 deletion test/db/cmd/print
Original file line number Diff line number Diff line change
Expand Up @@ -266,5 +266,49 @@ prz 100 | rz-ax -S
EOF
EXPECT=<<EOF
7f454c46020101
EOF
EOF
RUN

NAME=pj - Print json
FILE==
CMDS=<<EOF
ws "{\"as\": [1, 2, 3],\"asdf\": {\"a\": 1,\"b\": 0}}"
pj
s 0x4
pj
pj @ 0
pj @ 0x80
EOF
EXPECT=<<EOF
{
"as": [
1,
2,
3
],
"asdf": {
"a": 1,
"b": 0
}
}
[
1,
2,
3
] {
"a": 1,
"b": 0
}
{
"as": [
1,
2,
3
],
"asdf": {
"a": 1,
"b": 0
}
}
EOF
RUN
Loading