BUG: Robustify nulldup definition.
Probably unnecessary, but should avoid a warning and documents what happens.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <errno.h>
#include <windows.h>
#include <errhandlingapi.h>
@@ -29,13 +30,67 @@ static const char* driveletters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS
static int isAbsolutePath(const char* path);
#if !defined(nulldup) && !defined(HAVE_STRDUP)
+/** Copy s if not NULL.
+ *
+ * Implementation in terms of strdup in
+ *
+ * @li include/ncconfigure.h
+ * @li include/netcdf_json.h
+ * @li libdap4/ncd4.h
+ * @li libdispatch/dfile.c
+ * @li libdispatch/dinfermodel.c
+ * @li libdispatch/drc.c
+ * @li libdispatch/dutil.c
+ * @li libdispatch/nc.c
+ * @li libdispatch/ncjson.c
+ * @li libdispatch/ncurl.c
+ * @li libncxml/ncxml_ezxml.c
+ * @li ncxml_tinyxml2.cpp
+ * @li libncxml/ncxml_xml2.c
+ * @li libnczarr/zsync.c
+ * @li ncdump/ocprint.c
+ * @li ncgen/cvt.c
+ * @li ncgen/ncgen.h
+ * @li ncgen3/ncgen.h
+ * @li nczarr_test/test_nczarr_utils.h
+ * @li oc2/ocinternal.h
+ *
+ * Declarations as extern:
+ *
+ * @li include/ncconfigure.h
+ *
+ * I'd like it to be
+ * static inline const char *nulldup(const char *const s);
+ * but that's not what's in ncconfigure.h
+ *
+ * @param s the string to duplicate
+ * @pre s is either NULL or a NULL-terminated string
+ *
+ * @returns NULL or the duplicated string (caller owns the new
+ * pointer)
+ *
+ * @throws ENOMEM if out of memory
+ *
+ * @post returns NULL if s is NULL, or a new pointer to a
+ * freshly-allocated copy of s
+ */
extern char *nulldup(const char* s) {
- if (s) {
- char *result = malloc(strlen(s) + 1);
- strcpy(result, s);
+ if (s != NULL) {
+ ssize_t result_length = strlen(s) + 1;
+ char *result = malloc(result_length);
+ if (result == NULL) {
+#ifdef ENOMEM
+ /* C++11, POSIX? */
+ errno = ENOMEM;
+#else
+ errno = 1;
+#endif
+ return NULL;
+ }
+ strncpy(result, s, result_length);
return result;
} else {
- return s;
+ return NULL;
}
}
#endif
