Repository navigation
feat(core/oid): migrate edge/cache to gm helpers #173
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
Changes from all commits
16a9de9
b97f366
7445bcf
ebd9f75
17ddad1
eaf10c6
e024305
28cf980
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |||||||||||||||||||||||||||||||||||||
| #include "gitmind/types.h" | ||||||||||||||||||||||||||||||||||||||
| #include "gitmind/attribution.h" | ||||||||||||||||||||||||||||||||||||||
| #include "gitmind/util/memory.h" | ||||||||||||||||||||||||||||||||||||||
| #include "gitmind/util/oid.h" | ||||||||||||||||||||||||||||||||||||||
| #include "gitmind/edge/internal/blob_identity.h" | ||||||||||||||||||||||||||||||||||||||
| #include <stdint.h> | ||||||||||||||||||||||||||||||||||||||
| #include "gitmind/security/memory.h" | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -237,11 +238,25 @@ static int decode_attr_ex_impl(const uint8_t *buffer, size_t len, | |||||||||||||||||||||||||||||||||||||
| gm_result_void_t rr = gm_cbor_read_text(buffer, &offset, len, out.ulid, GM_ULID_SIZE + 1); | ||||||||||||||||||||||||||||||||||||||
| if (!rr.ok) return GM_ERR_INVALID_FORMAT; break; } | ||||||||||||||||||||||||||||||||||||||
| case GM_CBOR_KEY_SRC_OID: { | ||||||||||||||||||||||||||||||||||||||
| uint8_t raw[GM_OID_RAWSZ]; gm_result_void_t rr = gm_cbor_read_bytes(buffer, &offset, len, raw, GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||
| if (!rr.ok) return GM_ERR_INVALID_FORMAT; git_oid_fromraw(&out.src_oid, raw); break; } | ||||||||||||||||||||||||||||||||||||||
| uint8_t raw[GM_OID_RAWSZ]; | ||||||||||||||||||||||||||||||||||||||
| gm_result_void_t rr = | ||||||||||||||||||||||||||||||||||||||
| gm_cbor_read_bytes(buffer, &offset, len, raw, GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||
| if (!rr.ok) return GM_ERR_INVALID_FORMAT; | ||||||||||||||||||||||||||||||||||||||
| if (gm_oid_from_raw(&out.src_oid, raw, GM_OID_RAWSZ) != GM_OK) { | ||||||||||||||||||||||||||||||||||||||
| return GM_ERR_INVALID_FORMAT; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| case GM_CBOR_KEY_TGT_OID: { | ||||||||||||||||||||||||||||||||||||||
| uint8_t raw[GM_OID_RAWSZ]; gm_result_void_t rr = gm_cbor_read_bytes(buffer, &offset, len, raw, GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||
| if (!rr.ok) return GM_ERR_INVALID_FORMAT; git_oid_fromraw(&out.tgt_oid, raw); break; } | ||||||||||||||||||||||||||||||||||||||
| uint8_t raw[GM_OID_RAWSZ]; | ||||||||||||||||||||||||||||||||||||||
| gm_result_void_t rr = | ||||||||||||||||||||||||||||||||||||||
| gm_cbor_read_bytes(buffer, &offset, len, raw, GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||
| if (!rr.ok) return GM_ERR_INVALID_FORMAT; | ||||||||||||||||||||||||||||||||||||||
| if (gm_oid_from_raw(&out.tgt_oid, raw, GM_OID_RAWSZ) != GM_OK) { | ||||||||||||||||||||||||||||||||||||||
| return GM_ERR_INVALID_FORMAT; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| case GM_CBOR_KEY_SOURCE_TYPE: { | ||||||||||||||||||||||||||||||||||||||
| gm_result_uint64_t rr = gm_cbor_read_uint(buffer, &offset, len); | ||||||||||||||||||||||||||||||||||||||
| if (!rr.ok) return GM_ERR_INVALID_FORMAT; out.attribution.source_type = (gm_source_type_t)rr.u.val; break; } | ||||||||||||||||||||||||||||||||||||||
|
|
@@ -262,8 +277,12 @@ static int decode_attr_ex_impl(const uint8_t *buffer, size_t len, | |||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| if (git_oid_is_zero(&out.src_oid)) git_oid_fromraw(&out.src_oid, out.src_sha); | ||||||||||||||||||||||||||||||||||||||
| if (git_oid_is_zero(&out.tgt_oid)) git_oid_fromraw(&out.tgt_oid, out.tgt_sha); | ||||||||||||||||||||||||||||||||||||||
| if (gm_oid_is_zero(&out.src_oid)) { | ||||||||||||||||||||||||||||||||||||||
| (void)gm_oid_from_raw(&out.src_oid, out.src_sha, GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
| if (gm_oid_is_zero(&out.tgt_oid)) { | ||||||||||||||||||||||||||||||||||||||
| (void)gm_oid_from_raw(&out.tgt_oid, out.tgt_sha, GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+280
to
+285
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix OID backfill length mismatch (potential OOB read) You pass GM_OID_RAWSZ while sourcing from out.src_sha/out.tgt_sha (GM_SHA1_SIZE). That can read past the SHA buffer or fail. Zero‑pad into a GM_OID_RAWSZ scratch first. - if (gm_oid_is_zero(&out.src_oid)) {
- (void)gm_oid_from_raw(&out.src_oid, out.src_sha, GM_OID_RAWSZ);
- }
- if (gm_oid_is_zero(&out.tgt_oid)) {
- (void)gm_oid_from_raw(&out.tgt_oid, out.tgt_sha, GM_OID_RAWSZ);
- }
+ if (gm_oid_is_zero(&out.src_oid)) {
+ uint8_t tmp[GM_OID_RAWSZ];
+ gm_memset_safe(tmp, sizeof tmp, 0, sizeof tmp);
+ gm_memcpy_span(tmp, sizeof tmp, out.src_sha, GM_SHA1_SIZE);
+ (void)gm_oid_from_raw(&out.src_oid, tmp, GM_OID_RAWSZ);
+ }
+ if (gm_oid_is_zero(&out.tgt_oid)) {
+ uint8_t tmp[GM_OID_RAWSZ];
+ gm_memset_safe(tmp, sizeof tmp, 0, sizeof tmp);
+ gm_memcpy_span(tmp, sizeof tmp, out.tgt_sha, GM_SHA1_SIZE);
+ (void)gm_oid_from_raw(&out.tgt_oid, tmp, GM_OID_RAWSZ);
+ }As per coding guidelines (zero outputs on error paths; use gm_memcpy_span). Based on learnings. 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| *e = out; *consumed = offset; return GM_OK; | ||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,6 +13,7 @@ | |||||||||||||||||||||||||||||||||||||||||
| #include "gitmind/security/string.h" | ||||||||||||||||||||||||||||||||||||||||||
| #include "gitmind/security/memory.h" | ||||||||||||||||||||||||||||||||||||||||||
| #include "gitmind/util/memory.h" | ||||||||||||||||||||||||||||||||||||||||||
| #include "gitmind/util/oid.h" | ||||||||||||||||||||||||||||||||||||||||||
| #include "gitmind/cbor/keys.h" | ||||||||||||||||||||||||||||||||||||||||||
| #include <stdint.h> | ||||||||||||||||||||||||||||||||||||||||||
| #include <string.h> | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -114,8 +115,8 @@ bool gm_edge_equal(const gm_edge_t *edge_a, const gm_edge_t *edge_b) { | |||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /* Source: if both OIDs present, they must match; otherwise fallback to legacy SHA */ | ||||||||||||||||||||||||||||||||||||||||||
| if (!git_oid_is_zero(&edge_a->src_oid) && !git_oid_is_zero(&edge_b->src_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| if (git_oid_cmp(&edge_a->src_oid, &edge_b->src_oid) != 0) { | ||||||||||||||||||||||||||||||||||||||||||
| if (!gm_oid_is_zero(&edge_a->src_oid) && !gm_oid_is_zero(&edge_b->src_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| if (!gm_oid_equal(&edge_a->src_oid, &edge_b->src_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -125,8 +126,8 @@ bool gm_edge_equal(const gm_edge_t *edge_a, const gm_edge_t *edge_b) { | |||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /* Target: same rule as Source */ | ||||||||||||||||||||||||||||||||||||||||||
| if (!git_oid_is_zero(&edge_a->tgt_oid) && !git_oid_is_zero(&edge_b->tgt_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| if (git_oid_cmp(&edge_a->tgt_oid, &edge_b->tgt_oid) != 0) { | ||||||||||||||||||||||||||||||||||||||||||
| if (!gm_oid_is_zero(&edge_a->tgt_oid) && !gm_oid_is_zero(&edge_b->tgt_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| if (!gm_oid_equal(&edge_a->tgt_oid, &edge_b->tgt_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| return false; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -318,7 +319,7 @@ gm_result_void_t gm_edge_encode_cbor(const gm_edge_t *edge, uint8_t *buffer, | |||||||||||||||||||||||||||||||||||||||||
| uint8_t src_oid_bytes[GM_OID_RAWSZ] = {0}; | ||||||||||||||||||||||||||||||||||||||||||
| uint8_t tgt_oid_bytes[GM_OID_RAWSZ] = {0}; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (!git_oid_is_zero(&edge->src_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| if (!gm_oid_is_zero(&edge->src_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| (void)gm_memcpy_span(src_oid_bytes, sizeof(src_oid_bytes), edge->src_oid.id, | ||||||||||||||||||||||||||||||||||||||||||
| GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -331,7 +332,7 @@ gm_result_void_t gm_edge_encode_cbor(const gm_edge_t *edge, uint8_t *buffer, | |||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (!git_oid_is_zero(&edge->tgt_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| if (!gm_oid_is_zero(&edge->tgt_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| (void)gm_memcpy_span(tgt_oid_bytes, sizeof(tgt_oid_bytes), edge->tgt_oid.id, | ||||||||||||||||||||||||||||||||||||||||||
| GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -436,14 +437,20 @@ static gm_result_void_t decode_cbor_field(const uint8_t *buffer, size_t *offset, | |||||||||||||||||||||||||||||||||||||||||
| uint8_t raw[GM_OID_RAWSZ]; | ||||||||||||||||||||||||||||||||||||||||||
| gm_result_void_t r = gm_cbor_read_bytes(buffer, offset, len, raw, GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||||||
| if (!r.ok) return r; | ||||||||||||||||||||||||||||||||||||||||||
| git_oid_fromraw(&edge->src_oid, raw); | ||||||||||||||||||||||||||||||||||||||||||
| if (gm_oid_from_raw(&edge->src_oid, raw, GM_OID_RAWSZ) != GM_OK) { | ||||||||||||||||||||||||||||||||||||||||||
| return gm_err_void( | ||||||||||||||||||||||||||||||||||||||||||
| GM_ERROR(GM_ERR_INVALID_FORMAT, "Invalid source OID payload")); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| return gm_ok_void(); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| case GM_CBOR_KEY_TGT_OID: { | ||||||||||||||||||||||||||||||||||||||||||
| uint8_t raw[GM_OID_RAWSZ]; | ||||||||||||||||||||||||||||||||||||||||||
| gm_result_void_t r = gm_cbor_read_bytes(buffer, offset, len, raw, GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||||||
| if (!r.ok) return r; | ||||||||||||||||||||||||||||||||||||||||||
| git_oid_fromraw(&edge->tgt_oid, raw); | ||||||||||||||||||||||||||||||||||||||||||
| if (gm_oid_from_raw(&edge->tgt_oid, raw, GM_OID_RAWSZ) != GM_OK) { | ||||||||||||||||||||||||||||||||||||||||||
| return gm_err_void( | ||||||||||||||||||||||||||||||||||||||||||
| GM_ERROR(GM_ERR_INVALID_FORMAT, "Invalid target OID payload")); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| return gm_ok_void(); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| default: | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -482,11 +489,11 @@ static int gm_edge_decode_cbor_ex_impl(const uint8_t *buffer, size_t len, gm_edg | |||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /* Backfill OIDs from legacy SHA if missing */ | ||||||||||||||||||||||||||||||||||||||||||
| if (git_oid_is_zero(&edge.src_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| git_oid_fromraw(&edge.src_oid, edge.src_sha); | ||||||||||||||||||||||||||||||||||||||||||
| if (gm_oid_is_zero(&edge.src_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| (void)gm_oid_from_raw(&edge.src_oid, edge.src_sha, GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| if (git_oid_is_zero(&edge.tgt_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| git_oid_fromraw(&edge.tgt_oid, edge.tgt_sha); | ||||||||||||||||||||||||||||||||||||||||||
| if (gm_oid_is_zero(&edge.tgt_oid)) { | ||||||||||||||||||||||||||||||||||||||||||
| (void)gm_oid_from_raw(&edge.tgt_oid, edge.tgt_sha, GM_OID_RAWSZ); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+492
to
497
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix OID backfill length mismatch (potential OOB read) As in attributed.c, passing GM_OID_RAWSZ while sourcing from GM_SHA1_SIZE buffers risks OOB. Zero‑pad into a GM_OID_RAWSZ scratch first. - if (gm_oid_is_zero(&edge.src_oid)) {
- (void)gm_oid_from_raw(&edge.src_oid, edge.src_sha, GM_OID_RAWSZ);
- }
- if (gm_oid_is_zero(&edge.tgt_oid)) {
- (void)gm_oid_from_raw(&edge.tgt_oid, edge.tgt_sha, GM_OID_RAWSZ);
- }
+ if (gm_oid_is_zero(&edge.src_oid)) {
+ uint8_t tmp[GM_OID_RAWSZ];
+ gm_memset_safe(tmp, sizeof tmp, 0, sizeof tmp);
+ gm_memcpy_span(tmp, sizeof tmp, edge.src_sha, GM_SHA1_SIZE);
+ (void)gm_oid_from_raw(&edge.src_oid, tmp, GM_OID_RAWSZ);
+ }
+ if (gm_oid_is_zero(&edge.tgt_oid)) {
+ uint8_t tmp[GM_OID_RAWSZ];
+ gm_memset_safe(tmp, sizeof tmp, 0, sizeof tmp);
+ gm_memcpy_span(tmp, sizeof tmp, edge.tgt_sha, GM_SHA1_SIZE);
+ (void)gm_oid_from_raw(&edge.tgt_oid, tmp, GM_OID_RAWSZ);
+ }As per coding guidelines (safe memory ops; zero on error). 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| *edge_out = edge; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify umbrella exposure in include/gitmind.h.
Public headers must be umbrella‑safe and reachable via the umbrella. Please confirm this header is re‑exported.
🏁 Script executed:
Length of output: 0
🏁 Script executed:
Length of output: 42
Include util/oid.h in the umbrella header
Add the following to
include/gitmind.hso thatcore/include/gitmind/util/oid.his re-exported by the umbrella API:📝 Committable suggestion
🤖 Prompt for AI Agents