1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 
8 #include "stdalloc.h"
9 
stdalloc__malloc(size_t len,const char * file,int line)10 static void *stdalloc__malloc(size_t len, const char *file, int line)
11 {
12 	void *ptr = malloc(len);
13 
14 	GIT_UNUSED(file);
15 	GIT_UNUSED(line);
16 
17 	if (!ptr) git_error_set_oom();
18 	return ptr;
19 }
20 
stdalloc__calloc(size_t nelem,size_t elsize,const char * file,int line)21 static void *stdalloc__calloc(size_t nelem, size_t elsize, const char *file, int line)
22 {
23 	void *ptr = calloc(nelem, elsize);
24 
25 	GIT_UNUSED(file);
26 	GIT_UNUSED(line);
27 
28 	if (!ptr) git_error_set_oom();
29 	return ptr;
30 }
31 
stdalloc__strdup(const char * str,const char * file,int line)32 static char *stdalloc__strdup(const char *str, const char *file, int line)
33 {
34 	char *ptr = strdup(str);
35 
36 	GIT_UNUSED(file);
37 	GIT_UNUSED(line);
38 
39 	if (!ptr) git_error_set_oom();
40 	return ptr;
41 }
42 
stdalloc__strndup(const char * str,size_t n,const char * file,int line)43 static char *stdalloc__strndup(const char *str, size_t n, const char *file, int line)
44 {
45 	size_t length = 0, alloclength;
46 	char *ptr;
47 
48 	length = p_strnlen(str, n);
49 
50 	if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
51 		!(ptr = stdalloc__malloc(alloclength, file, line)))
52 		return NULL;
53 
54 	if (length)
55 		memcpy(ptr, str, length);
56 
57 	ptr[length] = '\0';
58 
59 	return ptr;
60 }
61 
stdalloc__substrdup(const char * start,size_t n,const char * file,int line)62 static char *stdalloc__substrdup(const char *start, size_t n, const char *file, int line)
63 {
64 	char *ptr;
65 	size_t alloclen;
66 
67 	if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
68 		!(ptr = stdalloc__malloc(alloclen, file, line)))
69 		return NULL;
70 
71 	memcpy(ptr, start, n);
72 	ptr[n] = '\0';
73 	return ptr;
74 }
75 
stdalloc__realloc(void * ptr,size_t size,const char * file,int line)76 static void *stdalloc__realloc(void *ptr, size_t size, const char *file, int line)
77 {
78 	void *new_ptr = realloc(ptr, size);
79 
80 	GIT_UNUSED(file);
81 	GIT_UNUSED(line);
82 
83 	if (!new_ptr) git_error_set_oom();
84 	return new_ptr;
85 }
86 
stdalloc__reallocarray(void * ptr,size_t nelem,size_t elsize,const char * file,int line)87 static void *stdalloc__reallocarray(void *ptr, size_t nelem, size_t elsize, const char *file, int line)
88 {
89 	size_t newsize;
90 
91 	if (GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize))
92 		return NULL;
93 
94 	return stdalloc__realloc(ptr, newsize, file, line);
95 }
96 
stdalloc__mallocarray(size_t nelem,size_t elsize,const char * file,int line)97 static void *stdalloc__mallocarray(size_t nelem, size_t elsize, const char *file, int line)
98 {
99 	return stdalloc__reallocarray(NULL, nelem, elsize, file, line);
100 }
101 
stdalloc__free(void * ptr)102 static void stdalloc__free(void *ptr)
103 {
104 	free(ptr);
105 }
106 
git_stdalloc_init_allocator(git_allocator * allocator)107 int git_stdalloc_init_allocator(git_allocator *allocator)
108 {
109 	allocator->gmalloc = stdalloc__malloc;
110 	allocator->gcalloc = stdalloc__calloc;
111 	allocator->gstrdup = stdalloc__strdup;
112 	allocator->gstrndup = stdalloc__strndup;
113 	allocator->gsubstrdup = stdalloc__substrdup;
114 	allocator->grealloc = stdalloc__realloc;
115 	allocator->greallocarray = stdalloc__reallocarray;
116 	allocator->gmallocarray = stdalloc__mallocarray;
117 	allocator->gfree = stdalloc__free;
118 	return 0;
119 }
120