]> git.proxmox.com Git - libgit2.git/blob - src/allocators/win32_leakcheck.c
fe06a14af738023c0a8b7c7fc7b32ab6e36c8a5c
[libgit2.git] / src / allocators / win32_leakcheck.c
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 "win32_leakcheck.h"
9
10 #if defined(GIT_WIN32_LEAKCHECK)
11
12 #include "win32/w32_leakcheck.h"
13
14 static void *leakcheck_malloc(size_t len, const char *file, int line)
15 {
16 void *ptr = _malloc_dbg(len, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line);
17 if (!ptr) git_error_set_oom();
18 return ptr;
19 }
20
21 static void *leakcheck_calloc(size_t nelem, size_t elsize, const char *file, int line)
22 {
23 void *ptr = _calloc_dbg(nelem, elsize, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line);
24 if (!ptr) git_error_set_oom();
25 return ptr;
26 }
27
28 static char *leakcheck_strdup(const char *str, const char *file, int line)
29 {
30 char *ptr = _strdup_dbg(str, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line);
31 if (!ptr) git_error_set_oom();
32 return ptr;
33 }
34
35 static char *leakcheck_strndup(const char *str, size_t n, const char *file, int line)
36 {
37 size_t length = 0, alloclength;
38 char *ptr;
39
40 length = p_strnlen(str, n);
41
42 if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
43 !(ptr = leakcheck_malloc(alloclength, file, line)))
44 return NULL;
45
46 if (length)
47 memcpy(ptr, str, length);
48
49 ptr[length] = '\0';
50
51 return ptr;
52 }
53
54 static char *leakcheck_substrdup(const char *start, size_t n, const char *file, int line)
55 {
56 char *ptr;
57 size_t alloclen;
58
59 if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
60 !(ptr = leakcheck_malloc(alloclen, file, line)))
61 return NULL;
62
63 memcpy(ptr, start, n);
64 ptr[n] = '\0';
65 return ptr;
66 }
67
68 static void *leakcheck_realloc(void *ptr, size_t size, const char *file, int line)
69 {
70 void *new_ptr = _realloc_dbg(ptr, size, _NORMAL_BLOCK, git_win32_leakcheck_stacktrace(1,file), line);
71 if (!new_ptr) git_error_set_oom();
72 return new_ptr;
73 }
74
75 static void *leakcheck_reallocarray(void *ptr, size_t nelem, size_t elsize, const char *file, int line)
76 {
77 size_t newsize;
78
79 if (GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize))
80 return NULL;
81
82 return leakcheck_realloc(ptr, newsize, file, line);
83 }
84
85 static void *leakcheck_mallocarray(size_t nelem, size_t elsize, const char *file, int line)
86 {
87 return leakcheck_reallocarray(NULL, nelem, elsize, file, line);
88 }
89
90 static void leakcheck_free(void *ptr)
91 {
92 free(ptr);
93 }
94
95 int git_win32_leakcheck_init_allocator(git_allocator *allocator)
96 {
97 allocator->gmalloc = leakcheck_malloc;
98 allocator->gcalloc = leakcheck_calloc;
99 allocator->gstrdup = leakcheck_strdup;
100 allocator->gstrndup = leakcheck_strndup;
101 allocator->gsubstrdup = leakcheck_substrdup;
102 allocator->grealloc = leakcheck_realloc;
103 allocator->greallocarray = leakcheck_reallocarray;
104 allocator->gmallocarray = leakcheck_mallocarray;
105 allocator->gfree = leakcheck_free;
106 return 0;
107 }
108
109 #else
110
111 int git_win32_leakcheck_init_allocator(git_allocator *allocator)
112 {
113 GIT_UNUSED(allocator);
114 git_error_set(GIT_EINVALID, "leakcheck memory allocator not available");
115 return -1;
116 }
117
118 #endif