aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShelley Vohr <shelley.vohr@gmail.com>2018-06-20 10:01:57 -0700
committerSantiago Gimeno <santiago.gimeno@gmail.com>2018-07-06 19:35:21 +0200
commit5124b27d355a868a07c51ca694c45b32b10f89b5 (patch)
treeffcd0664ea156ad315b775f6f60ab2a35e4a9efb
parentb16d10a0177c32d6a9442d0758031cac8a5db36e (diff)
downloadlibuv-5124b27d355a868a07c51ca694c45b32b10f89b5.tar.gz
libuv-5124b27d355a868a07c51ca694c45b32b10f89b5.zip
src: add new error apis to prevent memory leaks
This PR creates two new externally-facing APIs, uv_err_name_r() and uv_strerror_r(). In keeping with the precedent set by POSIX, the *_r() suffix of these two new methods indicate that the caller does the memory management and passes in the memory that the output will be stored in, which provides an alternative for the two existent methods (uv_err_name() and uv_strerror()), which, when called with an unknown error code, leak a few bytes of memory. PR-URL: https://github.com/libuv/libuv/pull/1898 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Santiago Gimeno santiago.gimeno@gmail.com
-rw-r--r--docs/src/errors.rst14
-rw-r--r--include/uv.h3
-rw-r--r--src/uv-common.c25
-rw-r--r--test/test-error.c6
4 files changed, 48 insertions, 0 deletions
diff --git a/docs/src/errors.rst b/docs/src/errors.rst
index 7c3f95d7..b8f971f5 100644
--- a/docs/src/errors.rst
+++ b/docs/src/errors.rst
@@ -335,11 +335,25 @@ API
Returns the error message for the given error code. Leaks a few bytes
of memory when you call it with an unknown error code.
+.. c:function:: char* uv_strerror_r(int err, char* buf, size_t buflen)
+
+ Returns the error message for the given error code. The zero-terminated
+ message is stored in the user-supplied buffer `buf` of at most `buflen` bytes.
+
+ .. versionadded:: 1.22.0
+
.. c:function:: const char* uv_err_name(int err)
Returns the error name for the given error code. Leaks a few bytes
of memory when you call it with an unknown error code.
+.. c:function:: char* uv_err_name_r(int err, char* buf, size_t buflen)
+
+ Returns the error name for the given error code. The zero-terminated
+ name is stored in the user-supplied buffer `buf` of at most `buflen` bytes.
+
+ .. versionadded:: 1.22.0
+
.. c:function:: int uv_translate_sys_error(int sys_errno)
Returns the libuv error code equivalent to the given platform dependent error
diff --git a/include/uv.h b/include/uv.h
index 91451ada..7565769c 100644
--- a/include/uv.h
+++ b/include/uv.h
@@ -370,7 +370,10 @@ typedef enum {
UV_EXTERN int uv_translate_sys_error(int sys_errno);
UV_EXTERN const char* uv_strerror(int err);
+UV_EXTERN char* uv_strerror_r(int err, char* buf, size_t buflen);
+
UV_EXTERN const char* uv_err_name(int err);
+UV_EXTERN char* uv_err_name_r(int err, char* buf, size_t buflen);
#define UV_REQ_FIELDS \
diff --git a/src/uv-common.c b/src/uv-common.c
index 1146cfa3..f0aec452 100644
--- a/src/uv-common.c
+++ b/src/uv-common.c
@@ -155,6 +155,18 @@ static const char* uv__unknown_err_code(int err) {
return copy != NULL ? copy : "Unknown system error";
}
+#define UV_ERR_NAME_GEN_R(name, _) \
+case UV_## name: \
+ snprintf(buf, buflen, "%s", #name); break;
+char* uv_err_name_r(int err, char* buf, size_t buflen) {
+ switch (err) {
+ UV_ERRNO_MAP(UV_ERR_NAME_GEN_R)
+ default: snprintf(buf, buflen, "Unknown system error %d", err);
+ }
+ return buf;
+}
+#undef UV_ERR_NAME_GEN_R
+
#define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name;
const char* uv_err_name(int err) {
@@ -166,6 +178,19 @@ const char* uv_err_name(int err) {
#undef UV_ERR_NAME_GEN
+#define UV_STRERROR_GEN_R(name, msg) \
+case UV_ ## name: \
+ snprintf(buf, buflen, "%s", msg); break;
+char* uv_strerror_r(int err, char* buf, size_t buflen) {
+ switch (err) {
+ UV_ERRNO_MAP(UV_STRERROR_GEN_R)
+ default: snprintf(buf, buflen, "Unknown system error %d", err);
+ }
+ return buf;
+}
+#undef UV_STRERROR_GEN_R
+
+
#define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg;
const char* uv_strerror(int err) {
switch (err) {
diff --git a/test/test-error.c b/test/test-error.c
index a2d559a4..7f44f4a1 100644
--- a/test/test-error.c
+++ b/test/test-error.c
@@ -37,6 +37,8 @@
* See https://github.com/joyent/libuv/issues/210
*/
TEST_IMPL(error_message) {
+ char buf[32];
+
/* Cop out. Can't do proper checks on systems with
* i18n-ized error messages...
*/
@@ -49,6 +51,10 @@ TEST_IMPL(error_message) {
ASSERT(strcmp(uv_strerror(1337), "Unknown error") == 0);
ASSERT(strcmp(uv_strerror(-1337), "Unknown error") == 0);
+ ASSERT(strstr(uv_strerror_r(UV_EINVAL, buf, sizeof(buf)), "Success") == NULL);
+ ASSERT(strstr(uv_strerror_r(1337, buf, sizeof(buf)), "1337") != NULL);
+ ASSERT(strstr(uv_strerror_r(-1337, buf, sizeof(buf)), "-1337") != NULL);
+
return 0;
}