Commit efe3f37d by Nelson Elhage

Add a git_libgit2_opts option to set the max indexer object count

parent 912c59c9
...@@ -195,7 +195,9 @@ typedef enum { ...@@ -195,7 +195,9 @@ typedef enum {
GIT_OPT_SET_WINDOWS_SHAREMODE, GIT_OPT_SET_WINDOWS_SHAREMODE,
GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION,
GIT_OPT_SET_ALLOCATOR, GIT_OPT_SET_ALLOCATOR,
GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY GIT_OPT_ENABLE_UNSAVED_INDEX_SAFETY,
GIT_OPT_GET_INDEXER_MAX_OBJECTS,
GIT_OPT_SET_INDEXER_MAX_OBJECTS
} git_libgit2_opt_t; } git_libgit2_opt_t;
/** /**
...@@ -372,6 +374,18 @@ typedef enum { ...@@ -372,6 +374,18 @@ typedef enum {
* > fail. (Using the FORCE flag to checkout will still overwrite * > fail. (Using the FORCE flag to checkout will still overwrite
* > these changes.) * > these changes.)
* *
* opts(GIT_OPT_GET_INDEXER_MAX_OBJECTS, size_t *out)
*
* > Get the maximum number of objects libgit2 will allow in a pack
* > file when downloading a pack file from a remote. This can be
* > used to limit maximum memory usage when fetching from an untrusted
* > remote.
*
* opts(GIT_OPT_SET_INDEXER_MAX_OBJECTS, size_t objects)
*
* > Set the maximum number of objects libgit2 will allow in a pack
* > file when downloading a pack file from a remote.
*
* @param option Option key * @param option Option key
* @param ... value to set the option * @param ... value to set the option
* @return 0 on success, <0 on failure * @return 0 on success, <0 on failure
......
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
extern git_mutex git__mwindow_mutex; extern git_mutex git__mwindow_mutex;
size_t git_indexer__max_objects = (1ul << 32);
#define UINT31_MAX (0x7FFFFFFF) #define UINT31_MAX (0x7FFFFFFF)
struct entry { struct entry {
...@@ -557,17 +559,12 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran ...@@ -557,17 +559,12 @@ int git_indexer_append(git_indexer *idx, const void *data, size_t size, git_tran
idx->nr_objects = ntohl(hdr->hdr_entries); idx->nr_objects = ntohl(hdr->hdr_entries);
idx->off = sizeof(struct git_pack_header); idx->off = sizeof(struct git_pack_header);
/* for now, limit to 2^32 objects */ if (idx->nr_objects <= git_indexer__max_objects) {
assert(idx->nr_objects == (size_t)((unsigned int)idx->nr_objects));
if (idx->nr_objects == (size_t)((unsigned int)idx->nr_objects))
total_objects = (unsigned int)idx->nr_objects; total_objects = (unsigned int)idx->nr_objects;
else } else {
total_objects = UINT_MAX; giterr_set(GITERR_INDEXER, "too many objects");
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION return -1;
if (total_objects > 4096) {
total_objects = 4096;
} }
#endif
idx->pack->idx_cache = git_oidmap_alloc(); idx->pack->idx_cache = git_oidmap_alloc();
GITERR_CHECK_ALLOC(idx->pack->idx_cache); GITERR_CHECK_ALLOC(idx->pack->idx_cache);
......
...@@ -56,6 +56,7 @@ int git_libgit2_features(void) ...@@ -56,6 +56,7 @@ int git_libgit2_features(void)
/* Declarations for tuneable settings */ /* Declarations for tuneable settings */
extern size_t git_mwindow__window_size; extern size_t git_mwindow__window_size;
extern size_t git_mwindow__mapped_limit; 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 config_level)
{ {
...@@ -270,6 +271,14 @@ int git_libgit2_opts(int key, ...) ...@@ -270,6 +271,14 @@ int git_libgit2_opts(int key, ...)
git_index__enforce_unsaved_safety = (va_arg(ap, int) != 0); git_index__enforce_unsaved_safety = (va_arg(ap, int) != 0);
break; break;
case GIT_OPT_SET_INDEXER_MAX_OBJECTS:
git_indexer__max_objects = va_arg(ap, size_t);
break;
case GIT_OPT_GET_INDEXER_MAX_OBJECTS:
*(va_arg(ap, size_t *)) = git_indexer__max_objects;
break;
default: default:
giterr_set(GITERR_INVALID, "invalid option key"); giterr_set(GITERR_INVALID, "invalid option key");
error = -1; error = -1;
...@@ -279,4 +288,3 @@ int git_libgit2_opts(int key, ...) ...@@ -279,4 +288,3 @@ int git_libgit2_opts(int key, ...)
return error; return error;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment