From efa5f5e1ef44ef20c96e2b6e2f4a91fbc0356d45 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 5 May 2026 08:10:46 +0200 Subject: [PATCH 1/4] feat: expose attachment types Expose attachment type setters together with well-known type constants so downstream SDKs can mark attachments such as view hierarchy payloads as "event.view_hierarchy". Co-Authored-By: OpenAI Codex --- CHANGELOG.md | 1 + include/sentry.h | 18 ++++++++++ src/backends/native/sentry_crash_daemon.c | 43 ++++++++++++++++------- src/backends/sentry_backend_breakpad.cpp | 4 +-- src/backends/sentry_backend_crashpad.cpp | 5 +-- src/backends/sentry_backend_native.c | 4 +++ src/sentry_attachment.c | 38 ++++++++++++++++---- src/sentry_attachment.h | 15 ++------ src/sentry_core.c | 6 ++-- src/sentry_database.c | 2 +- src/sentry_envelope.c | 31 ++++------------ src/sentry_envelope.h | 2 +- src/sentry_hint.c | 8 ++--- src/sentry_options.c | 15 ++++---- src/sentry_scope.c | 8 ++--- tests/unit/test_attachments.c | 18 +++++----- tests/unit/test_envelopes.c | 9 +++-- 17 files changed, 134 insertions(+), 93 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b85251c3a6..11c65859f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ **Features**: - Auto-populate `event.user.id` with a persistent per-installation UUID when no explicit user ID is set. ([#1661](https://github.com/getsentry/sentry-native/pull/1661)) +- Add `sentry_attachment_set_type` and `SENTRY_ATTACHMENT_TYPE_*` for common envelope attachment types. ([#TODO](https://github.com/getsentry/sentry-native/pull/TODO)) ## 0.14.0 diff --git a/include/sentry.h b/include/sentry.h index 210381223a..e24229d77e 100644 --- a/include/sentry.h +++ b/include/sentry.h @@ -2719,6 +2719,24 @@ SENTRY_API sentry_attachment_t *sentry_scope_attach_bytesw_n( const wchar_t *filename, size_t filename_len); #endif +#define SENTRY_ATTACHMENT_TYPE_GENERIC "event.attachment" +#define SENTRY_ATTACHMENT_TYPE_MINIDUMP "event.minidump" +#define SENTRY_ATTACHMENT_TYPE_VIEW_HIERARCHY "event.view_hierarchy" + +/** + * Sets the attachment type. + * + * Well-known attachment types are exposed as `SENTRY_ATTACHMENT_TYPE_*` + * macros. Pass `NULL` or an empty string to clear the attachment type. + * + * See: + * https://develop.sentry.dev/sdk/telemetry/attachments/#attachment-types + */ +SENTRY_API void sentry_attachment_set_type( + sentry_attachment_t *attachment, const char *type); +SENTRY_API void sentry_attachment_set_type_n( + sentry_attachment_t *attachment, const char *type, size_t type_len); + /** * Sets the content type of attachment. */ diff --git a/src/backends/native/sentry_crash_daemon.c b/src/backends/native/sentry_crash_daemon.c index a2cf4df71b..ad36ee1ebc 100644 --- a/src/backends/native/sentry_crash_daemon.c +++ b/src/backends/native/sentry_crash_daemon.c @@ -78,7 +78,7 @@ __asan_default_options(void) */ static bool write_attachment_to_envelope(int fd, const char *file_path, - const char *filename, const char *content_type) + const char *filename, const char *attachment_type, const char *content_type) { #if defined(SENTRY_PLATFORM_UNIX) int attach_fd = open(file_path, O_RDONLY); @@ -117,16 +117,20 @@ write_attachment_to_envelope(int fd, const char *file_path, if (content_type) { header_written = snprintf(header, sizeof(header), "{\"type\":\"attachment\",\"length\":%lld," - "\"attachment_type\":\"event.attachment\"," + "\"attachment_type\":\"%s\"," "\"content_type\":\"%s\"," "\"filename\":\"%s\"}\n", - file_size, content_type, filename ? filename : "attachment"); + file_size, + attachment_type ? attachment_type : SENTRY_ATTACHMENT_TYPE_GENERIC, + content_type, filename ? filename : "attachment"); } else { header_written = snprintf(header, sizeof(header), "{\"type\":\"attachment\",\"length\":%lld," - "\"attachment_type\":\"event.attachment\"," + "\"attachment_type\":\"%s\"," "\"filename\":\"%s\"}\n", - file_size, filename ? filename : "attachment"); + file_size, + attachment_type ? attachment_type : SENTRY_ATTACHMENT_TYPE_GENERIC, + filename ? filename : "attachment"); } if (header_written < 0 || header_written >= (int)sizeof(header)) { @@ -203,7 +207,6 @@ attachment_is_placeholder(const sentry_options_t *options, const char *path) if (!attachment.path) { return false; } - attachment.type = ATTACHMENT; bool is_placeholder = sentry__attachment_is_placeholder(&attachment, options); sentry__path_free(attachment.path); @@ -251,6 +254,8 @@ add_attachment_refs(sentry_envelope_t *envelope, = sentry_value_as_string(sentry_value_get_by_key(info, "path")); const char *filename = sentry_value_as_string(sentry_value_get_by_key(info, "filename")); + const char *attachment_type = sentry_value_as_string( + sentry_value_get_by_key(info, "attachment_type")); const char *content_type = sentry_value_as_string( sentry_value_get_by_key(info, "content_type")); if (!path || !*path || !filename || !*filename) { @@ -266,7 +271,9 @@ add_attachment_refs(sentry_envelope_t *envelope, sentry__path_free(attachment.filename); continue; } - attachment.type = ATTACHMENT; + attachment.type + = (char *)((attachment_type && *attachment_type) ? attachment_type + : NULL); attachment.content_type = (char *)((content_type && *content_type) ? content_type : NULL); if (!sentry__attachment_is_placeholder(&attachment, options)) { @@ -2471,6 +2478,9 @@ write_envelope_with_native_stacktrace(const sentry_options_t *options, = sentry_value_get_by_key(attach_info, "path"); sentry_value_t filename_val = sentry_value_get_by_key(attach_info, "filename"); + sentry_value_t attachment_type_val + = sentry_value_get_by_key( + attach_info, "attachment_type"); sentry_value_t content_type_val = sentry_value_get_by_key( attach_info, "content_type"); @@ -2478,13 +2488,15 @@ write_envelope_with_native_stacktrace(const sentry_options_t *options, const char *path = sentry_value_as_string(path_val); const char *filename = sentry_value_as_string(filename_val); + const char *attachment_type + = sentry_value_as_string(attachment_type_val); const char *content_type = sentry_value_as_string(content_type_val); if (path && filename && !attachment_is_placeholder(options, path)) { - write_attachment_to_envelope( - fd, path, filename, content_type); + write_attachment_to_envelope(fd, path, filename, + attachment_type, content_type); } } sentry_value_decref(attach_list); @@ -2499,7 +2511,7 @@ write_envelope_with_native_stacktrace(const sentry_options_t *options, = sentry__path_join_str(run_folder, "screenshot.png"); if (screenshot_path) { write_attachment_to_envelope( - fd, screenshot_path->path, "screenshot.png", "image/png"); + fd, screenshot_path->path, "screenshot.png", NULL, "image/png"); sentry__path_free(screenshot_path); } } @@ -2707,6 +2719,9 @@ write_envelope_with_minidump(const sentry_options_t *options, = sentry_value_get_by_key(attach_info, "path"); sentry_value_t filename_val = sentry_value_get_by_key(attach_info, "filename"); + sentry_value_t attachment_type_val + = sentry_value_get_by_key( + attach_info, "attachment_type"); sentry_value_t content_type_val = sentry_value_get_by_key( attach_info, "content_type"); @@ -2714,13 +2729,15 @@ write_envelope_with_minidump(const sentry_options_t *options, const char *path = sentry_value_as_string(path_val); const char *filename = sentry_value_as_string(filename_val); + const char *attachment_type + = sentry_value_as_string(attachment_type_val); const char *content_type = sentry_value_as_string(content_type_val); if (path && filename && !attachment_is_placeholder(options, path)) { - write_attachment_to_envelope( - fd, path, filename, content_type); + write_attachment_to_envelope(fd, path, filename, + attachment_type, content_type); } } sentry_value_decref(attach_list); @@ -2735,7 +2752,7 @@ write_envelope_with_minidump(const sentry_options_t *options, = sentry__path_join_str(run_folder, "screenshot.png"); if (screenshot_path) { write_attachment_to_envelope( - fd, screenshot_path->path, "screenshot.png", "image/png"); + fd, screenshot_path->path, "screenshot.png", NULL, "image/png"); sentry__path_free(screenshot_path); } } diff --git a/src/backends/sentry_backend_breakpad.cpp b/src/backends/sentry_backend_breakpad.cpp index 3f0f4cdea5..a8db4c332f 100644 --- a/src/backends/sentry_backend_breakpad.cpp +++ b/src/backends/sentry_backend_breakpad.cpp @@ -186,14 +186,14 @@ breakpad_backend_callback(const google_breakpad::MinidumpDescriptor &descriptor, envelope, dump_path, "attachment"); if (item) { sentry__envelope_item_set_header(item, "attachment_type", - sentry_value_new_string("event.minidump")); + sentry_value_new_string(SENTRY_ATTACHMENT_TYPE_MINIDUMP)); sentry__envelope_item_set_header(item, "filename", sentry_value_new_string(sentry__path_filename(dump_path))); } else if (options->enable_large_attachments) { sentry_attachment_t tmp = {}; tmp.path = dump_path; - tmp.type = MINIDUMP; + tmp.type = SENTRY_ATTACHMENT_TYPE_MINIDUMP; if (!sentry__cache_attachment_ref( envelope, &tmp, options->run->cache_path, nullptr)) { SENTRY_SIGNAL_SAFE_LOG( diff --git a/src/backends/sentry_backend_crashpad.cpp b/src/backends/sentry_backend_crashpad.cpp index efa36c6711..300c7936f3 100644 --- a/src/backends/sentry_backend_crashpad.cpp +++ b/src/backends/sentry_backend_crashpad.cpp @@ -518,7 +518,7 @@ report_to_envelope(const crashpad::CrashReportDatabase::Report &report, breadcrumbs2 = read_msgpack_file(path); } else { sentry__attachments_add_path(&attachments, - sentry__path_clone(path), ATTACHMENT, nullptr); + sentry__path_clone(path), nullptr, nullptr); } } sentry__pathiter_free(iter); @@ -538,7 +538,8 @@ report_to_envelope(const crashpad::CrashReportDatabase::Report &report, sentry__value_merge_breadcrumbs( breadcrumbs1, breadcrumbs2, options->max_breadcrumbs)); sentry__attachments_add_path( - &attachments, minidump_path, MINIDUMP, nullptr); + &attachments, minidump_path, SENTRY_ATTACHMENT_TYPE_MINIDUMP, + nullptr); if (sentry__envelope_add_event(envelope, event)) { sentry__envelope_add_attachments(envelope, attachments, options); diff --git a/src/backends/sentry_backend_native.c b/src/backends/sentry_backend_native.c index d9bbcf038a..39488d875d 100644 --- a/src/backends/sentry_backend_native.c +++ b/src/backends/sentry_backend_native.c @@ -618,6 +618,10 @@ native_backend_write_attachments(const sentry_path_t *event_path) it->filename ? it->filename : it->path); sentry_value_set_by_key( attach_info, "filename", sentry_value_new_string(filename)); + if (it->type && *it->type) { + sentry_value_set_by_key(attach_info, "attachment_type", + sentry_value_new_string(it->type)); + } if (it->content_type) { sentry_value_set_by_key(attach_info, "content_type", sentry_value_new_string(it->content_type)); diff --git a/src/sentry_attachment.c b/src/sentry_attachment.c index 3537d9cf3b..37741c7827 100644 --- a/src/sentry_attachment.c +++ b/src/sentry_attachment.c @@ -7,6 +7,26 @@ #include +void +sentry_attachment_set_type(sentry_attachment_t *attachment, const char *type) +{ + sentry_attachment_set_type_n( + attachment, type, sentry__guarded_strlen(type)); +} + +void +sentry_attachment_set_type_n( + sentry_attachment_t *attachment, const char *type, size_t type_len) +{ + if (!attachment) { + return; + } + + sentry_free(attachment->type); + attachment->type + = type && type_len > 0 ? sentry__string_clone_n(type, type_len) : NULL; +} + void sentry_attachment_set_content_type( sentry_attachment_t *attachment, const char *content_type) @@ -117,6 +137,7 @@ sentry__attachment_free(sentry_attachment_t *attachment) sentry__path_free(attachment->path); sentry__path_free(attachment->filename); sentry_free(attachment->buf); + sentry_free(attachment->type); sentry_free(attachment->content_type); sentry_free(attachment); } @@ -141,7 +162,6 @@ sentry__attachment_is_placeholder( const sentry_attachment_t *att, const sentry_options_t *options) { return options && options->enable_large_attachments && att - && att->type == ATTACHMENT && sentry__attachment_get_size(att) >= SENTRY_LARGE_ATTACHMENT_SIZE; } @@ -170,7 +190,12 @@ attachment_eq(const sentry_attachment_t *a, const sentry_attachment_t *b) if (a == b) { return true; } - if (!a || !b || a->buf || b->buf || a->type != b->type) { + if (!a || !b || a->buf || b->buf) { + return false; + } + const char *a_type = a->type ? a->type : ""; + const char *b_type = b->type ? b->type : ""; + if (!sentry__string_eq(a_type, b_type)) { return false; } return sentry__path_eq(a->path, b->path); @@ -178,7 +203,7 @@ attachment_eq(const sentry_attachment_t *a, const sentry_attachment_t *b) sentry_attachment_t * sentry__attachments_add(sentry_attachment_t **attachments_ptr, - sentry_attachment_t *attachment, sentry_attachment_type_t attachment_type, + sentry_attachment_t *attachment, const char *attachment_type, const char *content_type) { if (!attachment) { @@ -196,8 +221,8 @@ sentry__attachments_add(sentry_attachment_t **attachments_ptr, SENTRY_INFOF("added large attachment \"%s\" (%zu MiB)", sentry__attachment_get_filename(attachment), size / (1024 * 1024)); } - attachment->type = attachment_type; - attachment->content_type = sentry__string_clone(content_type); + sentry_attachment_set_type(attachment, attachment_type); + sentry_attachment_set_content_type(attachment, content_type); sentry_attachment_t **next_ptr = attachments_ptr; @@ -216,8 +241,7 @@ sentry__attachments_add(sentry_attachment_t **attachments_ptr, sentry_attachment_t * sentry__attachments_add_path(sentry_attachment_t **attachments_ptr, - sentry_path_t *path, sentry_attachment_type_t attachment_type, - const char *content_type) + sentry_path_t *path, const char *attachment_type, const char *content_type) { sentry_attachment_t *attachment = sentry__attachment_from_path(path); return sentry__attachments_add( diff --git a/src/sentry_attachment.h b/src/sentry_attachment.h index 306ff66def..8a77eda994 100644 --- a/src/sentry_attachment.h +++ b/src/sentry_attachment.h @@ -8,15 +8,6 @@ #define SENTRY_LARGE_ATTACHMENT_SIZE (100 * 1024 * 1024) // 100 MiB #define SENTRY_MAX_ATTACHMENT_SIZE (1024 * 1024 * 1024) // 1 GiB -/** - * The attachment_type. - */ -typedef enum { - ATTACHMENT, - MINIDUMP, - VIEW_HIERARCHY, -} sentry_attachment_type_t; - /** * This is a linked list of all the attachments registered via * `sentry_options_add_attachment`. @@ -38,7 +29,7 @@ struct sentry_attachment_s { // Common fields for both attachment types sentry_path_t *filename; // Attachment name in envelope (can be NULL) - sentry_attachment_type_t type; + char *type; char *content_type; sentry_attachment_t *next; // Linked list pointer }; @@ -89,14 +80,14 @@ void sentry__attachments_free(sentry_attachment_t *attachments); */ sentry_attachment_t *sentry__attachments_add( sentry_attachment_t **attachments_ptr, sentry_attachment_t *attachment, - sentry_attachment_type_t attachment_type, const char *content_type); + const char *attachment_type, const char *content_type); /** * Adds a file attachment to the attachments list at `attachments_ptr`. */ sentry_attachment_t *sentry__attachments_add_path( sentry_attachment_t **attachments_ptr, sentry_path_t *path, - sentry_attachment_type_t attachment_type, const char *content_type); + const char *attachment_type, const char *content_type); /** * Removes an attachment from the attachments list at `attachments_ptr`. diff --git a/src/sentry_core.c b/src/sentry_core.c index a556d1c740..344888c2c6 100644 --- a/src/sentry_core.c +++ b/src/sentry_core.c @@ -1769,7 +1769,7 @@ sentry_capture_minidump_n(const char *path, size_t path_len) >= SENTRY_LARGE_ATTACHMENT_SIZE) { sentry_attachment_t tmp = { 0 }; tmp.path = dump_path; - tmp.type = MINIDUMP; + tmp.type = SENTRY_ATTACHMENT_TYPE_MINIDUMP; if (!sentry__cache_attachment_ref( envelope, &tmp, options->run->cache_path, NULL)) { SENTRY_WARN("failed to cache minidump attachment-ref"); @@ -1798,7 +1798,7 @@ sentry_capture_minidump_n(const char *path, size_t path_len) sentry_envelope_free(envelope); } else { sentry__envelope_item_set_header(item, "attachment_type", - sentry_value_new_string("event.minidump")); + sentry_value_new_string(SENTRY_ATTACHMENT_TYPE_MINIDUMP)); sentry__envelope_item_set_header(item, "filename", sentry_value_new_string(sentry__path_filename(dump_path))); @@ -1831,7 +1831,7 @@ add_attachment(sentry_attachment_t *attachment) } SENTRY_WITH_SCOPE_MUT (scope) { attachment = sentry__attachments_add( - &scope->attachments, attachment, ATTACHMENT, NULL); + &scope->attachments, attachment, NULL, NULL); } return attachment; } diff --git a/src/sentry_database.c b/src/sentry_database.c index 84078bda7f..ced802ebfc 100644 --- a/src/sentry_database.c +++ b/src/sentry_database.c @@ -290,7 +290,7 @@ static sentry_path_t * build_sibling_path(const sentry_path_t *cache_path, const char *uuid_str, const sentry_attachment_t *att) { - if (att->type == MINIDUMP) { + if (att->type && strcmp(att->type, SENTRY_ATTACHMENT_TYPE_MINIDUMP) == 0) { char buf[41]; snprintf(buf, sizeof(buf), "%s.dmp", uuid_str); return sentry__path_unique(cache_path, buf); diff --git a/src/sentry_envelope.c b/src/sentry_envelope.c index 69d3603d86..1ce5bb0347 100644 --- a/src/sentry_envelope.c +++ b/src/sentry_envelope.c @@ -628,22 +628,6 @@ sentry__envelope_add_session( envelope, payload, payload_len, "session"); } -static const char * -str_from_attachment_type(sentry_attachment_type_t attachment_type) -{ - switch (attachment_type) { - case ATTACHMENT: - return "event.attachment"; - case MINIDUMP: - return "event.minidump"; - case VIEW_HIERARCHY: - return "event.view_hierarchy"; - default: - UNREACHABLE("Unknown attachment type"); - return "event.attachment"; - } -} - static bool attachment_ref_has_payload(const sentry_attachment_ref_t *ref) { @@ -680,7 +664,7 @@ attachment_ref_payload_to_string( sentry_envelope_item_t * sentry__envelope_add_attachment_ref(sentry_envelope_t *envelope, const sentry_attachment_ref_t *ref, const char *filename, - sentry_attachment_type_t attachment_type, size_t attachment_length) + const char *attachment_type, size_t attachment_length) { if (!envelope) { return NULL; @@ -710,9 +694,9 @@ sentry__envelope_add_attachment_ref(sentry_envelope_t *envelope, sentry__envelope_item_set_header( item, "filename", sentry_value_new_string(filename)); } - if (attachment_type != ATTACHMENT) { - sentry__envelope_item_set_header(item, "attachment_type", - sentry_value_new_string(str_from_attachment_type(attachment_type))); + if (attachment_type && *attachment_type) { + sentry__envelope_item_set_header( + item, "attachment_type", sentry_value_new_string(attachment_type)); } sentry__envelope_item_set_header(item, "attachment_length", sentry_value_new_uint64((uint64_t)attachment_length)); @@ -746,10 +730,9 @@ sentry__envelope_add_attachment( if (!item) { return NULL; } - if (attachment->type != ATTACHMENT) { // don't need to set the default - sentry__envelope_item_set_header(item, "attachment_type", - sentry_value_new_string( - str_from_attachment_type(attachment->type))); + if (attachment->type && *attachment->type) { + sentry__envelope_item_set_header( + item, "attachment_type", sentry_value_new_string(attachment->type)); } if (attachment->content_type) { sentry__envelope_item_set_header(item, "content_type", diff --git a/src/sentry_envelope.h b/src/sentry_envelope.h index fac42b418d..08d7213d42 100644 --- a/src/sentry_envelope.h +++ b/src/sentry_envelope.h @@ -112,7 +112,7 @@ void sentry__envelope_add_attachments(sentry_envelope_t *envelope, */ sentry_envelope_item_t *sentry__envelope_add_attachment_ref( sentry_envelope_t *envelope, const sentry_attachment_ref_t *ref, - const char *filename, sentry_attachment_type_t attachment_type, + const char *filename, const char *attachment_type, size_t attachment_length); /** diff --git a/src/sentry_hint.c b/src/sentry_hint.c index 13d9a0e6e6..a67b7dafd8 100644 --- a/src/sentry_hint.c +++ b/src/sentry_hint.c @@ -41,7 +41,7 @@ sentry_hint_attach_file_n( return NULL; } return sentry__attachments_add_path(&hint->attachments, - sentry__path_from_str_n(path, path_len), ATTACHMENT, NULL); + sentry__path_from_str_n(path, path_len), NULL, NULL); } sentry_attachment_t * @@ -62,7 +62,7 @@ sentry_hint_attach_bytes_n(sentry_hint_t *hint, const char *buf, size_t buf_len, return sentry__attachments_add(&hint->attachments, sentry__attachment_from_buffer( buf, buf_len, sentry__path_from_str_n(filename, filename_len)), - ATTACHMENT, NULL); + NULL, NULL); } #ifdef SENTRY_PLATFORM_WINDOWS @@ -81,7 +81,7 @@ sentry_hint_attach_filew_n( return NULL; } return sentry__attachments_add_path(&hint->attachments, - sentry__path_from_wstr_n(path, path_len), ATTACHMENT, NULL); + sentry__path_from_wstr_n(path, path_len), NULL, NULL); } sentry_attachment_t * @@ -103,6 +103,6 @@ sentry_hint_attach_bytesw_n(sentry_hint_t *hint, const char *buf, return sentry__attachments_add(&hint->attachments, sentry__attachment_from_buffer( buf, buf_len, sentry__path_from_wstr_n(filename, filename_len)), - ATTACHMENT, NULL); + NULL, NULL); } #endif diff --git a/src/sentry_options.c b/src/sentry_options.c index 100015cfe5..cd48911b9e 100644 --- a/src/sentry_options.c +++ b/src/sentry_options.c @@ -610,7 +610,7 @@ void sentry_options_add_attachment(sentry_options_t *opts, const char *path) { sentry__attachments_add_path( - &opts->attachments, sentry__path_from_str(path), ATTACHMENT, NULL); + &opts->attachments, sentry__path_from_str(path), NULL, NULL); } void @@ -618,14 +618,15 @@ sentry_options_add_attachment_n( sentry_options_t *opts, const char *path, size_t path_len) { sentry__attachments_add_path(&opts->attachments, - sentry__path_from_str_n(path, path_len), ATTACHMENT, NULL); + sentry__path_from_str_n(path, path_len), NULL, NULL); } void sentry_options_add_view_hierarchy(sentry_options_t *opts, const char *path) { sentry__attachments_add_path(&opts->attachments, - sentry__path_from_str(path), VIEW_HIERARCHY, "application/json"); + sentry__path_from_str(path), SENTRY_ATTACHMENT_TYPE_VIEW_HIERARCHY, + "application/json"); } void @@ -633,7 +634,8 @@ sentry_options_add_view_hierarchy_n( sentry_options_t *opts, const char *path, size_t path_len) { sentry__attachments_add_path(&opts->attachments, - sentry__path_from_str_n(path, path_len), VIEW_HIERARCHY, + sentry__path_from_str_n(path, path_len), + SENTRY_ATTACHMENT_TYPE_VIEW_HIERARCHY, "application/json"); } @@ -703,7 +705,7 @@ sentry_options_add_attachmentw_n( sentry_options_t *opts, const wchar_t *path, size_t path_len) { sentry__attachments_add_path(&opts->attachments, - sentry__path_from_wstr_n(path, path_len), ATTACHMENT, NULL); + sentry__path_from_wstr_n(path, path_len), NULL, NULL); } void @@ -724,7 +726,8 @@ sentry_options_add_view_hierarchyw_n( sentry_options_t *opts, const wchar_t *path, size_t path_len) { sentry__attachments_add_path(&opts->attachments, - sentry__path_from_wstr_n(path, path_len), VIEW_HIERARCHY, + sentry__path_from_wstr_n(path, path_len), + SENTRY_ATTACHMENT_TYPE_VIEW_HIERARCHY, "application/json"); } diff --git a/src/sentry_scope.c b/src/sentry_scope.c index b73245839b..8ac1d36293 100644 --- a/src/sentry_scope.c +++ b/src/sentry_scope.c @@ -629,7 +629,7 @@ sentry_scope_attach_file_n( sentry_scope_t *scope, const char *path, size_t path_len) { return sentry__attachments_add_path(&scope->attachments, - sentry__path_from_str_n(path, path_len), ATTACHMENT, NULL); + sentry__path_from_str_n(path, path_len), NULL, NULL); } sentry_attachment_t * @@ -647,7 +647,7 @@ sentry_scope_attach_bytes_n(sentry_scope_t *scope, const char *buf, return sentry__attachments_add(&scope->attachments, sentry__attachment_from_buffer( buf, buf_len, sentry__path_from_str_n(filename, filename_len)), - ATTACHMENT, NULL); + NULL, NULL); } #ifdef SENTRY_PLATFORM_WINDOWS @@ -663,7 +663,7 @@ sentry_scope_attach_filew_n( sentry_scope_t *scope, const wchar_t *path, size_t path_len) { return sentry__attachments_add_path(&scope->attachments, - sentry__path_from_wstr_n(path, path_len), ATTACHMENT, NULL); + sentry__path_from_wstr_n(path, path_len), NULL, NULL); } sentry_attachment_t * @@ -682,7 +682,7 @@ sentry_scope_attach_bytesw_n(sentry_scope_t *scope, const char *buf, return sentry__attachments_add(&scope->attachments, sentry__attachment_from_buffer( buf, buf_len, sentry__path_from_wstr_n(filename, filename_len)), - ATTACHMENT, NULL); + NULL, NULL); } #endif diff --git a/tests/unit/test_attachments.c b/tests/unit/test_attachments.c index f1ea3e45f1..16586e907e 100644 --- a/tests/unit/test_attachments.c +++ b/tests/unit/test_attachments.c @@ -16,7 +16,6 @@ SENTRY_TEST(attachment_placeholder) char data[] = "x"; sentry_attachment_t attachment = { 0 }; - attachment.type = ATTACHMENT; attachment.buf = data; attachment.buf_len = SENTRY_LARGE_ATTACHMENT_SIZE; @@ -29,9 +28,10 @@ SENTRY_TEST(attachment_placeholder) attachment.buf_len = SENTRY_LARGE_ATTACHMENT_SIZE; TEST_CHECK(sentry__attachment_is_placeholder(&attachment, options)); - attachment.type = MINIDUMP; - TEST_CHECK(!sentry__attachment_is_placeholder(&attachment, options)); + sentry_attachment_set_type(&attachment, SENTRY_ATTACHMENT_TYPE_MINIDUMP); + TEST_CHECK(sentry__attachment_is_placeholder(&attachment, options)); + sentry_free(attachment.type); sentry_options_free(options); } @@ -269,19 +269,19 @@ SENTRY_TEST(attachments_extend) sentry_attachment_t *attachments_abc = NULL; sentry__attachments_add_path( - &attachments_abc, sentry__path_clone(path_a), ATTACHMENT, NULL); + &attachments_abc, sentry__path_clone(path_a), NULL, NULL); sentry__attachments_add_path( - &attachments_abc, sentry__path_clone(path_b), ATTACHMENT, NULL); + &attachments_abc, sentry__path_clone(path_b), NULL, NULL); sentry__attachments_add_path( - &attachments_abc, sentry__path_clone(path_c), ATTACHMENT, NULL); + &attachments_abc, sentry__path_clone(path_c), NULL, NULL); sentry_attachment_t *attachments_bcd = NULL; sentry__attachments_add_path( - &attachments_bcd, sentry__path_clone(path_b), ATTACHMENT, NULL); + &attachments_bcd, sentry__path_clone(path_b), NULL, NULL); sentry__attachments_add_path( - &attachments_bcd, sentry__path_clone(path_c), ATTACHMENT, NULL); + &attachments_bcd, sentry__path_clone(path_c), NULL, NULL); sentry__attachments_add_path( - &attachments_bcd, sentry__path_clone(path_d), ATTACHMENT, NULL); + &attachments_bcd, sentry__path_clone(path_d), NULL, NULL); sentry_attachment_t *all_attachments = NULL; sentry__attachments_extend(&all_attachments, attachments_abc); diff --git a/tests/unit/test_envelopes.c b/tests/unit/test_envelopes.c index 9cd4017ee5..6e0c655a05 100644 --- a/tests/unit/test_envelopes.c +++ b/tests/unit/test_envelopes.c @@ -915,7 +915,7 @@ SENTRY_TEST(attachment_ref_copy) sentry_attachment_t *attachment = sentry__attachment_from_path(sentry__path_clone(test_file_path)); - attachment->type = MINIDUMP; + sentry_attachment_set_type(attachment, SENTRY_ATTACHMENT_TYPE_MINIDUMP); sentry_attachment_set_content_type(attachment, "application/x-dmp"); sentry_envelope_t *envelope = sentry__envelope_new(); @@ -941,8 +941,8 @@ SENTRY_TEST(attachment_ref_copy) // envelope carries an attachment-ref item with the expected headers TEST_ASSERT(sentry__envelope_get_item_count(envelope) == 1); check_attachment_ref_item(envelope, 0, "sentry_test_minidump.dmp", - "application/x-dmp", "event.minidump", strlen("minidump_data"), - "c993afb6-b4ac-48a6-b61b-2558e601d65d.dmp"); + "application/x-dmp", SENTRY_ATTACHMENT_TYPE_MINIDUMP, + strlen("minidump_data"), "c993afb6-b4ac-48a6-b61b-2558e601d65d.dmp"); sentry_envelope_free(envelope); sentry__path_remove(cached); @@ -985,7 +985,6 @@ SENTRY_TEST(attachment_ref_move) sentry_attachment_t *attachment = sentry__attachment_from_path(sentry__path_clone(src_path)); - attachment->type = ATTACHMENT; sentry_envelope_t *envelope = sentry__envelope_new(); sentry__envelope_set_event_id(envelope, &event_id); @@ -1106,7 +1105,7 @@ SENTRY_TEST(attachment_ref_roundtrip) ref.path = "abc-crashlog.bin"; ref.content_type = "application/octet-stream"; sentry__envelope_add_attachment_ref( - envelope, &ref, "crashlog.bin", ATTACHMENT, 12345); + envelope, &ref, "crashlog.bin", NULL, 12345); size_t buf_len = 0; char *buf = sentry_envelope_serialize(envelope, &buf_len); From 2300be8d830fcd93d1a5bce67b840411e1d74982 Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 5 May 2026 13:05:21 +0200 Subject: [PATCH 2/4] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11c65859f3..10c4634d5a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ **Features**: - Auto-populate `event.user.id` with a persistent per-installation UUID when no explicit user ID is set. ([#1661](https://github.com/getsentry/sentry-native/pull/1661)) -- Add `sentry_attachment_set_type` and `SENTRY_ATTACHMENT_TYPE_*` for common envelope attachment types. ([#TODO](https://github.com/getsentry/sentry-native/pull/TODO)) +- Add `sentry_attachment_set_type` and `SENTRY_ATTACHMENT_TYPE_*` macros for standard Sentry attachment types. ([#1700](https://github.com/getsentry/sentry-native/pull/1700)) ## 0.14.0 From fd973a2441291bc72ee8635a46d97cd540058f8e Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 5 May 2026 13:09:31 +0200 Subject: [PATCH 3/4] Fix formatting --- src/backends/sentry_backend_crashpad.cpp | 9 ++++----- src/sentry_options.c | 6 ++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/backends/sentry_backend_crashpad.cpp b/src/backends/sentry_backend_crashpad.cpp index 300c7936f3..f9ad2025b1 100644 --- a/src/backends/sentry_backend_crashpad.cpp +++ b/src/backends/sentry_backend_crashpad.cpp @@ -517,8 +517,8 @@ report_to_envelope(const crashpad::CrashReportDatabase::Report &report, } else if (strcmp(filename, "__sentry-breadcrumb2") == 0) { breadcrumbs2 = read_msgpack_file(path); } else { - sentry__attachments_add_path(&attachments, - sentry__path_clone(path), nullptr, nullptr); + sentry__attachments_add_path( + &attachments, sentry__path_clone(path), nullptr, nullptr); } } sentry__pathiter_free(iter); @@ -537,9 +537,8 @@ report_to_envelope(const crashpad::CrashReportDatabase::Report &report, sentry_value_set_by_key(event, "breadcrumbs", sentry__value_merge_breadcrumbs( breadcrumbs1, breadcrumbs2, options->max_breadcrumbs)); - sentry__attachments_add_path( - &attachments, minidump_path, SENTRY_ATTACHMENT_TYPE_MINIDUMP, - nullptr); + sentry__attachments_add_path(&attachments, minidump_path, + SENTRY_ATTACHMENT_TYPE_MINIDUMP, nullptr); if (sentry__envelope_add_event(envelope, event)) { sentry__envelope_add_attachments(envelope, attachments, options); diff --git a/src/sentry_options.c b/src/sentry_options.c index cd48911b9e..619d7f8443 100644 --- a/src/sentry_options.c +++ b/src/sentry_options.c @@ -635,8 +635,7 @@ sentry_options_add_view_hierarchy_n( { sentry__attachments_add_path(&opts->attachments, sentry__path_from_str_n(path, path_len), - SENTRY_ATTACHMENT_TYPE_VIEW_HIERARCHY, - "application/json"); + SENTRY_ATTACHMENT_TYPE_VIEW_HIERARCHY, "application/json"); } void @@ -727,8 +726,7 @@ sentry_options_add_view_hierarchyw_n( { sentry__attachments_add_path(&opts->attachments, sentry__path_from_wstr_n(path, path_len), - SENTRY_ATTACHMENT_TYPE_VIEW_HIERARCHY, - "application/json"); + SENTRY_ATTACHMENT_TYPE_VIEW_HIERARCHY, "application/json"); } void From e4abe3dbb76f30fb990d86fba7b5d6928a87845b Mon Sep 17 00:00:00 2001 From: J-P Nurmi Date: Tue, 5 May 2026 13:26:38 +0200 Subject: [PATCH 4/4] Cast --- src/backends/sentry_backend_breakpad.cpp | 2 +- src/sentry_core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/sentry_backend_breakpad.cpp b/src/backends/sentry_backend_breakpad.cpp index a8db4c332f..39e9d7fad5 100644 --- a/src/backends/sentry_backend_breakpad.cpp +++ b/src/backends/sentry_backend_breakpad.cpp @@ -193,7 +193,7 @@ breakpad_backend_callback(const google_breakpad::MinidumpDescriptor &descriptor, } else if (options->enable_large_attachments) { sentry_attachment_t tmp = {}; tmp.path = dump_path; - tmp.type = SENTRY_ATTACHMENT_TYPE_MINIDUMP; + tmp.type = (char *)SENTRY_ATTACHMENT_TYPE_MINIDUMP; if (!sentry__cache_attachment_ref( envelope, &tmp, options->run->cache_path, nullptr)) { SENTRY_SIGNAL_SAFE_LOG( diff --git a/src/sentry_core.c b/src/sentry_core.c index 344888c2c6..3299a2b169 100644 --- a/src/sentry_core.c +++ b/src/sentry_core.c @@ -1769,7 +1769,7 @@ sentry_capture_minidump_n(const char *path, size_t path_len) >= SENTRY_LARGE_ATTACHMENT_SIZE) { sentry_attachment_t tmp = { 0 }; tmp.path = dump_path; - tmp.type = SENTRY_ATTACHMENT_TYPE_MINIDUMP; + tmp.type = (char *)SENTRY_ATTACHMENT_TYPE_MINIDUMP; if (!sentry__cache_attachment_ref( envelope, &tmp, options->run->cache_path, NULL)) { SENTRY_WARN("failed to cache minidump attachment-ref");