From 10cb9eaea6e8cbf6055be19ed2fff1da8ff7fed2 Mon Sep 17 00:00:00 2001 From: Rama542 Date: Sun, 8 Mar 2026 13:24:05 +0530 Subject: [PATCH 1/5] Add RZ_OWN/RZ_BORROW pointer ownership annotations to fix rz-bindgen warnings (#5870) Add missing pointer ownership annotations (RZ_OWN or RZ_BORROW) to functions returning non-const pointers in public headers and their corresponding .c implementations. Headers modified: - rz_config.h, rz_hash.h, rz_lang.h, rz_type.h, rz_cmp.h - rz_bin_source_line.h, rz_search.h, rz_parse.h - rz_util/rz_event.h, rz_util/rz_annotated_code.h, rz_util/rz_bitvector.h - rz_il/rz_il_opcodes.h, rz_il/rz_il_reg.h, rz_il/definitions/label.h Functions annotated with RZ_OWN (allocates/returns new memory): rz_config_hold_new, rz_hash_new, rz_lang_new, rz_type_db_new, rz_bin_source_line_info_builder_build_and_fini, rz_event_new, rz_annotated_code_new, rz_il_op_pure_dup, rz_il_reg_binding_derive, rz_il_effect_label_dup, rz_bv_cast, rz_search_new, rz_search_find, rz_search_keyword_new_str, rz_search_keyword_new_wide, rz_search_keyword_new_hex, rz_search_keyword_new_hexmask, rz_search_keyword_new_regexp, rz_parse_new, rz_parse_pseudocode Functions annotated with RZ_BORROW (returns pointer to existing data): rz_core_cmpwatch_get, rz_parse_immtrim --- issues.json | Bin 0 -> 5394 bytes librz/arch/parse.c | 6 +++--- librz/bin/dbginfo.c | 2 +- librz/config/hold.c | 2 +- librz/core/cmp.c | 2 +- librz/hash/hash.c | 2 +- librz/il/definitions/label.c | 2 +- librz/il/il_opcodes.c | 2 +- librz/il/il_reg.c | 2 +- librz/include/rz_bin_source_line.h | 2 +- librz/include/rz_cmp.h | 2 +- librz/include/rz_config.h | 2 +- librz/include/rz_hash.h | 2 +- librz/include/rz_il/definitions/label.h | 2 +- librz/include/rz_il/rz_il_opcodes.h | 2 +- librz/include/rz_il/rz_il_reg.h | 2 +- librz/include/rz_lang.h | 2 +- librz/include/rz_parse.h | 6 +++--- librz/include/rz_search.h | 14 +++++++------- librz/include/rz_type.h | 2 +- librz/include/rz_util/rz_annotated_code.h | 2 +- librz/include/rz_util/rz_bitvector.h | 2 +- librz/include/rz_util/rz_event.h | 2 +- librz/lang/lang.c | 2 +- librz/search/keyword.c | 10 +++++----- librz/search/search.c | 4 ++-- librz/type/type.c | 2 +- librz/util/annotated_code.c | 2 +- librz/util/bitvector.c | 2 +- librz/util/event.c | 2 +- 30 files changed, 44 insertions(+), 44 deletions(-) create mode 100644 issues.json diff --git a/issues.json b/issues.json new file mode 100644 index 0000000000000000000000000000000000000000..6b1e45ef585cf4e0b31eb942aa08db84c7a11ee7 GIT binary patch literal 5394 zcmd6r-ER^>6vgkeiT}fdCrwl+RNDH6mBuF4)IMkvHB#)B68Q=X_QUwEtG_eDNI@F2 z$v#XrEW7iyGv}Ur?w$Gl>!Uri2j&*nkCnGrTCtJMZD?J~Y-$yI;afkqUE8*%J-MgP z%=$L70exbRiXBmwbM+aq$0!pU^PAJ^jFFvP@}F}L^;P@IbH@D}rJ8}Gen8JLtu^{3 zWjUp4@2o@Vtv&raN{27sH@i!E4;kwV<4*Zs&QUcpW|gzfDpzmur8(<=#$3kqtNQQX z`tNEky_J$G&{al+{QS9plv2Xc#jzOya57N%hcH-?ZW%bT3JjQ8b zDg?^JbO&U1*Q~PiflYjF**TYk5v#lwYtN{Wzc_mYGyC?M`(xh3)qw7hHX2nnaXgK= z=bm2~PhHa7OkVd1A1p*D$8u)eGV&R`1ly_T_T(Vp&I-i!u2F7>S2cW$C<>_`Bz(^f9u~*$HJq_nht98#|;f@b{g)wbNwy84xHJ z(}wL8;^!QM2H@3&cka$pP=^U+ie^h*Dw3=#aVin4j&JUjsaN5lT^s z#Q!N+%SYNU{uSAIn+$h|C#8d=)?GG|wL(a?z~_iebKB<{>pPfDnT0rh1NO@P9s7|b zbH&({u&tGfZLP3Y9H0x=;M0M1!K;;{NhK6FgW4-5UU{yLd|3}vQ^7E-xIBJtqqPky z#?LkgN-cvXN;$PR4w+m|xx73bb&M-46SG}3VyBQ#cks^K^Xwd*l%J056S1hqRc9>i zfF}za^{gB%BD%y^-re;Is-4~iNGl(hF_Vx(Yqv3HY~>+3t#E!vC|!`P)H_754)#&* zm!TDL77gCI{<}K;=%CAKa9;Zgp){eLx%`0DIHxnJ-NSx4E(40~w| z*(RQVwAtkx@a~eaK)|b93pCj&7s)S9$rz4(MASLQrZW(o?1|U%jZ_p{=apLNI(9k( J{p?TY{s1c)`Go)g literal 0 HcmV?d00001 diff --git a/librz/arch/parse.c b/librz/arch/parse.c index 915ea2e2bac..e37ea6507c5 100644 --- a/librz/arch/parse.c +++ b/librz/arch/parse.c @@ -9,7 +9,7 @@ #include #include -RZ_API RzParse *rz_parse_new(void) { +RZ_API RZ_OWN RzParse *rz_parse_new(void) { RzParse *p = RZ_NEW0(RzParse); if (!p) { return NULL; @@ -128,7 +128,7 @@ RZ_API bool rz_parse_assemble(RzParse *p, char *data, char *str) { * * Converts the assembly line into pseudocode * */ -RZ_API char *rz_parse_pseudocode(RzParse *p, const char *assembly) { +RZ_API RZ_OWN char *rz_parse_pseudocode(RzParse *p, const char *assembly) { rz_return_val_if_fail(p, NULL); if (RZ_STR_ISEMPTY(assembly)) { return NULL; @@ -148,7 +148,7 @@ RZ_API char *rz_parse_pseudocode(RzParse *p, const char *assembly) { return rz_strbuf_drain(sb); } -RZ_API char *rz_parse_immtrim(char *opstr) { +RZ_API RZ_BORROW char *rz_parse_immtrim(char *opstr) { if (!opstr || !*opstr) { return NULL; } diff --git a/librz/bin/dbginfo.c b/librz/bin/dbginfo.c index 6672619782b..a268ad28ced 100644 --- a/librz/bin/dbginfo.c +++ b/librz/bin/dbginfo.c @@ -85,7 +85,7 @@ static int line_sample_cmp(const void *a, const void *b, void *user) { return strcmp(sa->file, sb->file); } -RZ_API RzBinSourceLineInfo *rz_bin_source_line_info_builder_build_and_fini(RzBinSourceLineInfoBuilder *builder) { +RZ_API RZ_OWN RzBinSourceLineInfo *rz_bin_source_line_info_builder_build_and_fini(RzBinSourceLineInfoBuilder *builder) { RzBinSourceLineInfo *r = RZ_NEW0(RzBinSourceLineInfo); if (!r) { goto err; diff --git a/librz/config/hold.c b/librz/config/hold.c index 47f12e390b7..cb16f28cfa1 100644 --- a/librz/config/hold.c +++ b/librz/config/hold.c @@ -113,7 +113,7 @@ RZ_API bool rz_config_hold_i(RzConfigHold *h, ...) { * \param cfg RzConfig reference * \return RzConfigHold allocated object */ -RZ_API RzConfigHold *rz_config_hold_new(RzConfig *cfg) { +RZ_API RZ_OWN RzConfigHold *rz_config_hold_new(RzConfig *cfg) { if (cfg) { RzConfigHold *hold = RZ_NEW0(RzConfigHold); if (hold) { diff --git a/librz/core/cmp.c b/librz/core/cmp.c index 548aedb6b20..bd6b9e2dac3 100644 --- a/librz/core/cmp.c +++ b/librz/core/cmp.c @@ -315,7 +315,7 @@ RZ_API void rz_core_cmpwatch_free(RzCoreCmpWatcher *w) { * \param addr Expected address for the memory watcher to be found * \return RzCoreCmpWatcher* Pointer to the found memory watcher; NULL if not found */ -RZ_API RzCoreCmpWatcher *rz_core_cmpwatch_get(RzCore *core, ut64 addr) { +RZ_API RZ_BORROW RzCoreCmpWatcher *rz_core_cmpwatch_get(RzCore *core, ut64 addr) { rz_return_val_if_fail(core, NULL); RzListIter *iter; RzCoreCmpWatcher *w; diff --git a/librz/hash/hash.c b/librz/hash/hash.c index b194d07ae06..69ad1a72735 100644 --- a/librz/hash/hash.c +++ b/librz/hash/hash.c @@ -714,7 +714,7 @@ RZ_API RZ_OWN char *rz_hash_cfg_calculate_small_block_string(RZ_NONNULL RzHash * * Create a new RzHash object where plugins can be registered and specific * configurations can be created from. */ -RZ_API RzHash *rz_hash_new(void) { +RZ_API RZ_OWN RzHash *rz_hash_new(void) { RzHash *rh = RZ_NEW0(RzHash); if (!rh) { return NULL; diff --git a/librz/il/definitions/label.c b/librz/il/definitions/label.c index aa305850d44..4a4535407e4 100644 --- a/librz/il/definitions/label.c +++ b/librz/il/definitions/label.c @@ -25,7 +25,7 @@ RZ_API void rz_il_effect_label_free(RzILEffectLabel *lbl) { return; } -RZ_API RzILEffectLabel *rz_il_effect_label_dup(RZ_NONNULL RzILEffectLabel *lbl) { +RZ_API RZ_OWN RzILEffectLabel *rz_il_effect_label_dup(RZ_NONNULL RzILEffectLabel *lbl) { rz_return_val_if_fail(lbl, NULL); RzILEffectLabel *r = rz_il_effect_label_new(lbl->label_id, lbl->type); if (!r) { diff --git a/librz/il/il_opcodes.c b/librz/il/il_opcodes.c index 59da677c867..4b48d692dde 100644 --- a/librz/il/il_opcodes.c +++ b/librz/il/il_opcodes.c @@ -1044,7 +1044,7 @@ RZ_API RZ_OWN RzILOpFloat *rz_il_op_new_fcompound(RzFloatRMode rmode, RZ_NONNULL /** * Duplicate the given op recursively, for example to reuse it multiple times in another op. */ -RZ_API RzILOpPure *rz_il_op_pure_dup(RZ_NONNULL RzILOpPure *op) { +RZ_API RZ_OWN RzILOpPure *rz_il_op_pure_dup(RZ_NONNULL RzILOpPure *op) { rz_return_val_if_fail(op, NULL); RzILOpPure *r = RZ_NEW0(RzILOpPure); if (!r) { diff --git a/librz/il/il_reg.c b/librz/il/il_reg.c index be32db057c5..91ef9133b21 100644 --- a/librz/il/il_reg.c +++ b/librz/il/il_reg.c @@ -32,7 +32,7 @@ static void reg_binding_item_fini(RzILRegBindingItem *item, void *unused) { * * If two registers have the same offset and size, the result is currently undefined. */ -RZ_API RzILRegBinding *rz_il_reg_binding_derive(RZ_NONNULL RzReg *reg) { +RZ_API RZ_OWN RzILRegBinding *rz_il_reg_binding_derive(RZ_NONNULL RzReg *reg) { rz_return_val_if_fail(reg, NULL); RzILRegBinding *rb = RZ_NEW0(RzILRegBinding); if (!rb) { diff --git a/librz/include/rz_bin_source_line.h b/librz/include/rz_bin_source_line.h index de3fa1b2814..7ac58ea45c8 100644 --- a/librz/include/rz_bin_source_line.h +++ b/librz/include/rz_bin_source_line.h @@ -106,7 +106,7 @@ typedef struct { RZ_API void rz_bin_source_line_info_builder_init(RzBinSourceLineInfoBuilder *builder); RZ_API void rz_bin_source_line_info_builder_fini(RzBinSourceLineInfoBuilder *builder); RZ_API void rz_bin_source_line_info_builder_push_sample(RzBinSourceLineInfoBuilder *builder, ut64 address, ut32 line, ut32 column, const char *file); -RZ_API RzBinSourceLineInfo *rz_bin_source_line_info_builder_build_and_fini(RzBinSourceLineInfoBuilder *builder); +RZ_API RZ_OWN RzBinSourceLineInfo *rz_bin_source_line_info_builder_build_and_fini(RzBinSourceLineInfoBuilder *builder); RZ_API bool rz_bin_source_line_info_merge(RZ_BORROW RZ_NONNULL RzBinSourceLineInfo *dst, RZ_BORROW RZ_NONNULL RzBinSourceLineInfo *src); RZ_API void rz_bin_source_line_info_free(RzBinSourceLineInfo *sli); diff --git a/librz/include/rz_cmp.h b/librz/include/rz_cmp.h index e4db6836021..68e9a680044 100644 --- a/librz/include/rz_cmp.h +++ b/librz/include/rz_cmp.h @@ -41,7 +41,7 @@ typedef struct rz_core_cmpwatch_t { /* watchers */ RZ_API void rz_core_cmpwatch_free(RzCoreCmpWatcher *w); -RZ_API RzCoreCmpWatcher *rz_core_cmpwatch_get(RzCore *core, ut64 addr); +RZ_API RZ_BORROW RzCoreCmpWatcher *rz_core_cmpwatch_get(RzCore *core, ut64 addr); RZ_API bool rz_core_cmpwatch_add(RzCore *core, ut64 addr, int size, const char *cmd); RZ_API bool rz_core_cmpwatch_del(RzCore *core, ut64 addr); RZ_API bool rz_core_cmpwatch_update(RzCore *core, ut64 addr); diff --git a/librz/include/rz_config.h b/librz/include/rz_config.h index 1adae7acad5..7d6cc0c0f59 100644 --- a/librz/include/rz_config.h +++ b/librz/include/rz_config.h @@ -74,7 +74,7 @@ typedef struct rz_config_hold_t { } RzConfigHold; #ifdef RZ_API -RZ_API RzConfigHold *rz_config_hold_new(RzConfig *cfg); +RZ_API RZ_OWN RzConfigHold *rz_config_hold_new(RzConfig *cfg); RZ_API void rz_config_hold_free(RzConfigHold *h); RZ_API bool rz_config_hold_i(RzConfigHold *h, ...); diff --git a/librz/include/rz_hash.h b/librz/include/rz_hash.h index abf7b07d2aa..c4a82ead34c 100644 --- a/librz/include/rz_hash.h +++ b/librz/include/rz_hash.h @@ -67,7 +67,7 @@ static inline int rz_hash_plugin_cmp(RZ_NULLABLE const RzHashPlugin *a, RZ_NULLA #ifdef RZ_API -RZ_API RzHash *rz_hash_new(void); +RZ_API RZ_OWN RzHash *rz_hash_new(void); RZ_API void rz_hash_free(RZ_NULLABLE RzHash *rh); RZ_API bool rz_hash_plugin_add(RZ_NONNULL RzHash *rh, RZ_NONNULL RZ_OWN RzHashPlugin *plugin); RZ_API bool rz_hash_plugin_del(RZ_NONNULL RzHash *rh, RZ_NONNULL RzHashPlugin *plugin); diff --git a/librz/include/rz_il/definitions/label.h b/librz/include/rz_il/definitions/label.h index e2db9871a42..462b29c7469 100644 --- a/librz/include/rz_il/definitions/label.h +++ b/librz/include/rz_il/definitions/label.h @@ -32,7 +32,7 @@ typedef struct rz_il_effect_label_t { RZ_API RzILEffectLabel *rz_il_effect_label_new(RZ_NONNULL const char *name, RzILEffectLabelType type); RZ_API void rz_il_effect_label_free(RzILEffectLabel *lbl); -RZ_API RzILEffectLabel *rz_il_effect_label_dup(RZ_NONNULL RzILEffectLabel *lbl); +RZ_API RZ_OWN RzILEffectLabel *rz_il_effect_label_dup(RZ_NONNULL RzILEffectLabel *lbl); #ifdef __cplusplus } diff --git a/librz/include/rz_il/rz_il_opcodes.h b/librz/include/rz_il/rz_il_opcodes.h index 1d9522a4686..5ef7113f8f3 100644 --- a/librz/include/rz_il/rz_il_opcodes.h +++ b/librz/include/rz_il/rz_il_opcodes.h @@ -696,7 +696,7 @@ typedef RzILOpBitVector *(rz_il_pure_2args_op)(RzILOpBitVector *, RzILOpBitVecto typedef RzILOpBitVector *(rz_il_pure_3args_op)(RzILOpBitVector *, RzILOpBitVector *, RzILOpBitVector *); RZ_API void rz_il_op_pure_free(RZ_NULLABLE RzILOpPure *op); -RZ_API RzILOpPure *rz_il_op_pure_dup(RZ_NONNULL RzILOpPure *op); +RZ_API RZ_OWN RzILOpPure *rz_il_op_pure_dup(RZ_NONNULL RzILOpPure *op); RZ_API RZ_OWN RzILOpPure *rz_il_op_new_ite(RZ_NONNULL RzILOpPure *condition, RZ_NULLABLE RzILOpPure *x, RZ_NULLABLE RzILOpPure *y); RZ_API RZ_OWN RzILOpPure *rz_il_op_new_var(RZ_NONNULL const char *var, RzILVarKind kind); diff --git a/librz/include/rz_il/rz_il_reg.h b/librz/include/rz_il/rz_il_reg.h index 8255ba00111..dceadda8c5c 100644 --- a/librz/include/rz_il/rz_il_reg.h +++ b/librz/include/rz_il/rz_il_reg.h @@ -26,7 +26,7 @@ typedef struct rz_il_reg_binding_t { struct rz_il_vm_t; -RZ_API RzILRegBinding *rz_il_reg_binding_derive(RZ_NONNULL RzReg *reg); +RZ_API RZ_OWN RzILRegBinding *rz_il_reg_binding_derive(RZ_NONNULL RzReg *reg); RZ_API RzILRegBinding *rz_il_reg_binding_exactly(RZ_NONNULL RzReg *reg, size_t regs_count, RZ_NONNULL RZ_BORROW const char **regs); RZ_API void rz_il_reg_binding_free(RzILRegBinding *rb); diff --git a/librz/include/rz_lang.h b/librz/include/rz_lang.h index f7249d6f667..37b682e13c3 100644 --- a/librz/include/rz_lang.h +++ b/librz/include/rz_lang.h @@ -48,7 +48,7 @@ typedef struct rz_lang_def_t { } RzLangDef; #ifdef RZ_API -RZ_API RzLang *rz_lang_new(void); +RZ_API RZ_OWN RzLang *rz_lang_new(void); RZ_API void rz_lang_free(RzLang *lang); RZ_API bool rz_lang_setup(RzLang *lang); RZ_API bool rz_lang_plugin_add(RzLang *lang, RZ_NONNULL RzLangPlugin *plugin); diff --git a/librz/include/rz_parse.h b/librz/include/rz_parse.h index 34d4b9c0e01..64ac3c6b322 100644 --- a/librz/include/rz_parse.h +++ b/librz/include/rz_parse.h @@ -50,7 +50,7 @@ typedef struct rz_parse_plugin_t { #ifdef RZ_API /* lifecycle */ -RZ_API RzParse *rz_parse_new(void); +RZ_API RZ_OWN RzParse *rz_parse_new(void); RZ_API void rz_parse_free(RzParse *p); /* plugins */ @@ -60,11 +60,11 @@ RZ_API bool rz_parse_plugin_del(RzParse *p, RZ_NONNULL RzParsePlugin *plugin); RZ_API bool rz_parse_use(RzParse *p, const char *name); /* action */ -RZ_API char *rz_parse_pseudocode(RzParse *p, const char *data); +RZ_API RZ_OWN char *rz_parse_pseudocode(RzParse *p, const char *data); RZ_API bool rz_parse_assemble(RzParse *p, char *data, char *str); // XXX deprecate, unused and probably useless, related to write-hack RZ_API bool rz_parse_filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char *data, char *str, int len, bool big_endian); RZ_API bool rz_parse_subvar(RzParse *p, RZ_NULLABLE RzAnalysisFunction *f, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL RZ_IN char *data, RZ_BORROW RZ_NONNULL RZ_OUT char *str, int len); -RZ_API char *rz_parse_immtrim(char *opstr); +RZ_API RZ_BORROW char *rz_parse_immtrim(char *opstr); #endif diff --git a/librz/include/rz_search.h b/librz/include/rz_search.h index 851568e0672..16510fa01ef 100644 --- a/librz/include/rz_search.h +++ b/librz/include/rz_search.h @@ -83,22 +83,22 @@ typedef struct rz_search_value_range_t { #define RZ_SEARCH_AES_BOX_SIZE 31 -RZ_API RzSearch *rz_search_new(int mode); +RZ_API RZ_OWN RzSearch *rz_search_new(int mode); RZ_API int rz_search_set_mode(RzSearch *s, int mode); RZ_API RzSearch *rz_search_free(RzSearch *s); /* keyword management */ -RZ_API RzList /**/ *rz_search_find(RzSearch *s, ut64 addr, const ut8 *buf, int len); +RZ_API RZ_OWN RzList /**/ *rz_search_find(RzSearch *s, ut64 addr, const ut8 *buf, int len); RZ_API int rz_search_update(RzSearch *s, ut64 from, const ut8 *buf, long len); RZ_API int rz_search_update_i(RzSearch *s, ut64 from, const ut8 *buf, long len); RZ_API void rz_search_keyword_free(RzSearchKeyword *kw); RZ_API RZ_OWN RzSearchKeyword *rz_search_keyword_new(const ut8 *kw_buf, int kw_len, RZ_NULLABLE const ut8 *bm_buf, int bm_buf_len, RZ_NULLABLE const char *data); -RZ_API RzSearchKeyword *rz_search_keyword_new_str(const char *kw, const char *bm, const char *data, int icase); -RZ_API RzSearchKeyword *rz_search_keyword_new_wide(const char *kw, const char *bm, const char *data, int icase); -RZ_API RzSearchKeyword *rz_search_keyword_new_hex(const char *kwstr, const char *bmstr, const char *data); -RZ_API RzSearchKeyword *rz_search_keyword_new_hexmask(const char *kwstr, const char *data); -RZ_API RzSearchKeyword *rz_search_keyword_new_regexp(const char *str, const char *data); +RZ_API RZ_OWN RzSearchKeyword *rz_search_keyword_new_str(const char *kw, const char *bm, const char *data, int icase); +RZ_API RZ_OWN RzSearchKeyword *rz_search_keyword_new_wide(const char *kw, const char *bm, const char *data, int icase); +RZ_API RZ_OWN RzSearchKeyword *rz_search_keyword_new_hex(const char *kwstr, const char *bmstr, const char *data); +RZ_API RZ_OWN RzSearchKeyword *rz_search_keyword_new_hexmask(const char *kwstr, const char *data); +RZ_API RZ_OWN RzSearchKeyword *rz_search_keyword_new_regexp(const char *str, const char *data); RZ_API int rz_search_kw_add(RzSearch *s, RzSearchKeyword *kw); RZ_API void rz_search_reset(RzSearch *s, int mode); diff --git a/librz/include/rz_type.h b/librz/include/rz_type.h index 7dd976ea438..dc2e90ee12e 100644 --- a/librz/include/rz_type.h +++ b/librz/include/rz_type.h @@ -248,7 +248,7 @@ typedef struct rz_type_format_t { #ifdef RZ_API -RZ_API RzTypeDB *rz_type_db_new(); +RZ_API RZ_OWN RzTypeDB *rz_type_db_new(); RZ_API void rz_type_db_free(RzTypeDB *typedb); RZ_API bool rz_type_db_load_sdb(RzTypeDB *typedb, RZ_NONNULL const char *path); RZ_API bool rz_type_db_load_sdb_str(RzTypeDB *typedb, RZ_NONNULL const char *str); diff --git a/librz/include/rz_util/rz_annotated_code.h b/librz/include/rz_util/rz_annotated_code.h index 6913642fa44..292ab878536 100644 --- a/librz/include/rz_util/rz_annotated_code.h +++ b/librz/include/rz_util/rz_annotated_code.h @@ -92,7 +92,7 @@ typedef struct rz_annotated_code_t { * @param code A deallocatable character array. * @return Pointer to the new RzAnnotatedCode structure created. */ -RZ_API RzAnnotatedCode *rz_annotated_code_new(char *code); +RZ_API RZ_OWN RzAnnotatedCode *rz_annotated_code_new(char *code); /** * @brief Deallocates the dynamically allocated memory for the specified RzAnnotatedCode. * diff --git a/librz/include/rz_util/rz_bitvector.h b/librz/include/rz_util/rz_bitvector.h index 4699df2ed51..0960e54b9d8 100644 --- a/librz/include/rz_util/rz_bitvector.h +++ b/librz/include/rz_util/rz_bitvector.h @@ -103,7 +103,7 @@ RZ_API ut32 rz_bv_clz(RZ_NONNULL RzBitVector *bv); RZ_API ut32 rz_bv_ctz(RZ_NONNULL RzBitVector *bv); RZ_API bool rz_bv_cast_inplace(RZ_INOUT RZ_NONNULL RzBitVector *bv, ut32 to_size, bool fill_bit); -RZ_API RzBitVector *rz_bv_cast(RZ_NONNULL RzBitVector *bv, ut32 to_size, bool fill_bit); +RZ_API RZ_OWN RzBitVector *rz_bv_cast(RZ_NONNULL RzBitVector *bv, ut32 to_size, bool fill_bit); // some convert functions RZ_API ut8 rz_bv_to_ut8(RZ_NONNULL const RzBitVector *x); diff --git a/librz/include/rz_util/rz_event.h b/librz/include/rz_util/rz_event.h index 4ec71c3c94e..afc558e5265 100644 --- a/librz/include/rz_util/rz_event.h +++ b/librz/include/rz_util/rz_event.h @@ -81,7 +81,7 @@ typedef struct rz_event_debug_process_finished_t { int pid; } RzEventDebugProcessFinished; -RZ_API RzEvent *rz_event_new(void *user); +RZ_API RZ_OWN RzEvent *rz_event_new(void *user); RZ_API void rz_event_free(RzEvent *ev); RZ_API RzEventCallbackHandle rz_event_hook(RzEvent *ev, int type, RzEventCallback cb, void *user); RZ_API void rz_event_unhook(RzEvent *ev, RzEventCallbackHandle handle); diff --git a/librz/lang/lang.c b/librz/lang/lang.c index 36b71377d2e..cbdca79ac06 100644 --- a/librz/lang/lang.c +++ b/librz/lang/lang.c @@ -18,7 +18,7 @@ static bool plugin_fini(RzLang *lang, RzLangPlugin *plugin) { return true; } -RZ_API RzLang *rz_lang_new(void) { +RZ_API RZ_OWN RzLang *rz_lang_new(void) { RzLang *lang = RZ_NEW0(RzLang); if (!lang) { return NULL; diff --git a/librz/search/keyword.c b/librz/search/keyword.c index 2daef7d877f..25e36848905 100644 --- a/librz/search/keyword.c +++ b/librz/search/keyword.c @@ -66,7 +66,7 @@ RZ_API void rz_search_keyword_free(RzSearchKeyword *kw) { free(kw); } -RZ_API RzSearchKeyword *rz_search_keyword_new_str(const char *kwbuf, const char *bmstr, const char *data, int ignore_case) { +RZ_API RZ_OWN RzSearchKeyword *rz_search_keyword_new_str(const char *kwbuf, const char *bmstr, const char *data, int ignore_case) { RzSearchKeyword *kw; ut8 *bmbuf = NULL; int bmlen = 0; @@ -90,7 +90,7 @@ RZ_API RzSearchKeyword *rz_search_keyword_new_str(const char *kwbuf, const char return kw; } -RZ_API RzSearchKeyword *rz_search_keyword_new_wide(const char *kwbuf, const char *bmstr, const char *data, int ignore_case) { +RZ_API RZ_OWN RzSearchKeyword *rz_search_keyword_new_wide(const char *kwbuf, const char *bmstr, const char *data, int ignore_case) { RzSearchKeyword *kw; int len; const char *p2; @@ -140,7 +140,7 @@ RZ_API RzSearchKeyword *rz_search_keyword_new_wide(const char *kwbuf, const char return kw; } -RZ_API RzSearchKeyword *rz_search_keyword_new_hex(const char *kwstr, const char *bmstr, const char *data) { +RZ_API RZ_OWN RzSearchKeyword *rz_search_keyword_new_hex(const char *kwstr, const char *bmstr, const char *data) { RzSearchKeyword *kw; ut8 *kwbuf, *bmbuf; int kwlen, bmlen = 0; @@ -181,7 +181,7 @@ RZ_API RzSearchKeyword *rz_search_keyword_new_hex(const char *kwstr, const char return kw; } -RZ_API RzSearchKeyword *rz_search_keyword_new_hexmask(const char *kwstr, const char *data) { +RZ_API RZ_OWN RzSearchKeyword *rz_search_keyword_new_hexmask(const char *kwstr, const char *data) { RzSearchKeyword *ks = NULL; ut8 *kw, *bm; if (kwstr != NULL) { @@ -204,7 +204,7 @@ RZ_API RzSearchKeyword *rz_search_keyword_new_hexmask(const char *kwstr, const c } /* Validate a regexp in the canonical format // */ -RZ_API RzSearchKeyword *rz_search_keyword_new_regexp(const char *str, const char *data) { +RZ_API RZ_OWN RzSearchKeyword *rz_search_keyword_new_regexp(const char *str, const char *data) { RzSearchKeyword *kw; int i = 0, start, length; diff --git a/librz/search/search.c b/librz/search/search.c index 0be4342c167..5007588a252 100644 --- a/librz/search/search.c +++ b/librz/search/search.c @@ -23,7 +23,7 @@ typedef struct { ut8 data[]; } RzSearchLeftover; -RZ_API RzSearch *rz_search_new(int mode) { +RZ_API RZ_OWN RzSearch *rz_search_new(int mode) { RzSearch *s = RZ_NEW0(RzSearch); if (!s) { return NULL; @@ -465,7 +465,7 @@ static int listcb(RzSearchKeyword *k, void *user, ut64 addr) { return 1; } -RZ_API RzList /**/ *rz_search_find(RzSearch *s, ut64 addr, const ut8 *buf, int len) { +RZ_API RZ_OWN RzList /**/ *rz_search_find(RzSearch *s, ut64 addr, const ut8 *buf, int len) { RzList *ret = rz_list_new(); rz_search_set_callback(s, listcb, ret); rz_search_update(s, addr, buf, len); diff --git a/librz/type/type.c b/librz/type/type.c index 599f1797fbf..49c7faf5dd7 100644 --- a/librz/type/type.c +++ b/librz/type/type.c @@ -16,7 +16,7 @@ * hashtables for RzBaseType, RzCallable, type formats. * Also initializes default "target" (arch, bits, platform) parameters. */ -RZ_API RzTypeDB *rz_type_db_new() { +RZ_API RZ_OWN RzTypeDB *rz_type_db_new() { RzTypeDB *typedb = RZ_NEW0(RzTypeDB); if (!typedb) { return NULL; diff --git a/librz/util/annotated_code.c b/librz/util/annotated_code.c index 55f3695cc18..8c3f4f1b550 100644 --- a/librz/util/annotated_code.c +++ b/librz/util/annotated_code.c @@ -5,7 +5,7 @@ #include #include -RZ_API RzAnnotatedCode *rz_annotated_code_new(char *code) { +RZ_API RZ_OWN RzAnnotatedCode *rz_annotated_code_new(char *code) { RzAnnotatedCode *r = RZ_NEW0(RzAnnotatedCode); if (!r) { return NULL; diff --git a/librz/util/bitvector.c b/librz/util/bitvector.c index 75d5ba7c679..346489fb033 100644 --- a/librz/util/bitvector.c +++ b/librz/util/bitvector.c @@ -2289,7 +2289,7 @@ RZ_API bool rz_bv_cast_inplace(RZ_INOUT RZ_NONNULL RzBitVector *bv, ut32 to_size * \param fill_bit specify filling bit if extend * \return new bv with length (to_size) */ -RZ_API RzBitVector *rz_bv_cast(RZ_NONNULL RzBitVector *bv, ut32 to_size, bool fill_bit) { +RZ_API RZ_OWN RzBitVector *rz_bv_cast(RZ_NONNULL RzBitVector *bv, ut32 to_size, bool fill_bit) { rz_return_val_if_fail(bv, NULL); RzBitVector *ret = rz_bv_new(to_size); diff --git a/librz/util/event.c b/librz/util/event.c index 66b07bcacc2..52d19187815 100644 --- a/librz/util/event.c +++ b/librz/util/event.c @@ -10,7 +10,7 @@ typedef struct rz_event_callback_hook_t { int handle; } RzEventCallbackHook; -RZ_API RzEvent *rz_event_new(void *user) { +RZ_API RZ_OWN RzEvent *rz_event_new(void *user) { RzEvent *ev = RZ_NEW0(RzEvent); if (!ev) { return NULL; From 5f535acae3946e6f26f1241a29a953f79c2ce8a5 Mon Sep 17 00:00:00 2001 From: Rama542 Date: Sun, 8 Mar 2026 13:30:24 +0530 Subject: [PATCH 2/5] Add ownership annotations to medium-sized modules --- librz/core/agraph.c | 4 ++-- librz/il/definitions/bool.c | 10 +++++----- librz/il/definitions/mem.c | 4 ++-- librz/il/il_validate.c | 4 ++-- librz/include/rz_agraph.h | 4 ++-- librz/include/rz_il/definitions/bool.h | 10 +++++----- librz/include/rz_il/definitions/mem.h | 4 ++-- librz/include/rz_il/rz_il_validate.h | 4 ++-- librz/include/rz_util/rz_strbuf.h | 4 ++-- librz/util/strbuf.c | 4 ++-- 10 files changed, 26 insertions(+), 26 deletions(-) diff --git a/librz/core/agraph.c b/librz/core/agraph.c index 8a8988d54e5..d7e2996237b 100644 --- a/librz/core/agraph.c +++ b/librz/core/agraph.c @@ -3633,7 +3633,7 @@ static void agraph_sdb_init(const RzAGraph *g) { sdb_set_enc(g->db, "agraph.color_false", cons->context->pal.graph_false); } -RZ_API Sdb *rz_agraph_get_sdb(RzAGraph *g) { +RZ_API RZ_BORROW Sdb *rz_agraph_get_sdb(RzAGraph *g) { g->need_update_dim = true; g->need_set_layout = true; AGraphContext grp_ctx = { 0 }; @@ -3948,7 +3948,7 @@ RZ_API void rz_agraph_free(RzAGraph *g) { free(g); } -RZ_API RzAGraph *rz_agraph_new(RzConsCanvas *can) { +RZ_API RZ_OWN RzAGraph *rz_agraph_new(RzConsCanvas *can) { RzAGraph *g = RZ_NEW0(RzAGraph); if (!g) { return NULL; diff --git a/librz/il/definitions/bool.c b/librz/il/definitions/bool.c index abf07ef6a14..c742fde0cce 100644 --- a/librz/il/definitions/bool.c +++ b/librz/il/definitions/bool.c @@ -8,7 +8,7 @@ * \param true_or_false bool, set bool as true or false * \return bool RzILBool, pointer to bool value */ -RZ_API RzILBool *rz_il_bool_new(bool true_or_false) { +RZ_API RZ_OWN RzILBool *rz_il_bool_new(bool true_or_false) { RzILBool *ret = RZ_NEW0(RzILBool); if (!ret) { return NULL; @@ -23,7 +23,7 @@ RZ_API RzILBool *rz_il_bool_new(bool true_or_false) { * \param b RzILBool, operand of `AND` * \return bool RzILBool, pointer to the result */ -RZ_API RzILBool *rz_il_bool_and(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b) { +RZ_API RZ_OWN RzILBool *rz_il_bool_and(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b) { rz_return_val_if_fail(a && b, NULL); bool result = a->b && b->b; RzILBool *ret = rz_il_bool_new(result); @@ -36,7 +36,7 @@ RZ_API RzILBool *rz_il_bool_and(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b) * \param b RzILBool, operand of `AND` * \return bool RzILBool, pointer to the result */ -RZ_API RzILBool *rz_il_bool_or(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b) { +RZ_API RZ_OWN RzILBool *rz_il_bool_or(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b) { rz_return_val_if_fail(a && b, NULL); bool result = a->b || b->b; RzILBool *ret = rz_il_bool_new(result); @@ -49,7 +49,7 @@ RZ_API RzILBool *rz_il_bool_or(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b) { * \param b RzILBool, operand of `AND` * \return bool RzILBool, pointer to the result */ -RZ_API RzILBool *rz_il_bool_xor(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b) { +RZ_API RZ_OWN RzILBool *rz_il_bool_xor(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b) { rz_return_val_if_fail(a && b, NULL); bool result = a->b != b->b; return rz_il_bool_new(result); @@ -60,7 +60,7 @@ RZ_API RzILBool *rz_il_bool_xor(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b) * \param a RzILBool, operand of `AND` * \return bool RzILBool, pointer to the result */ -RZ_API RzILBool *rz_il_bool_not(RZ_NONNULL RzILBool *a) { +RZ_API RZ_OWN RzILBool *rz_il_bool_not(RZ_NONNULL RzILBool *a) { rz_return_val_if_fail(a, NULL); bool result = !a->b; RzILBool *ret = rz_il_bool_new(result); diff --git a/librz/il/definitions/mem.c b/librz/il/definitions/mem.c index d23a693b81b..d1a450de26e 100644 --- a/librz/il/definitions/mem.c +++ b/librz/il/definitions/mem.c @@ -110,7 +110,7 @@ RZ_API ut32 rz_il_mem_value_len(RzILMem *mem) { * \param key address (bitvector) * \return data (bitvector) */ -RZ_API RzBitVector *rz_il_mem_load(RzILMem *mem, RzBitVector *key) { +RZ_API RZ_OWN RzBitVector *rz_il_mem_load(RzILMem *mem, RzBitVector *key) { rz_return_val_if_fail(mem && key, NULL); return_val_if_key_len_wrong(mem, key, NULL); ut8 v = 0; @@ -180,7 +180,7 @@ static bool write_n_bits(RzBuffer *buf, RzBitVector *key, RzBitVector *value, bo * \param n_bits How many bits to read. This also determines the size of the returned bitvector * \return data (bitvector) */ -RZ_API RzBitVector *rz_il_mem_loadw(RzILMem *mem, RzBitVector *key, ut32 n_bits, bool big_endian) { +RZ_API RZ_OWN RzBitVector *rz_il_mem_loadw(RzILMem *mem, RzBitVector *key, ut32 n_bits, bool big_endian) { rz_return_val_if_fail(mem && key && n_bits, NULL); return_val_if_key_len_wrong(mem, key, NULL); return read_n_bits(mem->buf, n_bits, key, big_endian); diff --git a/librz/il/il_validate.c b/librz/il/il_validate.c index 7c5fa92c887..c0aa75d0e90 100644 --- a/librz/il/il_validate.c +++ b/librz/il/il_validate.c @@ -20,7 +20,7 @@ struct rz_il_validate_global_context_t { * Create a new global context for validation * Vars and mems can be added manually with rz_il_validate_global_context_add_* functions. */ -RZ_API RzILValidateGlobalContext *rz_il_validate_global_context_new_empty(ut32 pc_len) { +RZ_API RZ_OWN RzILValidateGlobalContext *rz_il_validate_global_context_new_empty(ut32 pc_len) { rz_return_val_if_fail(pc_len, NULL); RzILValidateGlobalContext *ctx = RZ_NEW0(RzILValidateGlobalContext); if (!ctx) { @@ -65,7 +65,7 @@ RZ_API void rz_il_validate_global_context_add_mem(RzILValidateGlobalContext *ctx /** * Create a new context for IL validation based on the global vars and mems in \p vm */ -RZ_API RzILValidateGlobalContext *rz_il_validate_global_context_new_from_vm(RZ_NONNULL RzILVM *vm) { +RZ_API RZ_OWN RzILValidateGlobalContext *rz_il_validate_global_context_new_from_vm(RZ_NONNULL RzILVM *vm) { rz_return_val_if_fail(vm, NULL); RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(rz_il_vm_get_pc_len(vm)); RzPVector *vars = rz_il_vm_get_all_vars(vm, RZ_IL_VAR_KIND_GLOBAL); diff --git a/librz/include/rz_agraph.h b/librz/include/rz_agraph.h index 7d168e00a69..6b4879f4898 100644 --- a/librz/include/rz_agraph.h +++ b/librz/include/rz_agraph.h @@ -92,7 +92,7 @@ typedef struct rz_ascii_graph_t { } RzAGraph; #ifdef RZ_API -RZ_API RzAGraph *rz_agraph_new(RzConsCanvas *can); +RZ_API RZ_OWN RzAGraph *rz_agraph_new(RzConsCanvas *can); RZ_API void rz_agraph_free(RzAGraph *g); RZ_API void rz_agraph_reset(RzAGraph *g); RZ_API void rz_agraph_set_title(RzAGraph *g, const char *title); @@ -106,7 +106,7 @@ RZ_API void rz_agraph_add_edge_at(const RzAGraph *g, RzANode *a, RzANode *b, int RZ_API void rz_agraph_del_edge(const RzAGraph *g, RzANode *a, RzANode *b); RZ_API void rz_agraph_print(RzAGraph *g); RZ_API void rz_agraph_print_json(RzAGraph *g, PJ *pj); -RZ_API Sdb *rz_agraph_get_sdb(RzAGraph *g); +RZ_API RZ_BORROW Sdb *rz_agraph_get_sdb(RzAGraph *g); RZ_API void rz_agraph_foreach(RzAGraph *g, RzANodeCallback cb, void *user); RZ_API void rz_agraph_foreach_edge(RzAGraph *g, RAEdgeCallback cb, void *user); RZ_API void rz_agraph_set_curnode(RzAGraph *g, RzANode *node); diff --git a/librz/include/rz_il/definitions/bool.h b/librz/include/rz_il/definitions/bool.h index 50d6c9adadb..6a9de6b7239 100644 --- a/librz/include/rz_il/definitions/bool.h +++ b/librz/include/rz_il/definitions/bool.h @@ -15,11 +15,11 @@ typedef struct rz_il_bool_t { bool b; } RzILBool; -RZ_API RzILBool *rz_il_bool_new(bool true_or_false); -RZ_API RzILBool *rz_il_bool_and(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b); -RZ_API RzILBool *rz_il_bool_or(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b); -RZ_API RzILBool *rz_il_bool_xor(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b); -RZ_API RzILBool *rz_il_bool_not(RZ_NONNULL RzILBool *a); +RZ_API RZ_OWN RzILBool *rz_il_bool_new(bool true_or_false); +RZ_API RZ_OWN RzILBool *rz_il_bool_and(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b); +RZ_API RZ_OWN RzILBool *rz_il_bool_or(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b); +RZ_API RZ_OWN RzILBool *rz_il_bool_xor(RZ_NONNULL RzILBool *a, RZ_NONNULL RzILBool *b); +RZ_API RZ_OWN RzILBool *rz_il_bool_not(RZ_NONNULL RzILBool *a); RZ_API void rz_il_bool_free(RzILBool *bool_var); #ifdef __cplusplus diff --git a/librz/include/rz_il/definitions/mem.h b/librz/include/rz_il/definitions/mem.h index ab541284e51..5084f546b56 100644 --- a/librz/include/rz_il/definitions/mem.h +++ b/librz/include/rz_il/definitions/mem.h @@ -33,9 +33,9 @@ RZ_API RZ_OWN RzILMem *rz_il_mem_new_borrowed(RZ_NONNULL RZ_BORROW RzBuffer *buf RZ_API void rz_il_mem_free(RzILMem *mem); RZ_API ut32 rz_il_mem_key_len(RzILMem *mem); RZ_API ut32 rz_il_mem_value_len(RzILMem *mem); -RZ_API RzBitVector *rz_il_mem_load(RzILMem *mem, RzBitVector *key); +RZ_API RZ_OWN RzBitVector *rz_il_mem_load(RzILMem *mem, RzBitVector *key); RZ_API bool rz_il_mem_store(RzILMem *mem, RzBitVector *key, RzBitVector *value); -RZ_API RzBitVector *rz_il_mem_loadw(RzILMem *mem, RzBitVector *key, ut32 n_bits, bool big_endian); +RZ_API RZ_OWN RzBitVector *rz_il_mem_loadw(RzILMem *mem, RzBitVector *key, ut32 n_bits, bool big_endian); RZ_API bool rz_il_mem_storew(RzILMem *mem, RzBitVector *key, RzBitVector *value, bool big_endian); #ifdef __cplusplus diff --git a/librz/include/rz_il/rz_il_validate.h b/librz/include/rz_il/rz_il_validate.h index d200fff7be8..0766cfc4790 100644 --- a/librz/include/rz_il/rz_il_validate.h +++ b/librz/include/rz_il/rz_il_validate.h @@ -27,10 +27,10 @@ typedef char *RzILValidateReport; */ typedef struct rz_il_validate_global_context_t RzILValidateGlobalContext; -RZ_API RzILValidateGlobalContext *rz_il_validate_global_context_new_empty(ut32 pc_len); +RZ_API RZ_OWN RzILValidateGlobalContext *rz_il_validate_global_context_new_empty(ut32 pc_len); RZ_API void rz_il_validate_global_context_add_var(RzILValidateGlobalContext *ctx, RZ_NONNULL const char *name, RzILSortPure sort); RZ_API void rz_il_validate_global_context_add_mem(RzILValidateGlobalContext *ctx, RzILMemIndex idx, ut32 key_len, ut32 val_len); -RZ_API RzILValidateGlobalContext *rz_il_validate_global_context_new_from_vm(RZ_NONNULL RzILVM *vm); +RZ_API RZ_OWN RzILValidateGlobalContext *rz_il_validate_global_context_new_from_vm(RZ_NONNULL RzILVM *vm); RZ_API void rz_il_validate_global_context_free(RzILValidateGlobalContext *ctx); RZ_API bool rz_il_validate_pure(RZ_NULLABLE RzILOpPure *op, RZ_NONNULL RzILValidateGlobalContext *ctx, RZ_NULLABLE RZ_OUT RzILSortPure *sort_out, RZ_NULLABLE RZ_OUT RzILValidateReport *report_out); diff --git a/librz/include/rz_util/rz_strbuf.h b/librz/include/rz_util/rz_strbuf.h index 3e208d2d2f6..af2a0499f6c 100644 --- a/librz/include/rz_util/rz_strbuf.h +++ b/librz/include/rz_util/rz_strbuf.h @@ -19,7 +19,7 @@ RZ_API RzStrBuf *rz_strbuf_new(const char *s); RZ_API const char *rz_strbuf_set(RzStrBuf *sb, const char *s); // return = the string or NULL on fail RZ_API bool rz_strbuf_slice(RZ_NONNULL RzStrBuf *sb, size_t from, size_t len); RZ_API bool rz_strbuf_setbin(RzStrBuf *sb, const ut8 *s, size_t len); -RZ_API ut8 *rz_strbuf_getbin(RzStrBuf *sb, size_t *len); +RZ_API RZ_BORROW ut8 *rz_strbuf_getbin(RzStrBuf *sb, size_t *len); RZ_API const char *rz_strbuf_setf(RzStrBuf *sb, const char *fmt, ...) RZ_PRINTF_CHECK(2, 3); // return = the string or NULL on fail RZ_API const char *rz_strbuf_vsetf(RzStrBuf *sb, const char *fmt, va_list ap); // return = the string or NULL on fail RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s); @@ -27,7 +27,7 @@ RZ_API bool rz_strbuf_append_n(RzStrBuf *sb, const char *s, size_t l); RZ_API bool rz_strbuf_prepend(RzStrBuf *sb, const char *s); RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt, ...) RZ_PRINTF_CHECK(2, 3); RZ_API bool rz_strbuf_vappendf(RzStrBuf *sb, const char *fmt, va_list ap); -RZ_API char *rz_strbuf_get(RzStrBuf *sb); +RZ_API RZ_BORROW char *rz_strbuf_get(RzStrBuf *sb); RZ_API RZ_OWN char *rz_strbuf_drain(RZ_OWN RZ_NONNULL RzStrBuf *sb); RZ_API RZ_OWN char *rz_strbuf_drain_nofree(RzStrBuf *sb); RZ_API size_t rz_strbuf_length(RzStrBuf *sb); diff --git a/librz/util/strbuf.c b/librz/util/strbuf.c index e66b9560e28..7e3472a174b 100644 --- a/librz/util/strbuf.c +++ b/librz/util/strbuf.c @@ -298,12 +298,12 @@ RZ_API bool rz_strbuf_vappendf(RzStrBuf *sb, const char *fmt, va_list ap) { return ret; } -RZ_API char *rz_strbuf_get(RzStrBuf *sb) { +RZ_API RZ_BORROW char *rz_strbuf_get(RzStrBuf *sb) { rz_return_val_if_fail(sb, NULL); return sb->ptr ? sb->ptr : sb->buf; } -RZ_API ut8 *rz_strbuf_getbin(RzStrBuf *sb, size_t *len) { +RZ_API RZ_BORROW ut8 *rz_strbuf_getbin(RzStrBuf *sb, size_t *len) { rz_return_val_if_fail(sb, NULL); if (len) { *len = sb->len; From 5d2887ffabc7db1be39a7a098406857fdfad95f4 Mon Sep 17 00:00:00 2001 From: Rama542 Date: Mon, 9 Mar 2026 09:34:27 +0530 Subject: [PATCH 3/5] Add test_ownership.c: verify pointer ownership semantics for annotated functions --- test/unit/meson.build | 1 + test/unit/test_ownership.c | 313 +++++++++++++++++++++++++++++++++++++ 2 files changed, 314 insertions(+) create mode 100644 test/unit/test_ownership.c diff --git a/test/unit/meson.build b/test/unit/meson.build index fd15560ed99..078091b7be1 100644 --- a/test/unit/meson.build +++ b/test/unit/meson.build @@ -94,6 +94,7 @@ if get_option('enable_tests') 'lzma', 'mem', 'ovf', + 'ownership', 'pj', 'rbtree', 'reg', diff --git a/test/unit/test_ownership.c b/test/unit/test_ownership.c new file mode 100644 index 00000000000..052962826fa --- /dev/null +++ b/test/unit/test_ownership.c @@ -0,0 +1,313 @@ +// SPDX-FileCopyrightText: 2024 rizinorg +// SPDX-License-Identifier: LGPL-3.0-only + +/** + * Tests to verify pointer ownership semantics for functions annotated + * with RZ_OWN and RZ_BORROW (issue #5870). + * + * RZ_OWN functions must return newly allocated memory that the caller can free. + * RZ_BORROW functions must return pointers to existing internal data. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "minunit.h" + +// ==================== RZ_OWN tests ==================== +// These tests verify that _new/_dup/_cast functions return +// owned pointers that the caller is responsible for freeing. + +bool test_rz_hash_new_ownership(void) { + RzHash *rh = rz_hash_new(); + mu_assert_notnull(rh, "rz_hash_new should return a non-null owned pointer"); + rz_hash_free(rh); + mu_end; +} + +bool test_rz_config_hold_new_ownership(void) { + RzConfig *cfg = rz_config_new(NULL); + mu_assert_notnull(cfg, "rz_config_new should return non-null"); + + RzConfigHold *hold = rz_config_hold_new(cfg); + mu_assert_notnull(hold, "rz_config_hold_new should return a non-null owned pointer"); + rz_config_hold_free(hold); + + rz_config_free(cfg); + mu_end; +} + +bool test_rz_type_db_new_ownership(void) { + RzTypeDB *typedb = rz_type_db_new(); + mu_assert_notnull(typedb, "rz_type_db_new should return a non-null owned pointer"); + rz_type_db_free(typedb); + mu_end; +} + +bool test_rz_event_new_ownership(void) { + RzEvent *ev = rz_event_new(NULL); + mu_assert_notnull(ev, "rz_event_new should return a non-null owned pointer"); + rz_event_free(ev); + mu_end; +} + +bool test_rz_annotated_code_new_ownership(void) { + char *code = strdup("int main() { return 0; }"); + RzAnnotatedCode *ac = rz_annotated_code_new(code); + mu_assert_notnull(ac, "rz_annotated_code_new should return a non-null owned pointer"); + rz_annotated_code_free(ac); + mu_end; +} + +bool test_rz_search_new_ownership(void) { + RzSearch *s = rz_search_new(RZ_SEARCH_KEYWORD); + mu_assert_notnull(s, "rz_search_new should return a non-null owned pointer"); + rz_search_free(s); + mu_end; +} + +bool test_rz_search_keyword_new_str_ownership(void) { + RzSearchKeyword *kw = rz_search_keyword_new_str("hello", NULL, NULL, 0); + mu_assert_notnull(kw, "rz_search_keyword_new_str should return a non-null owned pointer"); + rz_search_keyword_free(kw); + mu_end; +} + +bool test_rz_search_keyword_new_hex_ownership(void) { + RzSearchKeyword *kw = rz_search_keyword_new_hex("deadbeef", NULL, NULL); + mu_assert_notnull(kw, "rz_search_keyword_new_hex should return a non-null owned pointer"); + rz_search_keyword_free(kw); + mu_end; +} + +bool test_rz_il_bool_new_ownership(void) { + RzILBool *b = rz_il_bool_new(true); + mu_assert_notnull(b, "rz_il_bool_new should return a non-null owned pointer"); + mu_assert_eq(b->b, true, "bool value should be true"); + rz_il_bool_free(b); + mu_end; +} + +bool test_rz_il_bool_and_ownership(void) { + RzILBool *a = rz_il_bool_new(true); + RzILBool *b = rz_il_bool_new(false); + + RzILBool *result = rz_il_bool_and(a, b); + mu_assert_notnull(result, "rz_il_bool_and should return a non-null owned pointer"); + mu_assert_eq(result->b, false, "true AND false = false"); + + // Result is a NEW allocation, distinct from inputs + mu_assert_ptrneq(result, a, "result should be a new allocation, not input a"); + mu_assert_ptrneq(result, b, "result should be a new allocation, not input b"); + + rz_il_bool_free(result); + rz_il_bool_free(a); + rz_il_bool_free(b); + mu_end; +} + +bool test_rz_il_bool_or_ownership(void) { + RzILBool *a = rz_il_bool_new(false); + RzILBool *b = rz_il_bool_new(true); + + RzILBool *result = rz_il_bool_or(a, b); + mu_assert_notnull(result, "rz_il_bool_or should return a non-null owned pointer"); + mu_assert_eq(result->b, true, "false OR true = true"); + mu_assert_ptrneq(result, a, "result should be a new allocation"); + mu_assert_ptrneq(result, b, "result should be a new allocation"); + + rz_il_bool_free(result); + rz_il_bool_free(a); + rz_il_bool_free(b); + mu_end; +} + +bool test_rz_il_bool_not_ownership(void) { + RzILBool *a = rz_il_bool_new(true); + + RzILBool *result = rz_il_bool_not(a); + mu_assert_notnull(result, "rz_il_bool_not should return a non-null owned pointer"); + mu_assert_eq(result->b, false, "NOT true = false"); + mu_assert_ptrneq(result, a, "result should be a new allocation"); + + rz_il_bool_free(result); + rz_il_bool_free(a); + mu_end; +} + +bool test_rz_il_bool_xor_ownership(void) { + RzILBool *a = rz_il_bool_new(true); + RzILBool *b = rz_il_bool_new(true); + + RzILBool *result = rz_il_bool_xor(a, b); + mu_assert_notnull(result, "rz_il_bool_xor should return a non-null owned pointer"); + mu_assert_eq(result->b, false, "true XOR true = false"); + mu_assert_ptrneq(result, a, "result should be a new allocation"); + + rz_il_bool_free(result); + rz_il_bool_free(a); + rz_il_bool_free(b); + mu_end; +} + +bool test_rz_il_mem_load_ownership(void) { + ut8 data[] = { 0x0, 0x42, 0x0, 0x0 }; + RzBuffer *buf = rz_buf_new_with_pointers(data, sizeof(data), false); + RzILMem *mem = rz_il_mem_new_owned(buf, 16); + mu_assert_notnull(mem, "Create mem"); + + RzBitVector *addr = rz_bv_new_from_ut64(16, 1); + RzBitVector *val = rz_il_mem_load(mem, addr); + mu_assert_notnull(val, "rz_il_mem_load should return a non-null owned pointer"); + mu_assert_eq(rz_bv_to_ut64(val), 0x42, "loaded value"); + + // val is a NEW allocation that the caller owns + rz_bv_free(val); + rz_bv_free(addr); + rz_il_mem_free(mem); + mu_end; +} + +bool test_rz_il_mem_loadw_ownership(void) { + ut8 data[] = { 0x0, 0x13, 0x37, 0x0 }; + RzBuffer *buf = rz_buf_new_with_pointers(data, sizeof(data), false); + RzILMem *mem = rz_il_mem_new_owned(buf, 16); + mu_assert_notnull(mem, "Create mem"); + + RzBitVector *addr = rz_bv_new_from_ut64(16, 1); + RzBitVector *val = rz_il_mem_loadw(mem, addr, 16, true); + mu_assert_notnull(val, "rz_il_mem_loadw should return a non-null owned pointer"); + mu_assert_eq(rz_bv_len(val), 16, "loadw size"); + mu_assert_eq(rz_bv_to_ut64(val), 0x1337, "loadw val (big endian)"); + + rz_bv_free(val); + rz_bv_free(addr); + rz_il_mem_free(mem); + mu_end; +} + +bool test_rz_il_op_pure_dup_ownership(void) { + RzILOpPure *op = rz_il_op_new_bitv_from_ut64(32, 0xdeadbeef); + mu_assert_notnull(op, "original op"); + + RzILOpPure *dup = rz_il_op_pure_dup(op); + mu_assert_notnull(dup, "rz_il_op_pure_dup should return a non-null owned pointer"); + mu_assert_ptrneq(dup, op, "dup should be a distinct allocation from original"); + + rz_il_op_pure_free(dup); + rz_il_op_pure_free(op); + mu_end; +} + +bool test_rz_il_effect_label_dup_ownership(void) { + RzILEffectLabel *lbl = rz_il_effect_label_new("test_label", RZ_IL_EFFECT_LABEL_SYSCALL); + mu_assert_notnull(lbl, "original label"); + + RzILEffectLabel *dup = rz_il_effect_label_dup(lbl); + mu_assert_notnull(dup, "rz_il_effect_label_dup should return a non-null owned pointer"); + mu_assert_ptrneq(dup, lbl, "dup should be a distinct allocation from original"); + mu_assert_streq(dup->label_id, lbl->label_id, "dup should have same label"); + mu_assert_eq(dup->type, lbl->type, "dup should have same type"); + + rz_il_effect_label_free(dup); + rz_il_effect_label_free(lbl); + mu_end; +} + +bool test_rz_bv_cast_ownership(void) { + RzBitVector *bv = rz_bv_new_from_ut64(16, 0x1234); + mu_assert_notnull(bv, "original bv"); + + RzBitVector *cast = rz_bv_cast(bv, 32, false); + mu_assert_notnull(cast, "rz_bv_cast should return a non-null owned pointer"); + mu_assert_ptrneq(cast, bv, "cast should be a distinct allocation from original"); + mu_assert_eq(rz_bv_len(cast), 32, "cast should have new size"); + mu_assert_eq(rz_bv_to_ut64(cast), 0x1234, "cast value should be preserved"); + + rz_bv_free(cast); + rz_bv_free(bv); + mu_end; +} + +// ==================== RZ_BORROW tests ==================== +// These tests verify that _get functions return internal pointers +// that the caller must NOT free. + +bool test_rz_strbuf_get_borrow(void) { + RzStrBuf sb; + rz_strbuf_init(&sb); + rz_strbuf_set(&sb, "hello world"); + + // rz_strbuf_get returns a BORROWED pointer to internal data + char *ptr = rz_strbuf_get(&sb); + mu_assert_notnull(ptr, "rz_strbuf_get should return non-null"); + mu_assert_streq(ptr, "hello world", "rz_strbuf_get content"); + + // Modifying the strbuf should be reflected in the borrowed pointer + // (it may point to a different address after set, but that's fine) + rz_strbuf_set(&sb, "changed"); + char *ptr2 = rz_strbuf_get(&sb); + mu_assert_streq(ptr2, "changed", "borrowed pointer reflects changes"); + + // Do NOT free ptr — it's borrowed + rz_strbuf_fini(&sb); + mu_end; +} + +bool test_rz_strbuf_getbin_borrow(void) { + RzStrBuf sb; + rz_strbuf_init(&sb); + rz_strbuf_setbin(&sb, (const ut8 *)"\x01\x02\x03\x04", 4); + + size_t len = 0; + ut8 *bin = rz_strbuf_getbin(&sb, &len); + mu_assert_notnull(bin, "rz_strbuf_getbin should return non-null"); + mu_assert_eq(len, 4, "binary length"); + mu_assert_memeq(bin, (const ut8 *)"\x01\x02\x03\x04", 4, "binary content"); + + // Do NOT free bin — it's borrowed + rz_strbuf_fini(&sb); + mu_end; +} + +bool test_rz_il_validate_context_new_ownership(void) { + RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(32); + mu_assert_notnull(ctx, "rz_il_validate_global_context_new_empty should return a non-null owned pointer"); + rz_il_validate_global_context_free(ctx); + mu_end; +} + +bool all_tests() { + // RZ_OWN tests — verify functions return owned, freeable pointers + mu_run_test(test_rz_hash_new_ownership); + mu_run_test(test_rz_config_hold_new_ownership); + mu_run_test(test_rz_type_db_new_ownership); + mu_run_test(test_rz_event_new_ownership); + mu_run_test(test_rz_annotated_code_new_ownership); + mu_run_test(test_rz_search_new_ownership); + mu_run_test(test_rz_search_keyword_new_str_ownership); + mu_run_test(test_rz_search_keyword_new_hex_ownership); + mu_run_test(test_rz_il_bool_new_ownership); + mu_run_test(test_rz_il_bool_and_ownership); + mu_run_test(test_rz_il_bool_or_ownership); + mu_run_test(test_rz_il_bool_not_ownership); + mu_run_test(test_rz_il_bool_xor_ownership); + mu_run_test(test_rz_il_mem_load_ownership); + mu_run_test(test_rz_il_mem_loadw_ownership); + mu_run_test(test_rz_il_op_pure_dup_ownership); + mu_run_test(test_rz_il_effect_label_dup_ownership); + mu_run_test(test_rz_bv_cast_ownership); + mu_run_test(test_rz_il_validate_context_new_ownership); + + // RZ_BORROW tests — verify functions return internal pointers + mu_run_test(test_rz_strbuf_get_borrow); + mu_run_test(test_rz_strbuf_getbin_borrow); + + return tests_passed != tests_run; +} + +mu_main(all_tests) From c4458e334740032d64be66bedcc084f7c22a53f8 Mon Sep 17 00:00:00 2001 From: Rama542 Date: Mon, 9 Mar 2026 09:35:48 +0530 Subject: [PATCH 4/5] Remove accidentally committed issues.json --- issues.json | Bin 5394 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 issues.json diff --git a/issues.json b/issues.json deleted file mode 100644 index 6b1e45ef585cf4e0b31eb942aa08db84c7a11ee7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5394 zcmd6r-ER^>6vgkeiT}fdCrwl+RNDH6mBuF4)IMkvHB#)B68Q=X_QUwEtG_eDNI@F2 z$v#XrEW7iyGv}Ur?w$Gl>!Uri2j&*nkCnGrTCtJMZD?J~Y-$yI;afkqUE8*%J-MgP z%=$L70exbRiXBmwbM+aq$0!pU^PAJ^jFFvP@}F}L^;P@IbH@D}rJ8}Gen8JLtu^{3 zWjUp4@2o@Vtv&raN{27sH@i!E4;kwV<4*Zs&QUcpW|gzfDpzmur8(<=#$3kqtNQQX z`tNEky_J$G&{al+{QS9plv2Xc#jzOya57N%hcH-?ZW%bT3JjQ8b zDg?^JbO&U1*Q~PiflYjF**TYk5v#lwYtN{Wzc_mYGyC?M`(xh3)qw7hHX2nnaXgK= z=bm2~PhHa7OkVd1A1p*D$8u)eGV&R`1ly_T_T(Vp&I-i!u2F7>S2cW$C<>_`Bz(^f9u~*$HJq_nht98#|;f@b{g)wbNwy84xHJ z(}wL8;^!QM2H@3&cka$pP=^U+ie^h*Dw3=#aVin4j&JUjsaN5lT^s z#Q!N+%SYNU{uSAIn+$h|C#8d=)?GG|wL(a?z~_iebKB<{>pPfDnT0rh1NO@P9s7|b zbH&({u&tGfZLP3Y9H0x=;M0M1!K;;{NhK6FgW4-5UU{yLd|3}vQ^7E-xIBJtqqPky z#?LkgN-cvXN;$PR4w+m|xx73bb&M-46SG}3VyBQ#cks^K^Xwd*l%J056S1hqRc9>i zfF}za^{gB%BD%y^-re;Is-4~iNGl(hF_Vx(Yqv3HY~>+3t#E!vC|!`P)H_754)#&* zm!TDL77gCI{<}K;=%CAKa9;Zgp){eLx%`0DIHxnJ-NSx4E(40~w| z*(RQVwAtkx@a~eaK)|b93pCj&7s)S9$rz4(MASLQrZW(o?1|U%jZ_p{=apLNI(9k( J{p?TY{s1c)`Go)g From 17136a980ebb82590937bcfbad0c055844a6577b Mon Sep 17 00:00:00 2001 From: Rama542 Date: Mon, 9 Mar 2026 10:03:11 +0530 Subject: [PATCH 5/5] Remove test_ownership.c and issues.json per reviewer feedback --- test/unit/meson.build | 1 - test/unit/test_ownership.c | 313 ------------------------------------- 2 files changed, 314 deletions(-) delete mode 100644 test/unit/test_ownership.c diff --git a/test/unit/meson.build b/test/unit/meson.build index 078091b7be1..fd15560ed99 100644 --- a/test/unit/meson.build +++ b/test/unit/meson.build @@ -94,7 +94,6 @@ if get_option('enable_tests') 'lzma', 'mem', 'ovf', - 'ownership', 'pj', 'rbtree', 'reg', diff --git a/test/unit/test_ownership.c b/test/unit/test_ownership.c deleted file mode 100644 index 052962826fa..00000000000 --- a/test/unit/test_ownership.c +++ /dev/null @@ -1,313 +0,0 @@ -// SPDX-FileCopyrightText: 2024 rizinorg -// SPDX-License-Identifier: LGPL-3.0-only - -/** - * Tests to verify pointer ownership semantics for functions annotated - * with RZ_OWN and RZ_BORROW (issue #5870). - * - * RZ_OWN functions must return newly allocated memory that the caller can free. - * RZ_BORROW functions must return pointers to existing internal data. - */ - -#include -#include -#include -#include -#include -#include -#include -#include "minunit.h" - -// ==================== RZ_OWN tests ==================== -// These tests verify that _new/_dup/_cast functions return -// owned pointers that the caller is responsible for freeing. - -bool test_rz_hash_new_ownership(void) { - RzHash *rh = rz_hash_new(); - mu_assert_notnull(rh, "rz_hash_new should return a non-null owned pointer"); - rz_hash_free(rh); - mu_end; -} - -bool test_rz_config_hold_new_ownership(void) { - RzConfig *cfg = rz_config_new(NULL); - mu_assert_notnull(cfg, "rz_config_new should return non-null"); - - RzConfigHold *hold = rz_config_hold_new(cfg); - mu_assert_notnull(hold, "rz_config_hold_new should return a non-null owned pointer"); - rz_config_hold_free(hold); - - rz_config_free(cfg); - mu_end; -} - -bool test_rz_type_db_new_ownership(void) { - RzTypeDB *typedb = rz_type_db_new(); - mu_assert_notnull(typedb, "rz_type_db_new should return a non-null owned pointer"); - rz_type_db_free(typedb); - mu_end; -} - -bool test_rz_event_new_ownership(void) { - RzEvent *ev = rz_event_new(NULL); - mu_assert_notnull(ev, "rz_event_new should return a non-null owned pointer"); - rz_event_free(ev); - mu_end; -} - -bool test_rz_annotated_code_new_ownership(void) { - char *code = strdup("int main() { return 0; }"); - RzAnnotatedCode *ac = rz_annotated_code_new(code); - mu_assert_notnull(ac, "rz_annotated_code_new should return a non-null owned pointer"); - rz_annotated_code_free(ac); - mu_end; -} - -bool test_rz_search_new_ownership(void) { - RzSearch *s = rz_search_new(RZ_SEARCH_KEYWORD); - mu_assert_notnull(s, "rz_search_new should return a non-null owned pointer"); - rz_search_free(s); - mu_end; -} - -bool test_rz_search_keyword_new_str_ownership(void) { - RzSearchKeyword *kw = rz_search_keyword_new_str("hello", NULL, NULL, 0); - mu_assert_notnull(kw, "rz_search_keyword_new_str should return a non-null owned pointer"); - rz_search_keyword_free(kw); - mu_end; -} - -bool test_rz_search_keyword_new_hex_ownership(void) { - RzSearchKeyword *kw = rz_search_keyword_new_hex("deadbeef", NULL, NULL); - mu_assert_notnull(kw, "rz_search_keyword_new_hex should return a non-null owned pointer"); - rz_search_keyword_free(kw); - mu_end; -} - -bool test_rz_il_bool_new_ownership(void) { - RzILBool *b = rz_il_bool_new(true); - mu_assert_notnull(b, "rz_il_bool_new should return a non-null owned pointer"); - mu_assert_eq(b->b, true, "bool value should be true"); - rz_il_bool_free(b); - mu_end; -} - -bool test_rz_il_bool_and_ownership(void) { - RzILBool *a = rz_il_bool_new(true); - RzILBool *b = rz_il_bool_new(false); - - RzILBool *result = rz_il_bool_and(a, b); - mu_assert_notnull(result, "rz_il_bool_and should return a non-null owned pointer"); - mu_assert_eq(result->b, false, "true AND false = false"); - - // Result is a NEW allocation, distinct from inputs - mu_assert_ptrneq(result, a, "result should be a new allocation, not input a"); - mu_assert_ptrneq(result, b, "result should be a new allocation, not input b"); - - rz_il_bool_free(result); - rz_il_bool_free(a); - rz_il_bool_free(b); - mu_end; -} - -bool test_rz_il_bool_or_ownership(void) { - RzILBool *a = rz_il_bool_new(false); - RzILBool *b = rz_il_bool_new(true); - - RzILBool *result = rz_il_bool_or(a, b); - mu_assert_notnull(result, "rz_il_bool_or should return a non-null owned pointer"); - mu_assert_eq(result->b, true, "false OR true = true"); - mu_assert_ptrneq(result, a, "result should be a new allocation"); - mu_assert_ptrneq(result, b, "result should be a new allocation"); - - rz_il_bool_free(result); - rz_il_bool_free(a); - rz_il_bool_free(b); - mu_end; -} - -bool test_rz_il_bool_not_ownership(void) { - RzILBool *a = rz_il_bool_new(true); - - RzILBool *result = rz_il_bool_not(a); - mu_assert_notnull(result, "rz_il_bool_not should return a non-null owned pointer"); - mu_assert_eq(result->b, false, "NOT true = false"); - mu_assert_ptrneq(result, a, "result should be a new allocation"); - - rz_il_bool_free(result); - rz_il_bool_free(a); - mu_end; -} - -bool test_rz_il_bool_xor_ownership(void) { - RzILBool *a = rz_il_bool_new(true); - RzILBool *b = rz_il_bool_new(true); - - RzILBool *result = rz_il_bool_xor(a, b); - mu_assert_notnull(result, "rz_il_bool_xor should return a non-null owned pointer"); - mu_assert_eq(result->b, false, "true XOR true = false"); - mu_assert_ptrneq(result, a, "result should be a new allocation"); - - rz_il_bool_free(result); - rz_il_bool_free(a); - rz_il_bool_free(b); - mu_end; -} - -bool test_rz_il_mem_load_ownership(void) { - ut8 data[] = { 0x0, 0x42, 0x0, 0x0 }; - RzBuffer *buf = rz_buf_new_with_pointers(data, sizeof(data), false); - RzILMem *mem = rz_il_mem_new_owned(buf, 16); - mu_assert_notnull(mem, "Create mem"); - - RzBitVector *addr = rz_bv_new_from_ut64(16, 1); - RzBitVector *val = rz_il_mem_load(mem, addr); - mu_assert_notnull(val, "rz_il_mem_load should return a non-null owned pointer"); - mu_assert_eq(rz_bv_to_ut64(val), 0x42, "loaded value"); - - // val is a NEW allocation that the caller owns - rz_bv_free(val); - rz_bv_free(addr); - rz_il_mem_free(mem); - mu_end; -} - -bool test_rz_il_mem_loadw_ownership(void) { - ut8 data[] = { 0x0, 0x13, 0x37, 0x0 }; - RzBuffer *buf = rz_buf_new_with_pointers(data, sizeof(data), false); - RzILMem *mem = rz_il_mem_new_owned(buf, 16); - mu_assert_notnull(mem, "Create mem"); - - RzBitVector *addr = rz_bv_new_from_ut64(16, 1); - RzBitVector *val = rz_il_mem_loadw(mem, addr, 16, true); - mu_assert_notnull(val, "rz_il_mem_loadw should return a non-null owned pointer"); - mu_assert_eq(rz_bv_len(val), 16, "loadw size"); - mu_assert_eq(rz_bv_to_ut64(val), 0x1337, "loadw val (big endian)"); - - rz_bv_free(val); - rz_bv_free(addr); - rz_il_mem_free(mem); - mu_end; -} - -bool test_rz_il_op_pure_dup_ownership(void) { - RzILOpPure *op = rz_il_op_new_bitv_from_ut64(32, 0xdeadbeef); - mu_assert_notnull(op, "original op"); - - RzILOpPure *dup = rz_il_op_pure_dup(op); - mu_assert_notnull(dup, "rz_il_op_pure_dup should return a non-null owned pointer"); - mu_assert_ptrneq(dup, op, "dup should be a distinct allocation from original"); - - rz_il_op_pure_free(dup); - rz_il_op_pure_free(op); - mu_end; -} - -bool test_rz_il_effect_label_dup_ownership(void) { - RzILEffectLabel *lbl = rz_il_effect_label_new("test_label", RZ_IL_EFFECT_LABEL_SYSCALL); - mu_assert_notnull(lbl, "original label"); - - RzILEffectLabel *dup = rz_il_effect_label_dup(lbl); - mu_assert_notnull(dup, "rz_il_effect_label_dup should return a non-null owned pointer"); - mu_assert_ptrneq(dup, lbl, "dup should be a distinct allocation from original"); - mu_assert_streq(dup->label_id, lbl->label_id, "dup should have same label"); - mu_assert_eq(dup->type, lbl->type, "dup should have same type"); - - rz_il_effect_label_free(dup); - rz_il_effect_label_free(lbl); - mu_end; -} - -bool test_rz_bv_cast_ownership(void) { - RzBitVector *bv = rz_bv_new_from_ut64(16, 0x1234); - mu_assert_notnull(bv, "original bv"); - - RzBitVector *cast = rz_bv_cast(bv, 32, false); - mu_assert_notnull(cast, "rz_bv_cast should return a non-null owned pointer"); - mu_assert_ptrneq(cast, bv, "cast should be a distinct allocation from original"); - mu_assert_eq(rz_bv_len(cast), 32, "cast should have new size"); - mu_assert_eq(rz_bv_to_ut64(cast), 0x1234, "cast value should be preserved"); - - rz_bv_free(cast); - rz_bv_free(bv); - mu_end; -} - -// ==================== RZ_BORROW tests ==================== -// These tests verify that _get functions return internal pointers -// that the caller must NOT free. - -bool test_rz_strbuf_get_borrow(void) { - RzStrBuf sb; - rz_strbuf_init(&sb); - rz_strbuf_set(&sb, "hello world"); - - // rz_strbuf_get returns a BORROWED pointer to internal data - char *ptr = rz_strbuf_get(&sb); - mu_assert_notnull(ptr, "rz_strbuf_get should return non-null"); - mu_assert_streq(ptr, "hello world", "rz_strbuf_get content"); - - // Modifying the strbuf should be reflected in the borrowed pointer - // (it may point to a different address after set, but that's fine) - rz_strbuf_set(&sb, "changed"); - char *ptr2 = rz_strbuf_get(&sb); - mu_assert_streq(ptr2, "changed", "borrowed pointer reflects changes"); - - // Do NOT free ptr — it's borrowed - rz_strbuf_fini(&sb); - mu_end; -} - -bool test_rz_strbuf_getbin_borrow(void) { - RzStrBuf sb; - rz_strbuf_init(&sb); - rz_strbuf_setbin(&sb, (const ut8 *)"\x01\x02\x03\x04", 4); - - size_t len = 0; - ut8 *bin = rz_strbuf_getbin(&sb, &len); - mu_assert_notnull(bin, "rz_strbuf_getbin should return non-null"); - mu_assert_eq(len, 4, "binary length"); - mu_assert_memeq(bin, (const ut8 *)"\x01\x02\x03\x04", 4, "binary content"); - - // Do NOT free bin — it's borrowed - rz_strbuf_fini(&sb); - mu_end; -} - -bool test_rz_il_validate_context_new_ownership(void) { - RzILValidateGlobalContext *ctx = rz_il_validate_global_context_new_empty(32); - mu_assert_notnull(ctx, "rz_il_validate_global_context_new_empty should return a non-null owned pointer"); - rz_il_validate_global_context_free(ctx); - mu_end; -} - -bool all_tests() { - // RZ_OWN tests — verify functions return owned, freeable pointers - mu_run_test(test_rz_hash_new_ownership); - mu_run_test(test_rz_config_hold_new_ownership); - mu_run_test(test_rz_type_db_new_ownership); - mu_run_test(test_rz_event_new_ownership); - mu_run_test(test_rz_annotated_code_new_ownership); - mu_run_test(test_rz_search_new_ownership); - mu_run_test(test_rz_search_keyword_new_str_ownership); - mu_run_test(test_rz_search_keyword_new_hex_ownership); - mu_run_test(test_rz_il_bool_new_ownership); - mu_run_test(test_rz_il_bool_and_ownership); - mu_run_test(test_rz_il_bool_or_ownership); - mu_run_test(test_rz_il_bool_not_ownership); - mu_run_test(test_rz_il_bool_xor_ownership); - mu_run_test(test_rz_il_mem_load_ownership); - mu_run_test(test_rz_il_mem_loadw_ownership); - mu_run_test(test_rz_il_op_pure_dup_ownership); - mu_run_test(test_rz_il_effect_label_dup_ownership); - mu_run_test(test_rz_bv_cast_ownership); - mu_run_test(test_rz_il_validate_context_new_ownership); - - // RZ_BORROW tests — verify functions return internal pointers - mu_run_test(test_rz_strbuf_get_borrow); - mu_run_test(test_rz_strbuf_getbin_borrow); - - return tests_passed != tests_run; -} - -mu_main(all_tests)