Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15
libgit2
0005-buffer-git_buf_sanitize-should-return-a-va...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0005-buffer-git_buf_sanitize-should-return-a-value.patch of Package libgit2
From cb4bfbc99dffa7679f42cf8500931fa250bb7db3 Mon Sep 17 00:00:00 2001 From: Edward Thomson <ethomson@edwardthomson.com> Date: Sun, 5 Apr 2020 11:07:54 +0100 Subject: [PATCH] buffer: git_buf_sanitize should return a value `git_buf_sanitize` is called with user-input, and wants to sanity-check that input. Allow it to return a value if the input was malformed in a way that we cannot cope. --- src/blob.c | 5 +++-- src/branch.c | 11 +++++----- src/buffer.c | 10 ++++++--- src/buffer.h | 2 +- src/config.c | 30 +++++++++++++++++++++------ src/describe.c | 3 ++- src/diff_print.c | 13 ++++++++++-- src/filter.c | 12 +++++++---- src/libgit2.c | 51 ++++++++++++++++++++++++++-------------------- src/message.c | 4 +++- src/notes.c | 5 ++--- src/object.c | 4 +++- src/pack-objects.c | 7 ++++++- src/refspec.c | 17 +++++++++++++--- src/remote.c | 10 ++++++--- src/repository.c | 7 +++++-- src/submodule.c | 3 ++- 17 files changed, 133 insertions(+), 61 deletions(-) #diff --git a/src/blob.c b/src/blob.c #index 392a1fe07c7..97069645c8b 100644 #--- a/src/blob.c #+++ b/src/blob.c #@@ -423,11 +423,12 @@ int git_blob_filter( # GIT_ASSERT_ARG(path); # GIT_ASSERT_ARG(out); # #- git_buf_sanitize(out); #- # GIT_ERROR_CHECK_VERSION( # given_opts, GIT_BLOB_FILTER_OPTIONS_VERSION, "git_blob_filter_options"); # #+ if (git_buf_sanitize(out) < 0) #+ return -1; #+ # if (given_opts != NULL) # memcpy(&opts, given_opts, sizeof(git_blob_filter_options)); # diff --git a/src/branch.c b/src/branch.c index 08fd95d5851..29ff0b9d99d 100644 --- a/src/branch.c +++ b/src/branch.c @@ -417,7 +417,8 @@ int git_branch_upstream_name( # GIT_ASSERT_ARG(out); # GIT_ASSERT_ARG(refname); # assert(out && refname); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; if (!git_reference__is_branch(refname)) return not_a_local_branch(refname); @@ -478,9 +479,8 @@ int git_branch_upstream_remote(git_buf *buf, git_repository *repo, const char *r if ((error = git_repository_config__weakptr(&cfg, repo)) < 0) return error; - git_buf_sanitize(buf); - - if ((error = retrieve_upstream_configuration(buf, cfg, refname, "branch.%s.remote")) < 0) + if ((error = git_buf_sanitize(buf)) < 0 || + (error = retrieve_upstream_configuration(buf, cfg, refname, "branch.%s.remote")) < 0) return error; if (git_buf_len(buf) == 0) { @@ -505,7 +505,8 @@ int git_branch_remote_name(git_buf *buf, git_repository *repo, const char *refna # GIT_ASSERT_ARG(repo); # GIT_ASSERT_ARG(refname); # assert(buf && repo && refname); - git_buf_sanitize(buf); + if ((error = git_buf_sanitize(buf)) < 0) + return error; /* Verify that this is a remote branch */ if (!git_reference__is_remote(refname)) { diff --git a/src/buffer.c b/src/buffer.c index f395a77cc02..2928b17674d 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -140,13 +140,17 @@ void git_buf_free(git_buf *buf) # } # #endif # # git_buf_dispose(buf); git_buf_init(buf, 0); } -void git_buf_sanitize(git_buf *buf) +int git_buf_sanitize(git_buf *buf) { if (buf->ptr == NULL) { - assert(buf->size == 0 && buf->asize == 0); #+ GIT_ASSERT_ARG(buf->size == 0 && buf->asize == 0); + assert(buf->size == 0 && buf->asize == 0); + buf->ptr = git_buf__initbuf; - } else if (buf->asize > buf->size) + } else if (buf->asize > buf->size) { buf->ptr[buf->size] = '\0'; + } + + return 0; } void git_buf_clear(git_buf *buf) diff --git a/src/buffer.h b/src/buffer.h index 6b717d2e90c..6257b435b25 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -69,7 +69,7 @@ extern int git_buf_try_grow( * git_buf__initbuf. If a buffer with a non-NULL ptr is passed in, this method * assures that the buffer is '\0'-terminated. */ -extern void git_buf_sanitize(git_buf *buf); +extern int git_buf_sanitize(git_buf *buf); extern void git_buf_swap(git_buf *buf_a, git_buf *buf_b); extern char *git_buf_detach(git_buf *buf); diff --git a/src/config.c b/src/config.c index 42f46e6cf12..b3e7324a1ce 100644 --- a/src/config.c +++ b/src/config.c @@ -886,7 +886,8 @@ int git_config_get_string_buf( int ret; const char *str; - git_buf_sanitize(out); + if ((ret = git_buf_sanitize(out)) < 0) + return ret; ret = get_entry(&entry, cfg, name, true, GET_ALL_ERRORS); str = !ret ? (entry->value ? entry->value : "") : NULL; @@ -1084,19 +1085,31 @@ void git_config_iterator_free(git_config_iterator *iter) int git_config_find_global(git_buf *path) { - git_buf_sanitize(path); + int error; + + if ((error = git_buf_sanitize(path)) < 0) + return error; + return git_sysdir_find_global_file(path, GIT_CONFIG_FILENAME_GLOBAL); } int git_config_find_xdg(git_buf *path) { - git_buf_sanitize(path); + int error; + + if ((error = git_buf_sanitize(path)) < 0) + return error; + return git_sysdir_find_xdg_file(path, GIT_CONFIG_FILENAME_XDG); } int git_config_find_system(git_buf *path) { - git_buf_sanitize(path); + int error; + + if ((error = git_buf_sanitize(path)) < 0) + return error; + return git_sysdir_find_system_file(path, GIT_CONFIG_FILENAME_SYSTEM); } @@ -1104,7 +1117,9 @@ int git_config_find_programdata(git_buf *path) { int ret; - git_buf_sanitize(path); + if ((ret = git_buf_sanitize(path)) < 0) + return ret; + ret = git_sysdir_find_programdata_file(path, GIT_CONFIG_FILENAME_PROGRAMDATA); if (ret != GIT_OK) @@ -1360,9 +1375,12 @@ int git_config_parse_int32(int32_t *out, const char *value) int git_config_parse_path(git_buf *out, const char *value) { + int error; + assert(out && value); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; if (value[0] == '~') { if (value[1] != '\0' && value[1] != '/') { diff --git a/src/describe.c b/src/describe.c index 8beffdebaa6..ebf70b062eb 100644 --- a/src/describe.c +++ b/src/describe.c @@ -780,7 +780,8 @@ int git_describe_format(git_buf *out, const git_describe_result *result, const g # GIT_ERROR_CHECK_VERSION(given, GIT_DESCRIBE_FORMAT_OPTIONS_VERSION, "git_describe_format_options"); GITERR_CHECK_VERSION(given, GIT_DESCRIBE_FORMAT_OPTIONS_VERSION, "git_describe_format_options"); normalize_format_options(&opts, given); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; if (opts.always_use_long_format && opts.abbreviated_size == 0) { diff --git a/src/diff_print.c b/src/diff_print.c index 9ce04d70e35..0e93fe8933f 100644 --- a/src/diff_print.c +++ b/src/diff_print.c @@ -764,8 +764,12 @@ int git_diff_print_callback__to_file_handle( /* print a git_diff to a git_buf */ int git_diff_to_buf(git_buf *out, git_diff *diff, git_diff_format_t format) { + int error; + assert(out && diff); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; + # return git_diff_print(diff, format, git_diff_print_callback__to_buf, out); # } # return git_diff_print( diff, format, git_diff_print_callback__to_buf, out); } @@ -799,7 +803,12 @@ int git_patch_print( /* print a git_patch to a git_buf */ int git_patch_to_buf(git_buf *out, git_patch *patch) { + int error; + assert(out && patch); - git_buf_sanitize(out); + + if ((error = git_buf_sanitize(out)) < 0) + return error; + return git_patch_print(patch, git_diff_print_callback__to_buf, out); } diff --git a/src/filter.c b/src/filter.c index 86db5a5e370..ae9220c9b79 100644 --- a/src/filter.c +++ b/src/filter.c @@ -725,8 +725,9 @@ int git_filter_list_apply_to_data( struct buf_stream writer; int error; - git_buf_sanitize(tgt); - git_buf_sanitize(src); + if ((error = git_buf_sanitize(tgt)) < 0 || + (error = git_buf_sanitize(src)) < 0) + return error; if (!filters) { git_buf_attach_notowned(tgt, src->ptr, src->size); @@ -832,7 +833,9 @@ static int proxy_stream_close(git_writestream *s) if (error == GIT_PASSTHROUGH) { writebuf = &proxy_stream->input; } else if (error == 0) { - git_buf_sanitize(proxy_stream->output); + if ((error = git_buf_sanitize(proxy_stream->output)) < 0) + return error; + writebuf = proxy_stream->output; } else { /* close stream before erroring out taking care @@ -1004,7 +1007,8 @@ int git_filter_list_stream_data( git_writestream *stream_start; int error, initialized = 0; - git_buf_sanitize(data); + if ((error = git_buf_sanitize(data)) < 0) + return error; if ((error = stream_list_init(&stream_start, &filter_streams, filters, target)) < 0) goto out; #diff --git a/src/libgit2.c b/src/libgit2.c #index 07414bec826..9e5112dbf2a 100644 #--- a/src/libgit2.c #+++ b/src/libgit2.c #@@ -122,29 +122,28 @@ int git_libgit2_features(void) # ; # } # #-static int config_level_to_sysdir(int config_level) #+static int config_level_to_sysdir(int *out, int config_level) # { #- int val = -1; #- # switch (config_level) { # case GIT_CONFIG_LEVEL_SYSTEM: #- val = GIT_SYSDIR_SYSTEM; #- break; #+ *out = GIT_SYSDIR_SYSTEM; #+ return 0; # case GIT_CONFIG_LEVEL_XDG: #- val = GIT_SYSDIR_XDG; #- break; #+ *out = GIT_SYSDIR_XDG; #+ return 0; # case GIT_CONFIG_LEVEL_GLOBAL: #- val = GIT_SYSDIR_GLOBAL; #- break; #+ *out = GIT_SYSDIR_GLOBAL; #+ return 0; # case GIT_CONFIG_LEVEL_PROGRAMDATA: #- val = GIT_SYSDIR_PROGRAMDATA; #- break; #+ *out = GIT_SYSDIR_PROGRAMDATA; #+ return 0; # default: #- giterr_set( #- GITERR_INVALID, "invalid config path selector %d", config_level); #+ break; # } # #- return val; #+ giterr_set( #+ GITERR_INVALID, "invalid config path selector %d", config_level); #+ return -1; # } # # const char *git_libgit2__user_agent(void) #@@ -190,12 +189,15 @@ int git_libgit2_opts(int key, ...) # break; # # case GIT_OPT_GET_SEARCH_PATH: #- if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0) { #+ { #+ int sysdir = va_arg(ap, int); # git_buf *out = va_arg(ap, git_buf *); # const git_buf *tmp; #+ int level; # #- git_buf_sanitize(out); #- if ((error = git_sysdir_get(&tmp, error)) < 0) #+ if ((error = config_level_to_sysdir(&level, sysdir)) < 0 || #+ (error = git_buf_sanitize(out)) < 0 || #+ (error = git_sysdir_get(&tmp, level)) < 0) # break; # # error = git_buf_sets(out, tmp->ptr); #@@ -203,8 +205,12 @@ int git_libgit2_opts(int key, ...) # break; # # case GIT_OPT_SET_SEARCH_PATH: #- if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0) #- error = git_sysdir_set(error, va_arg(ap, const char *)); #+ { #+ int level; #+ #+ if ((error = config_level_to_sysdir(&level, va_arg(ap, int))) >= 0) #+ error = git_sysdir_set(level, va_arg(ap, const char *)); #+ } # break; # # case GIT_OPT_SET_CACHE_OBJECT_LIMIT: #@@ -233,8 +239,8 @@ int git_libgit2_opts(int key, ...) # git_buf *out = va_arg(ap, git_buf *); # const git_buf *tmp; # #- git_buf_sanitize(out); #- if ((error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0) #+ if ((error = git_buf_sanitize(out)) < 0 || #+ (error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0) # break; # # error = git_buf_sets(out, tmp->ptr); #@@ -303,7 +309,8 @@ int git_libgit2_opts(int key, ...) # case GIT_OPT_GET_USER_AGENT: # { # git_buf *out = va_arg(ap, git_buf *); #- git_buf_sanitize(out); #+ if ((error = git_buf_sanitize(out)) < 0) #+ break; # error = git_buf_sets(out, git__user_agent); # } # break; diff --git a/src/settings.c b/src/settings.c index 07414bec826..9e5112dbf2a 100644 --- a/src/settings.c 2019-12-10 20:39:58.000000000 +0100 +++ b/src/settings.c 2022-08-24 18:37:39.619994017 +0200 @@ -58,29 +58,28 @@ extern size_t git_mwindow__window_size; extern size_t git_mwindow__mapped_limit; # extern size_t git_indexer__max_objects; -static int config_level_to_sysdir(int config_level) +static int config_level_to_sysdir(int *out, int config_level) { - int val = -1; - switch (config_level) { case GIT_CONFIG_LEVEL_SYSTEM: - val = GIT_SYSDIR_SYSTEM; - break; + *out = GIT_SYSDIR_SYSTEM; + return 0; case GIT_CONFIG_LEVEL_XDG: - val = GIT_SYSDIR_XDG; - break; + *out = GIT_SYSDIR_XDG; + return 0; case GIT_CONFIG_LEVEL_GLOBAL: - val = GIT_SYSDIR_GLOBAL; - break; + *out = GIT_SYSDIR_GLOBAL; + return 0; case GIT_CONFIG_LEVEL_PROGRAMDATA: - val = GIT_SYSDIR_PROGRAMDATA; - break; + *out = GIT_SYSDIR_PROGRAMDATA; + return 0; default: #- giterr_set( #- GIT_ERROR_INVALID, "invalid config path selector %d", config_level); - giterr_set( - GITERR_INVALID, "invalid config path selector %d", config_level); + break; } - return val; + giterr_set( + GITERR_INVALID, "invalid config path selector %d", config_level); + return -1; } extern char *git__user_agent; @@ -121,12 +120,15 @@ break; case GIT_OPT_GET_SEARCH_PATH: - if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0) { + { + int sysdir = va_arg(ap, int); git_buf *out = va_arg(ap, git_buf *); const git_buf *tmp; + int level; - git_buf_sanitize(out); - if ((error = git_sysdir_get(&tmp, error)) < 0) + if ((error = config_level_to_sysdir(&level, sysdir)) < 0 || + (error = git_buf_sanitize(out)) < 0 || + (error = git_sysdir_get(&tmp, level)) < 0) break; error = git_buf_sets(out, tmp->ptr); @@ -134,8 +136,12 @@ break; case GIT_OPT_SET_SEARCH_PATH: - if ((error = config_level_to_sysdir(va_arg(ap, int))) >= 0) - error = git_sysdir_set(error, va_arg(ap, const char *)); + { + int level; + + if ((error = config_level_to_sysdir(&level, va_arg(ap, int))) >= 0) + error = git_sysdir_set(level, va_arg(ap, const char *)); + } break; case GIT_OPT_SET_CACHE_OBJECT_LIMIT: @@ -164,8 +170,8 @@ git_buf *out = va_arg(ap, git_buf *); const git_buf *tmp; - git_buf_sanitize(out); - if ((error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0) + if ((error = git_buf_sanitize(out)) < 0 || + (error = git_sysdir_get(&tmp, GIT_SYSDIR_TEMPLATE)) < 0) break; error = git_buf_sets(out, tmp->ptr); @@ -234,7 +240,8 @@ case GIT_OPT_GET_USER_AGENT: { git_buf *out = va_arg(ap, git_buf *); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + break; error = git_buf_sets(out, git__user_agent); } break; diff --git a/src/message.c b/src/message.c index 6c5a2379fc8..327b984fc7c 100644 --- a/src/message.c +++ b/src/message.c @@ -28,8 +28,10 @@ int git_message_prettify(git_buf *message_out, const char *message, int strip_co int consecutive_empty_lines = 0; size_t i, line_length, rtrimmed_line_length; char *next_newline; + int error; - git_buf_sanitize(message_out); + if ((error = git_buf_sanitize(message_out)) < 0) + return error; for (i = 0; i < strlen(message); i += line_length) { next_newline = memchr(message + i, '\n', message_len - i); diff --git a/src/notes.c b/src/notes.c index 68d2ae9ec62..a3c4b7c4fea 100644 --- a/src/notes.c +++ b/src/notes.c @@ -629,9 +629,8 @@ int git_note_default_ref(git_buf *out, git_repository *repo) assert(out && repo); - git_buf_sanitize(out); - - if ((error = note_get_default_ref(&default_ref, repo)) < 0) + if ((error = git_buf_sanitize(out)) < 0 || + (error = note_get_default_ref(&default_ref, repo)) < 0) return error; git_buf_attach(out, default_ref, strlen(default_ref)); diff --git a/src/object.c b/src/object.c index 749b0caf242..fa975347e11 100644 --- a/src/object.c +++ b/src/object.c @@ -495,7 +495,9 @@ int git_object_short_id(git_buf *out, const git_object *obj) assert(out && obj); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; + repo = git_object_owner(obj); # if ((error = git_repository__configmap_lookup(&len, repo, GIT_CONFIGMAP_ABBREV)) < 0) if ((error = git_repository__cvar(&len, repo, GIT_CVAR_ABBREV)) < 0) diff --git a/src/pack-objects.c b/src/pack-objects.c index cf10e6cb5a6..9679e8e23f9 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -1363,8 +1363,13 @@ int git_packbuilder_foreach(git_packbuilder *pb, int (*cb)(void *buf, size_t siz int git_packbuilder_write_buf(git_buf *buf, git_packbuilder *pb) { + int error; + + if ((error = git_buf_sanitize(buf)) < 0) + return error; + PREPARE_PACK; - git_buf_sanitize(buf); + return write_pack(pb, &write_pack_buf, buf); } diff --git a/src/refspec.c b/src/refspec.c index 4245cbbdad7..a778f62b465 100644 --- a/src/refspec.c +++ b/src/refspec.c @@ -245,8 +245,11 @@ static int refspec_transform( # { # const char *from_star, *to_star; const char *from_star, *to_star; const char *name_slash, *from_slash; size_t replacement_len, star_offset; + int error; + + if ((error = git_buf_sanitize(out)) < 0) + return error; - git_buf_sanitize(out); git_buf_clear(out); /* @@ -278,8 +281,12 @@ static int refspec_transform( int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *name) { + int error; + assert(out && spec && name); - git_buf_sanitize(out); + + if ((error = git_buf_sanitize(out)) < 0) + return error; if (!git_refspec_src_matches(spec, name)) { # giterr_set(GIT_ERROR_INVALID, "ref '%s' doesn't match the source", name); giterr_set(GITERR_INVALID, "ref '%s' doesn't match the source", name); @@ -294,8 +301,12 @@ int git_refspec_transform(git_buf *out, const git_refspec *spec, const char *nam int git_refspec_rtransform(git_buf *out, const git_refspec *spec, const char *name) { + int error; + assert(out && spec && name); - git_buf_sanitize(out); + + if ((error = git_buf_sanitize(out)) < 0) + return error; if (!git_refspec_dst_matches(spec, name)) { # giterr_set(GIT_ERROR_INVALID, "ref '%s' doesn't match the destination", name); giterr_set(GITERR_INVALID, "ref '%s' doesn't match the destination", name); diff --git a/src/remote.c b/src/remote.c index f6382486174..a12fa00ba96 100644 --- a/src/remote.c +++ b/src/remote.c #@@ -648,14 +648,17 @@ int git_remote_set_pushurl(git_repository *repo, const char *remote, const char* # # static int resolve_url(git_buf *resolved_url, const char *url, int direction, const git_remote_callbacks *callbacks) # { #- int status; #+ int status, error; # # if (callbacks && callbacks->resolve_url) { # git_buf_clear(resolved_url); # status = callbacks->resolve_url(resolved_url, url, direction, callbacks->payload); # if (status != GIT_PASSTHROUGH) { # git_error_set_after_callback_function(status, "git_resolve_url_cb"); #- git_buf_sanitize(resolved_url); #+ #+ if ((error = git_buf_sanitize(resolved_url)) < 0) #+ return error; #+ # return status; # } # } @@ -2403,7 +2406,8 @@ int git_remote_default_branch(git_buf *out, git_remote *remote) # goto done; # } # if (strcmp(heads[0]->name, GIT_HEAD_FILE)) return GIT_ENOTFOUND; - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; # # /* the first one must be HEAD so if that has the symref info, we're done */ # if (heads[0]->symref_target) { /* the first one must be HEAD so if that has the symref info, we're done */ if (heads[0]->symref_target) return git_buf_puts(out, heads[0]->symref_target); diff --git a/src/repository.c b/src/repository.c index f0d4b06aac1..28cbf3c6c4d 100644 --- a/src/repository.c +++ b/src/repository.c @@ -945,10 +945,12 @@ int git_repository_discover( const char *ceiling_dirs) { uint32_t flags = across_fs ? GIT_REPOSITORY_OPEN_CROSS_FS : 0; + int error; assert(start_path); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; return find_repo(out, NULL, NULL, NULL, start_path, flags, ceiling_dirs); } @@ -2609,7 +2611,8 @@ int git_repository_message(git_buf *out, git_repository *repo) struct stat st; int error; - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; if (git_buf_joinpath(&path, repo->gitdir, GIT_MERGE_MSG_FILE) < 0) return -1; diff --git a/src/submodule.c b/src/submodule.c index c32b9770a9a..8fb3bdb73d9 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -998,7 +998,8 @@ int git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *ur assert(out && repo && url); - git_buf_sanitize(out); + if ((error = git_buf_sanitize(out)) < 0) + return error; /* We do this in all platforms in case someone on Windows created the .gitmodules */ if (strchr(url, '\\')) {
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor