From a35e5bd966031f0a76e264fdb387283c2cf46094 Mon Sep 17 00:00:00 2001
From: Deomid Ryabkov <rojer@cesanta.com>
Date: Tue, 25 Apr 2017 13:18:43 +0300
Subject: [PATCH] A function to make a NUL-terminated copy of mg_str

PUBLISHED_FROM=c1310b7d62f3ad6e2f24fea9f5229588c56b0bbe
---
 mongoose.c | 22 +++++++++++++++++-----
 mongoose.h |  8 ++++++++
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/mongoose.c b/mongoose.c
index b116409a6..ce07eed38 100644
--- a/mongoose.c
+++ b/mongoose.c
@@ -1389,19 +1389,31 @@ int mg_vcasecmp(const struct mg_str *str1, const char *str2) {
   return r;
 }
 
-struct mg_str mg_strdup(const struct mg_str s) WEAK;
-struct mg_str mg_strdup(const struct mg_str s) {
+static struct mg_str mg_strdup_common(const struct mg_str s,
+                                      int nul_terminate) {
   struct mg_str r = {NULL, 0};
   if (s.len > 0 && s.p != NULL) {
-    r.p = (char *) MG_MALLOC(s.len);
-    if (r.p != NULL) {
-      memcpy((char *) r.p, s.p, s.len);
+    char *sc = (char *) MG_MALLOC(s.len + (nul_terminate ? 1 : 0));
+    if (sc != NULL) {
+      memcpy(sc, s.p, s.len);
+      if (nul_terminate) sc[s.len] = '\0';
+      r.p = sc;
       r.len = s.len;
     }
   }
   return r;
 }
 
+struct mg_str mg_strdup(const struct mg_str s) WEAK;
+struct mg_str mg_strdup(const struct mg_str s) {
+  return mg_strdup_common(s, 1 /* NUL-terminate */);
+}
+
+struct mg_str mg_strdup_nul(const struct mg_str s) WEAK;
+struct mg_str mg_strdup_nul(const struct mg_str s) {
+  return mg_strdup_common(s, 0 /* NUL-terminate */);
+}
+
 int mg_strcmp(const struct mg_str str1, const struct mg_str str2) WEAK;
 int mg_strcmp(const struct mg_str str1, const struct mg_str str2) {
   size_t i = 0;
diff --git a/mongoose.h b/mongoose.h
index 622923e33..76911e1c1 100644
--- a/mongoose.h
+++ b/mongoose.h
@@ -1789,7 +1789,15 @@ int mg_vcmp(const struct mg_str *str2, const char *str1);
  */
 int mg_vcasecmp(const struct mg_str *str2, const char *str1);
 
+/* Creates a copy of s (heap-allocated). */
 struct mg_str mg_strdup(const struct mg_str s);
+
+/*
+ * Creates a copy of s (heap-allocated).
+ * Resulting string is NUL-terminated (but NUL is not included in len).
+ */
+struct mg_str mg_strdup_nul(const struct mg_str s);
+
 int mg_strcmp(const struct mg_str str1, const struct mg_str str2);
 int mg_strncmp(const struct mg_str str1, const struct mg_str str2, size_t n);
 
-- 
GitLab