]> git.draconx.ca Git - cdecl99.git/commitdiff
libcdecl: Sidestep some possible snprintf issues.
authorNick Bowler <nbowler@draconx.ca>
Thu, 20 Jul 2023 02:12:24 +0000 (22:12 -0400)
committerNick Bowler <nbowler@draconx.ca>
Thu, 20 Jul 2023 02:12:24 +0000 (22:12 -0400)
Adjust cdecl__emit to avoid some known problems with snprintf
implementations:

 * some implementations (e.g., newlib 1.8.2) write to the destination
   when the size is zero.
 * some implementations (e.g., HP-UX 11) return -1 when the string is
   truncated.
 * some implementations (e.g., the replacement provided by gnulib!)
   allocate memory even for trivial conversions and return -1 on malloc
   failure.

Since we currently use gnulib, only the last one is presently a concern,
but the plan is to eventually remove the library dependency on gnulib
snprintf since in reality we barely need any snprintf functionality.

Adjust the cdecl__emit implementation to simply avoid tripping over these
sorts of problems.  Other snprintf calls in the library remain as before.

src/output.c

index 62c9c8f9bd0839330de432fde4ea79dac5d9f947..1075221b7e0aabebcd6b779638d3fa3b46d03a54 100644 (file)
@@ -38,9 +38,16 @@ size_t cdecl__advance(struct output_state *dst, size_t amount)
        return amount;
 }
 
+static size_t cdecl__strlcpy(char *dst, const char *src, size_t dstlen)
+{
+       if (dst)
+               snprintf(dst, dstlen, "%s", src);
+       return strlen(src);
+}
+
 size_t cdecl__emit(struct output_state *dst, const char *src)
 {
-       size_t rc = snprintf(dst->dst, dst->dstlen, "%s", src);
+       size_t rc = cdecl__strlcpy(dst->dst, src, dst->dstlen);
        return cdecl__advance(dst, rc);
 }