buffer: introduce git_buf_attach_notowned Provide a convenience function that creates a buffer that can be provided to callers but will not be freed via `git_buf_free`, so the buffer creator maintains the allocation lifecycle of the buffer's contents.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
diff --git a/src/attr.c b/src/attr.c
index 44593da..3842080 100644
--- a/src/attr.c
+++ b/src/attr.c
@@ -282,9 +282,8 @@ static int system_attr_file(
* a consumer. This allows them to treat this as a regular `git_buf`,
* but their call to `git_buf_free` will not attempt to free it.
*/
- out->ptr = attr_session->sysdir.ptr;
- out->size = attr_session->sysdir.size;
- out->asize = 0;
+ git_buf_attach_notowned(
+ out, attr_session->sysdir.ptr, attr_session->sysdir.size);
return 0;
}
diff --git a/src/blob.c b/src/blob.c
index 30d5b70..ba8769c 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -329,15 +329,13 @@ cleanup:
int git_blob_is_binary(const git_blob *blob)
{
- git_buf content;
+ git_buf content = GIT_BUF_INIT;
assert(blob);
- content.ptr = blob->odb_object->buffer;
- content.size =
- min(blob->odb_object->cached.size, GIT_FILTER_BYTES_TO_CHECK_NUL);
- content.asize = 0;
-
+ git_buf_attach_notowned(&content, blob->odb_object->buffer,
+ min(blob->odb_object->cached.size,
+ GIT_FILTER_BYTES_TO_CHECK_NUL));
return git_buf_text_is_binary(&content);
}
diff --git a/src/buffer.c b/src/buffer.c
index 3deb032..f633c5e 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -500,6 +500,20 @@ void git_buf_attach(git_buf *buf, char *ptr, size_t asize)
}
}
+void git_buf_attach_notowned(git_buf *buf, const char *ptr, size_t size)
+{
+ if (git_buf_is_allocated(buf))
+ git_buf_free(buf);
+
+ if (!size) {
+ git_buf_init(buf, 0);
+ } else {
+ buf->ptr = (char *)ptr;
+ buf->asize = 0;
+ buf->size = size;
+ }
+}
+
int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
{
va_list ap;
diff --git a/src/buffer.h b/src/buffer.h
index 52342e3..093ed9b 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -74,6 +74,12 @@ extern void git_buf_swap(git_buf *buf_a, git_buf *buf_b);
extern char *git_buf_detach(git_buf *buf);
extern void git_buf_attach(git_buf *buf, char *ptr, size_t asize);
+/* Populates a `git_buf` where the contents are not "owned" by the
+ * buffer, and calls to `git_buf_free` will not free the given buf.
+ */
+extern void git_buf_attach_notowned(
+ git_buf *buf, const char *ptr, size_t size);
+
/**
* Test if there have been any reallocation failures with this git_buf.
*
diff --git a/src/diff_driver.c b/src/diff_driver.c
index 7313ab5..049e6ef 100644
--- a/src/diff_driver.c
+++ b/src/diff_driver.c
@@ -418,14 +418,13 @@ void git_diff_driver_update_options(
int git_diff_driver_content_is_binary(
git_diff_driver *driver, const char *content, size_t content_len)
{
- git_buf search;
-
- search.ptr = (char *)content;
- search.size = min(content_len, GIT_FILTER_BYTES_TO_CHECK_NUL);
- search.asize = 0;
+ git_buf search = GIT_BUF_INIT;
GIT_UNUSED(driver);
+ git_buf_attach_notowned(&search, content,
+ min(content_len, GIT_FILTER_BYTES_TO_CHECK_NUL));
+
/* TODO: provide encoding / binary detection callbacks that can
* be UTF-8 aware, etc. For now, instead of trying to be smart,
* let's just use the simple NUL-byte detection that core git uses.
diff --git a/src/filter.c b/src/filter.c
index 08aa14b..4009a61 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -606,23 +606,6 @@ size_t git_filter_list_length(const git_filter_list *fl)
return fl ? git_array_size(fl->filters) : 0;
}
-static int filter_list_out_buffer_from_raw(
- git_buf *out, const void *ptr, size_t size)
-{
- if (git_buf_is_allocated(out))
- git_buf_free(out);
-
- if (!size) {
- git_buf_init(out, 0);
- } else {
- out->ptr = (char *)ptr;
- out->asize = 0;
- out->size = size;
- }
-
- return 0;
-}
-
struct buf_stream {
git_writestream parent;
git_buf *target;
@@ -677,8 +660,10 @@ int git_filter_list_apply_to_data(
git_buf_sanitize(tgt);
git_buf_sanitize(src);
- if (!filters)
- return filter_list_out_buffer_from_raw(tgt, src->ptr, src->size);
+ if (!filters) {
+ git_buf_attach_notowned(tgt, src->ptr, src->size);
+ return 0;
+ }
buf_stream_init(&writer, tgt);
@@ -718,10 +703,7 @@ static int buf_from_blob(git_buf *out, git_blob *blob)
return -1;
}
- out->ptr = (char *)git_blob_rawcontent(blob);
- out->asize = 0;
- out->size = (size_t)rawsize;
-
+ git_buf_attach_notowned(out, git_blob_rawcontent(blob), (size_t)rawsize);
return 0;
}