Welcome to little lamb

Code » limb » commit 2c82236

escall_fmt(): Don't ENOBUFS without a dst

author Olivier Brunel
2023-05-04 17:03:50 UTC
committer Olivier Brunel
2023-05-20 18:06:40 UTC
parent 20b9643bccd89f6f0a5b8df028c2f4a6d272f348

escall_fmt(): Don't ENOBUFS without a dst

Since we allow dst to be NULL, we shouldn't test that there's enough
room to write, as we're only computing how much space would be needed to
actually write.

src/liblimb/esc.h/escall_fmt.c +12 -6

diff --git a/src/liblimb/esc.h/escall_fmt.c b/src/liblimb/esc.h/escall_fmt.c
index a95e1bc..aaa9a12 100644
--- a/src/liblimb/esc.h/escall_fmt.c
+++ b/src/liblimb/esc.h/escall_fmt.c
@@ -12,7 +12,7 @@
 int
 escall_fmt(char *dst, size_t dlen, const char *sce, size_t slen, size_t *w, size_t *r)
 {
-    if (*w > dlen || *r > slen) return (errno = EINVAL, 0);
+    if ((dst && *w > dlen) || *r > slen) return (errno = EINVAL, 0);
 
     while ((!dst || *w < dlen) && *r < slen) {
         /* printable ASCII chars we can directly put */
@@ -23,8 +23,9 @@ escall_fmt(char *dst, size_t dlen, const char *sce, size_t slen, size_t *w, size
         } else {
             /* basic backslash escaping */
             if (sce[*r] == '\\' || sce[*r] == '"') {
-                if (*w + 2 > dlen) return (errno = ENOBUFS, 0);
                 if (dst) {
+                    if (*w + 2 > dlen)
+                        return (errno = ENOBUFS, 0);
                     dst[*w] = '\\';
                     dst[*w + 1] = sce[*r];
                 }
@@ -32,8 +33,9 @@ escall_fmt(char *dst, size_t dlen, const char *sce, size_t slen, size_t *w, size
                 *r += 1;
             /* simple backslash escaping */
             } else if (sce[*r] >= 7 && sce[*r] <= 13) {
-                if (*w + 2 > dlen) return (errno = ENOBUFS, 0);
                 if (dst) {
+                    if (*w + 2 > dlen)
+                        return (errno = ENOBUFS, 0);
                     const char esc[7] = "abtnvfr";
                     dst[*w] = '\\';
                     dst[*w + 1] = esc[sce[*r] - 7];
@@ -47,8 +49,11 @@ escall_fmt(char *dst, size_t dlen, const char *sce, size_t slen, size_t *w, size
                 size_t l = mbrtowc(&wc, sce + *r, slen - *r, &state);
                 /* if it is one and is printable, put the bytes */
                 if (l && l != (size_t) -2 && l != (size_t) -1 && iswprint(wc)) {
-                    if (*w + l > dlen) return (errno = ENOBUFS, 0);
-                    if (dst) memcpy(dst + *w, sce + *r, l);
+                    if (dst) {
+                        if (*w + l > dlen)
+                            return (errno = ENOBUFS, 0);
+                        memcpy(dst + *w, sce + *r, l);
+                    }
                     *w += l;
                     *r += l;
                 /* just a single-byte char */
@@ -58,8 +63,9 @@ escall_fmt(char *dst, size_t dlen, const char *sce, size_t slen, size_t *w, size
                     ++*r;
                 /* hexa-escaping */
                 } else {
-                    if (*w + 4 > dlen) return (errno = ENOBUFS, 0);
                     if (dst) {
+                        if (*w + 4 > dlen)
+                            return (errno = ENOBUFS, 0);
                         dst[*w] = '\\';
                         dst[*w + 1] = 'x';
                         ucharn_fmt(dst + *w + 2, sce + *r, 1);