diff --git a/mongoose.c b/mongoose.c index 200e750f..3cd70896 100644 --- a/mongoose.c +++ b/mongoose.c @@ -6633,8 +6633,7 @@ void mg_rpc_add(struct mg_rpc **head, struct mg_str method, void (*fn)(struct mg_rpc_req *), void *fn_data) { struct mg_rpc *rpc = (struct mg_rpc *) calloc(1, sizeof(*rpc)); if (rpc != NULL) { - rpc->method.buf = mg_mprintf("%.*s", method.len, method.buf); - rpc->method.len = method.len; + rpc->method = mg_strdup(method); rpc->fn = fn; rpc->fn_data = fn_data; rpc->next = *head, *head = rpc; @@ -8048,6 +8047,20 @@ int mg_casecmp(const char *s1, const char *s2) { return diff; } +struct mg_str mg_strdup(const struct mg_str s) { + struct mg_str r = {NULL, 0}; + if (s.len > 0 && s.buf != NULL) { + char *sc = (char *) calloc(1, s.len + 1); + if (sc != NULL) { + memcpy(sc, s.buf, s.len); + sc[s.len] = '\0'; + r.buf = sc; + r.len = s.len; + } + } + return r; +} + int mg_strcmp(const struct mg_str str1, const struct mg_str str2) { size_t i = 0; while (i < str1.len && i < str2.len) { @@ -10605,8 +10618,7 @@ static int mg_parse_pem(const struct mg_str pem, const struct mg_str label, const char *c; struct mg_str caps[5]; if (!mg_match(pem, mg_str("#-----BEGIN #-----#-----END #-----#"), caps)) { - der->buf = mg_mprintf("%.*s", pem.len, pem.buf); - der->len = pem.len; + *der = mg_strdup(pem); return 0; } if (mg_strcmp(caps[1], label) != 0 || mg_strcmp(caps[3], label) != 0) { diff --git a/mongoose.h b/mongoose.h index 10f04be5..79f0d6e7 100644 --- a/mongoose.h +++ b/mongoose.h @@ -186,7 +186,7 @@ extern "C" { #define calloc(a, b) mg_calloc(a, b) #define free(a) vPortFree(a) #define malloc(a) pvPortMalloc(a) -#define strdup(s) mg_mprintf("%s", s) +#define strdup(s) ((char *) mg_strdup(mg_str(s)).buf) // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib static inline void *mg_calloc(size_t cnt, size_t size) { @@ -288,7 +288,7 @@ extern uint32_t rt_time_get(void); #include "cmsis_os2.h" // keep this include #endif -#define strdup(s) mg_mprintf("%s", s) +#define strdup(s) ((char *) mg_strdup(mg_str(s)).buf) #if defined(__ARMCC_VERSION) #define mode_t size_t @@ -861,6 +861,7 @@ struct mg_str mg_str_n(const char *s, size_t n); int mg_casecmp(const char *s1, const char *s2); int mg_strcmp(const struct mg_str str1, const struct mg_str str2); int mg_strcasecmp(const struct mg_str str1, const struct mg_str str2); +struct mg_str mg_strdup(const struct mg_str s); bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str *caps); bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char delim); diff --git a/src/arch_freertos.h b/src/arch_freertos.h index 9ad78998..e3d81bd7 100644 --- a/src/arch_freertos.h +++ b/src/arch_freertos.h @@ -32,7 +32,7 @@ #define calloc(a, b) mg_calloc(a, b) #define free(a) vPortFree(a) #define malloc(a) pvPortMalloc(a) -#define strdup(s) mg_mprintf("%s", s) +#define strdup(s) ((char *) mg_strdup(mg_str(s)).buf) // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib static inline void *mg_calloc(size_t cnt, size_t size) { diff --git a/src/arch_rtx.h b/src/arch_rtx.h index cbf79d25..a6008db7 100644 --- a/src/arch_rtx.h +++ b/src/arch_rtx.h @@ -22,7 +22,7 @@ extern uint32_t rt_time_get(void); #include "cmsis_os2.h" // keep this include #endif -#define strdup(s) mg_mprintf("%s", s) +#define strdup(s) ((char *) mg_strdup(mg_str(s)).buf) #if defined(__ARMCC_VERSION) #define mode_t size_t diff --git a/src/rpc.c b/src/rpc.c index 509a2be4..9efe9671 100644 --- a/src/rpc.c +++ b/src/rpc.c @@ -5,8 +5,7 @@ void mg_rpc_add(struct mg_rpc **head, struct mg_str method, void (*fn)(struct mg_rpc_req *), void *fn_data) { struct mg_rpc *rpc = (struct mg_rpc *) calloc(1, sizeof(*rpc)); if (rpc != NULL) { - rpc->method.buf = mg_mprintf("%.*s", method.len, method.buf); - rpc->method.len = method.len; + rpc->method = mg_strdup(method); rpc->fn = fn; rpc->fn_data = fn_data; rpc->next = *head, *head = rpc; diff --git a/src/str.c b/src/str.c index c0edf373..cb997092 100644 --- a/src/str.c +++ b/src/str.c @@ -23,6 +23,20 @@ int mg_casecmp(const char *s1, const char *s2) { return diff; } +struct mg_str mg_strdup(const struct mg_str s) { + struct mg_str r = {NULL, 0}; + if (s.len > 0 && s.buf != NULL) { + char *sc = (char *) calloc(1, s.len + 1); + if (sc != NULL) { + memcpy(sc, s.buf, s.len); + sc[s.len] = '\0'; + r.buf = sc; + r.len = s.len; + } + } + return r; +} + int mg_strcmp(const struct mg_str str1, const struct mg_str str2) { size_t i = 0; while (i < str1.len && i < str2.len) { diff --git a/src/str.h b/src/str.h index 1cb446e2..ffeded37 100644 --- a/src/str.h +++ b/src/str.h @@ -16,6 +16,7 @@ struct mg_str mg_str_n(const char *s, size_t n); int mg_casecmp(const char *s1, const char *s2); int mg_strcmp(const struct mg_str str1, const struct mg_str str2); int mg_strcasecmp(const struct mg_str str1, const struct mg_str str2); +struct mg_str mg_strdup(const struct mg_str s); bool mg_match(struct mg_str str, struct mg_str pattern, struct mg_str *caps); bool mg_span(struct mg_str s, struct mg_str *a, struct mg_str *b, char delim); diff --git a/src/tls_builtin.c b/src/tls_builtin.c index ece5dad5..781fdb9d 100644 --- a/src/tls_builtin.c +++ b/src/tls_builtin.c @@ -1233,8 +1233,7 @@ static int mg_parse_pem(const struct mg_str pem, const struct mg_str label, const char *c; struct mg_str caps[5]; if (!mg_match(pem, mg_str("#-----BEGIN #-----#-----END #-----#"), caps)) { - der->buf = mg_mprintf("%.*s", pem.len, pem.buf); - der->len = pem.len; + *der = mg_strdup(pem); return 0; } if (mg_strcmp(caps[1], label) != 0 || mg_strcmp(caps[3], label) != 0) { diff --git a/test/unit_test.c b/test/unit_test.c index 3691476f..8e90f706 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -1854,6 +1854,12 @@ static bool chkdbl(struct mg_str s, double val) { } static void test_str(void) { + { + struct mg_str s = mg_strdup(mg_str("a")); + ASSERT(mg_strcmp(s, mg_str("a")) == 0); + free((void *) s.buf); + } + { const char *s; struct mg_str a = mg_str("hello"), b = mg_str("a"), c = mg_str(NULL); diff --git a/tutorials/core/multi-threaded/main.c b/tutorials/core/multi-threaded/main.c index efc439ee..6200e18e 100644 --- a/tutorials/core/multi-threaded/main.c +++ b/tutorials/core/multi-threaded/main.c @@ -50,8 +50,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { // Multithreading code path struct thread_data *data = (struct thread_data *) calloc(1, sizeof(*data)); // Worker owns it - data->message.buf = mg_mprintf("%.*s", hm->message.len, hm->message.buf); - data->message.len = hm->message.len; // Pass message + data->message = mg_strdup(hm->message); // Pass message data->conn_id = c->id; data->mgr = c->mgr; start_thread(thread_function, data); // Start thread and pass data diff --git a/tutorials/mqtt/mqtt-server/main.c b/tutorials/mqtt/mqtt-server/main.c index 4d32eef6..5d188c27 100644 --- a/tutorials/mqtt/mqtt-server/main.c +++ b/tutorials/mqtt/mqtt-server/main.c @@ -80,8 +80,7 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) { while ((pos = mg_mqtt_next_sub(mm, &topic, &qos, pos)) > 0) { struct sub *sub = calloc(1, sizeof(*sub)); sub->c = c; - sub->topic.buf = mg_mprintf("%.*s", topic.len, topic.buf); - sub->topic.len = topic.len; + sub->topic = mg_strdup(topic); sub->qos = qos; LIST_ADD_HEAD(struct sub, &s_subs, sub); MG_INFO(