From 7a42a3cd21753f202507cc3c11d37e55b6c61701 Mon Sep 17 00:00:00 2001
From: J-P Nurmi
Date: Fri, 13 Jun 2025 17:47:04 +0200
Subject: [PATCH 1/3] feat: add sentry_attachment_set_content_type()
---
CHANGELOG.md | 1 +
include/sentry.h | 3 ++
src/sentry_attachment.c | 20 ++++++++++++
src/sentry_attachment.h | 1 +
tests/unit/test_attachments.c | 57 +++++++++++++++++++++++++++++++++++
tests/unit/tests.inc | 1 +
6 files changed, 83 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 64e5f1d63..b7790739e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@
- The `sentry_attach_file`, `sentry_scope_attach_file` (and their wide-string variants), and `sentry_remove_attachment` have been added to modify the list of attachments that are sent along with sentry events after a call to `sentry_init`. ([#1266](https://github.com/getsentry/sentry-native/pull/1266))
- NOTE: When using the `crashpad` backend on macOS, the list of attachments that will be added at the time of a hard crash will be frozen at the time of `sentry_init`, and later modifications will not be reflected.
+- Add `sentry_attachment_set_content_type` to allow specifying the content type of attachments. ([#1276](https://github.com/getsentry/sentry-native/pull/1276))
## 0.9.0
diff --git a/include/sentry.h b/include/sentry.h
index 91c584418..b8b5c2004 100644
--- a/include/sentry.h
+++ b/include/sentry.h
@@ -1833,6 +1833,9 @@ SENTRY_API sentry_attachment_t *sentry_scope_attach_filew_n(
sentry_scope_t *scope, const wchar_t *path, size_t path_len);
#endif
+SENTRY_API void sentry_attachment_set_content_type(
+ sentry_attachment_t *attachment, const char *content_type);
+
/* -- Session APIs -- */
typedef enum {
diff --git a/src/sentry_attachment.c b/src/sentry_attachment.c
index b30630774..34383fb61 100644
--- a/src/sentry_attachment.c
+++ b/src/sentry_attachment.c
@@ -1,6 +1,22 @@
#include "sentry_attachment.h"
#include "sentry_alloc.h"
#include "sentry_path.h"
+#include "sentry_string.h"
+
+void
+sentry_attachment_set_content_type(
+ sentry_attachment_t *attachment, const char *content_type)
+{
+ if (!attachment) {
+ return;
+ }
+
+ if (attachment->content_type_owned) {
+ sentry_free((void *)attachment->content_type);
+ }
+ attachment->content_type = sentry__string_clone(content_type);
+ attachment->content_type_owned = true;
+}
static void
attachment_free(sentry_attachment_t *attachment)
@@ -9,6 +25,9 @@ attachment_free(sentry_attachment_t *attachment)
return;
}
sentry__path_free(attachment->path);
+ if (attachment->content_type_owned) {
+ sentry_free((void *)attachment->content_type);
+ }
sentry_free(attachment);
}
@@ -41,6 +60,7 @@ sentry__attachments_add(sentry_attachment_t **attachments_ptr,
attachment->next = NULL;
attachment->type = attachment_type;
attachment->content_type = content_type;
+ attachment->content_type_owned = false;
sentry_attachment_t **next_ptr = attachments_ptr;
diff --git a/src/sentry_attachment.h b/src/sentry_attachment.h
index cc69263e1..1cb661d14 100644
--- a/src/sentry_attachment.h
+++ b/src/sentry_attachment.h
@@ -22,6 +22,7 @@ struct sentry_attachment_s {
sentry_path_t *path;
sentry_attachment_type_t type;
const char *content_type;
+ bool content_type_owned;
sentry_attachment_t *next;
};
diff --git a/tests/unit/test_attachments.c b/tests/unit/test_attachments.c
index 08eb59086..d3215cb93 100644
--- a/tests/unit/test_attachments.c
+++ b/tests/unit/test_attachments.c
@@ -307,3 +307,60 @@ SENTRY_TEST(attachments_extend)
sentry__path_free(path_c);
sentry__path_free(path_d);
}
+
+SENTRY_TEST(attachment_content_type)
+{
+ SENTRY_TEST_OPTIONS_NEW(options);
+ sentry_init(options);
+
+ sentry_path_t *path_txt
+ = sentry__path_from_str(SENTRY_TEST_PATH_PREFIX ".a.txt");
+ sentry_path_t *path_html
+ = sentry__path_from_str(SENTRY_TEST_PATH_PREFIX ".b.html");
+ sentry_path_t *path_c = sentry__path_from_str(SENTRY_TEST_PATH_PREFIX ".c");
+
+ sentry__path_write_buffer(path_txt, "plain", 5);
+ sentry__path_write_buffer(path_html, "", 7);
+ sentry__path_write_buffer(path_c, "int main() {}", 13);
+
+ sentry_attachment_t *attachment_txt
+ = sentry_attach_file(SENTRY_TEST_PATH_PREFIX ".a.txt");
+ sentry_attachment_set_content_type(attachment_txt, "text/plain");
+
+ sentry_attachment_t *attachment_html
+ = sentry_attach_file(SENTRY_TEST_PATH_PREFIX ".b.html");
+ sentry_attachment_set_content_type(attachment_html, "text/html");
+
+ sentry_attachment_t *attachment_c
+ = sentry_attach_file(SENTRY_TEST_PATH_PREFIX ".c");
+ sentry_attachment_set_content_type(attachment_c, NULL);
+
+ SENTRY_WITH_SCOPE (scope) {
+ sentry_envelope_t *envelope = sentry__envelope_new();
+ sentry__envelope_add_attachments(envelope, scope->attachments);
+
+ char *serialized = sentry_envelope_serialize(envelope, NULL);
+ TEST_CHECK_STRING_EQUAL(serialized,
+ "{}\n"
+ "{\"type\":\"attachment\",\"length\":5,\"content_type\":\"text/"
+ "plain\","
+ "\"filename\":\".a.txt\"}\nplain\n"
+ "{\"type\":\"attachment\",\"length\":7,\"content_type\":\"text/"
+ "html\","
+ "\"filename\":\".b.html\"}\n
"
+ "\n{\"type\":\"attachment\",\"length\":13,\"filename\":\".c\"}\n"
+ "int main() {}");
+ sentry_free(serialized);
+ sentry_envelope_free(envelope);
+ }
+
+ sentry_close();
+
+ sentry__path_remove(path_txt);
+ sentry__path_remove(path_html);
+ sentry__path_remove(path_c);
+
+ sentry__path_free(path_txt);
+ sentry__path_free(path_html);
+ sentry__path_free(path_c);
+}
diff --git a/tests/unit/tests.inc b/tests/unit/tests.inc
index 56badaefc..abd15deae 100644
--- a/tests/unit/tests.inc
+++ b/tests/unit/tests.inc
@@ -1,6 +1,7 @@
XX(assert_sdk_name)
XX(assert_sdk_user_agent)
XX(assert_sdk_version)
+XX(attachment_content_type)
XX(attachments_add_dedupe)
XX(attachments_add_remove)
XX(attachments_extend)
From dbe09197cc2f61b92eaf230de313af28d4cbec9d Mon Sep 17 00:00:00 2001
From: J-P Nurmi
Date: Mon, 16 Jun 2025 10:40:53 +0200
Subject: [PATCH 2/3] drop content_type_owned
---
src/sentry_attachment.c | 12 +++---------
src/sentry_attachment.h | 3 +--
2 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/src/sentry_attachment.c b/src/sentry_attachment.c
index 34383fb61..1114c28b9 100644
--- a/src/sentry_attachment.c
+++ b/src/sentry_attachment.c
@@ -11,11 +11,8 @@ sentry_attachment_set_content_type(
return;
}
- if (attachment->content_type_owned) {
- sentry_free((void *)attachment->content_type);
- }
+ sentry_free(attachment->content_type);
attachment->content_type = sentry__string_clone(content_type);
- attachment->content_type_owned = true;
}
static void
@@ -25,9 +22,7 @@ attachment_free(sentry_attachment_t *attachment)
return;
}
sentry__path_free(attachment->path);
- if (attachment->content_type_owned) {
- sentry_free((void *)attachment->content_type);
- }
+ sentry_free(attachment->content_type);
sentry_free(attachment);
}
@@ -59,8 +54,7 @@ sentry__attachments_add(sentry_attachment_t **attachments_ptr,
attachment->path = path;
attachment->next = NULL;
attachment->type = attachment_type;
- attachment->content_type = content_type;
- attachment->content_type_owned = false;
+ attachment->content_type = sentry__string_clone(content_type);
sentry_attachment_t **next_ptr = attachments_ptr;
diff --git a/src/sentry_attachment.h b/src/sentry_attachment.h
index 1cb661d14..b403b8453 100644
--- a/src/sentry_attachment.h
+++ b/src/sentry_attachment.h
@@ -21,8 +21,7 @@ typedef enum {
struct sentry_attachment_s {
sentry_path_t *path;
sentry_attachment_type_t type;
- const char *content_type;
- bool content_type_owned;
+ char *content_type;
sentry_attachment_t *next;
};
From 57809f94d8fef1696fdc51f934b11d9d14ba98f8 Mon Sep 17 00:00:00 2001
From: J-P Nurmi
Date: Mon, 16 Jun 2025 10:43:29 +0200
Subject: [PATCH 3/3] add _n
---
include/sentry.h | 3 +++
src/sentry_attachment.c | 11 ++++++++++-
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/include/sentry.h b/include/sentry.h
index b8b5c2004..a06dbd234 100644
--- a/include/sentry.h
+++ b/include/sentry.h
@@ -1835,6 +1835,9 @@ SENTRY_API sentry_attachment_t *sentry_scope_attach_filew_n(
SENTRY_API void sentry_attachment_set_content_type(
sentry_attachment_t *attachment, const char *content_type);
+SENTRY_API void sentry_attachment_set_content_type_n(
+ sentry_attachment_t *attachment, const char *content_type,
+ size_t content_type_len);
/* -- Session APIs -- */
diff --git a/src/sentry_attachment.c b/src/sentry_attachment.c
index 1114c28b9..bafd647d9 100644
--- a/src/sentry_attachment.c
+++ b/src/sentry_attachment.c
@@ -6,13 +6,22 @@
void
sentry_attachment_set_content_type(
sentry_attachment_t *attachment, const char *content_type)
+{
+ sentry_attachment_set_content_type_n(
+ attachment, content_type, sentry__guarded_strlen(content_type));
+}
+
+void
+sentry_attachment_set_content_type_n(sentry_attachment_t *attachment,
+ const char *content_type, size_t content_type_len)
{
if (!attachment) {
return;
}
sentry_free(attachment->content_type);
- attachment->content_type = sentry__string_clone(content_type);
+ attachment->content_type
+ = sentry__string_clone_n(content_type, content_type_len);
}
static void