From 00c7fe7bb9b7c409c3922431c9fefd348e4f8346 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 14 Aug 2020 13:46:00 +0200 Subject: Make serd_strtod API const-correct This is an API breakage, but a minor one (particularly since NULL is allowed) that avoids the flaw in the standard C API. --- NEWS | 1 + serd/serd.h | 8 +++++--- src/string.c | 6 +++--- tests/serd_test.c | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 86f0e2e2..2e0f3ccb 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ serd (1.0.1) unstable; * Add SerdBuffer for mutable buffers to keep SerdChunk const-correct + * Make serd_strtod API const-correct * Remove useless character counting from API * Rename SerdChunk to SerdStringView * Use char* for strings in public API diff --git a/serd/serd.h b/serd/serd.h index b3ecb850..1963ff6b 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -320,13 +320,15 @@ serd_strlen(const char* str, SerdNodeFlags* flags); /** Parse a string to a double. - The API of this function is identical to the standard C strtod function, + The API of this function is similar to the standard C strtod function, except this function is locale-independent and always matches the lexical - format used in the Turtle grammar (the decimal point is always "."). + format used in the Turtle grammar (the decimal point is always "."). The + end parameter is an offset from the start of `str` to avoid the + const-correctness issues of the strtod API. */ SERD_API double -serd_strtod(const char* str, char** endptr); +serd_strtod(const char* str, size_t* end); /** Decode a base64 string. diff --git a/src/string.c b/src/string.c index 3f068a1d..1e7e9348 100644 --- a/src/string.c +++ b/src/string.c @@ -109,7 +109,7 @@ read_sign(const char** sptr) } double -serd_strtod(const char* str, char** endptr) +serd_strtod(const char* str, size_t* end) { double result = 0.0; @@ -145,8 +145,8 @@ serd_strtod(const char* str, char** endptr) result *= pow(10, expt * expt_sign); } - if (endptr) { - *endptr = (char*)s; + if (end) { + *end = s - str; } return result * sign; diff --git a/tests/serd_test.c b/tests/serd_test.c index ab0a0896..a8853969 100644 --- a/tests/serd_test.c +++ b/tests/serd_test.c @@ -40,11 +40,12 @@ test_strtod(double dbl, double max_delta) char buf[1024]; snprintf(buf, sizeof(buf), "%f", dbl); - char* endptr = NULL; - const double out = serd_strtod(buf, &endptr); + size_t end = 0; + const double out = serd_strtod(buf, &end); const double diff = fabs(out - dbl); assert(diff <= max_delta); + assert(end == strlen(buf)); } typedef struct { -- cgit v1.2.1