aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-08-06 21:26:31 +0300
committerGarrett D'Amore <garrett@damore.org>2018-08-06 22:51:37 +0300
commit8bea70c68e3f7ac23d4ff10b758af718ffb94263 (patch)
treefa0acc0c76dce541911cd9095c5c78aec31e9f71
parentb717dfefa5b1e8fa20ded02f3a79e2c8d2f24f41 (diff)
downloadnng-8bea70c68e3f7ac23d4ff10b758af718ffb94263.tar.gz
nng-8bea70c68e3f7ac23d4ff10b758af718ffb94263.tar.bz2
nng-8bea70c68e3f7ac23d4ff10b758af718ffb94263.zip
fixes #611 Memory Leaks under Windows
fixes #622 incorrect assumptions about malloc(0) Windows actually allocates an object of size zero when calling malloc on size zero. This is unusual behavior, and we just add logic to work more like malloc on POSIX systems. Other systems can return non-NULL objects to fixed pages here. We think the best option here is to uniformly return NULL from our APIs in these circumstances, and to include testing to validate that.
-rw-r--r--src/platform/posix/posix_alloc.c4
-rw-r--r--src/platform/posix/posix_file.c20
-rw-r--r--src/platform/windows/win_file.c21
-rw-r--r--src/platform/windows/win_thread.c4
-rw-r--r--src/protocol/pubsub0/sub.c10
5 files changed, 36 insertions, 23 deletions
diff --git a/src/platform/posix/posix_alloc.c b/src/platform/posix/posix_alloc.c
index f4b0245c..f0847408 100644
--- a/src/platform/posix/posix_alloc.c
+++ b/src/platform/posix/posix_alloc.c
@@ -17,13 +17,13 @@
void *
nni_alloc(size_t sz)
{
- return (malloc(sz));
+ return (sz > 0 ? malloc(sz) : NULL);
}
void *
nni_zalloc(size_t sz)
{
- return (calloc(1, sz));
+ return (sz > 0 ? calloc(1, sz) : NULL);
}
void
diff --git a/src/platform/posix/posix_file.c b/src/platform/posix/posix_file.c
index b21c0509..5d918d6b 100644
--- a/src/platform/posix/posix_file.c
+++ b/src/platform/posix/posix_file.c
@@ -115,14 +115,18 @@ nni_plat_file_get(const char *name, void **datap, size_t *lenp)
}
len = st.st_size;
- if ((data = nni_alloc(len)) == NULL) {
- rv = NNG_ENOMEM;
- goto done;
- }
- if (fread(data, 1, len, f) != len) {
- rv = nni_plat_errno(errno);
- nni_free(data, len);
- goto done;
+ if (len > 0) {
+ if ((data = nni_alloc(len)) == NULL) {
+ rv = NNG_ENOMEM;
+ goto done;
+ }
+ if (fread(data, 1, len, f) != len) {
+ rv = nni_plat_errno(errno);
+ nni_free(data, len);
+ goto done;
+ }
+ } else {
+ data = NULL;
}
*datap = data;
*lenp = len;
diff --git a/src/platform/windows/win_file.c b/src/platform/windows/win_file.c
index 3b6461a6..47bb87af 100644
--- a/src/platform/windows/win_file.c
+++ b/src/platform/windows/win_file.c
@@ -136,14 +136,19 @@ nni_plat_file_get(const char *name, void **datap, size_t *lenp)
rv = nni_win_error(GetLastError());
goto done;
}
- if ((data = nni_alloc((size_t) sz)) == NULL) {
- rv = NNG_ENOMEM;
- goto done;
- }
- if (!ReadFile(h, data, sz, &nread, NULL)) {
- rv = nni_win_error(GetLastError());
- nni_free(data, sz);
- goto done;
+ if (sz > 0) {
+ if ((data = nni_alloc((size_t) sz)) == NULL) {
+ rv = NNG_ENOMEM;
+ goto done;
+ }
+ if (!ReadFile(h, data, sz, &nread, NULL)) {
+ rv = nni_win_error(GetLastError());
+ nni_free(data, sz);
+ goto done;
+ }
+ } else {
+ data = NULL;
+ nread = 0;
}
// We can get a short read, indicating end of file. We return
diff --git a/src/platform/windows/win_thread.c b/src/platform/windows/win_thread.c
index d6363207..3b4e63bc 100644
--- a/src/platform/windows/win_thread.c
+++ b/src/platform/windows/win_thread.c
@@ -19,13 +19,13 @@
void *
nni_alloc(size_t sz)
{
- return (malloc(sz));
+ return (sz > 0 ? malloc(sz) : NULL);
}
void *
nni_zalloc(size_t sz)
{
- return (calloc(1, sz));
+ return (sz > 0 ? calloc(1, sz) : NULL);
}
void
diff --git a/src/protocol/pubsub0/sub.c b/src/protocol/pubsub0/sub.c
index cb6d781f..aeccfd25 100644
--- a/src/protocol/pubsub0/sub.c
+++ b/src/protocol/pubsub0/sub.c
@@ -228,9 +228,13 @@ sub0_subscribe(void *arg, const void *buf, size_t sz, nni_opt_type t)
nni_mtx_unlock(&s->lk);
return (NNG_ENOMEM);
}
- if ((newtopic->buf = nni_alloc(sz)) == NULL) {
- nni_mtx_unlock(&s->lk);
- return (NNG_ENOMEM);
+ if (sz > 0) {
+ if ((newtopic->buf = nni_alloc(sz)) == NULL) {
+ nni_mtx_unlock(&s->lk);
+ return (NNG_ENOMEM);
+ }
+ } else {
+ newtopic->buf = NULL;
}
NNI_LIST_NODE_INIT(&newtopic->node);
newtopic->len = sz;