]> diplodocus.org Git - nmh/blobdiff - sbr/utils.c
Fix invalid pointer arithmetic.
[nmh] / sbr / utils.c
index 8bd84c39cd07563c4c8d4d8a9976b8257e37e3ce..8debe1aaedb0f1f25be8bd5b96bd61f148bf7e32 100644 (file)
@@ -11,6 +11,8 @@
 #include "m_mktemp.h"
 #include "makedir.h"
 #include <fcntl.h>
+#include <limits.h>
+#include "read_line.h"
 
 extern char *mhdocdir;
 
@@ -46,7 +48,7 @@ void *mh_xrealloc(void *ptr, size_t size)
 
     /* Copy POSIX behaviour, coping with non-POSIX systems. */
     if (size == 0) {
-        mh_xfree(ptr);
+        free(ptr);
         return mh_xmalloc(1); /* Get a unique pointer. */
     }
     if (!ptr)
@@ -87,13 +89,6 @@ char *mh_xstrdup(const char *src)
     return dest;
 }
 
-/* Call free(3), if ptr isn't NULL. */
-void mh_xfree(void *ptr)
-{
-    if (ptr)
-        free(ptr); /* Some very old platforms can't cope with NULL. */
-}
-
 /*
  * Return the present working directory, if the current directory does not
  * exist, or is too long, make / the pwd.
@@ -267,22 +262,6 @@ app_msgnum(struct msgnum_array *msgs, int msgnum)
        msgs->msgnums[msgs->size++] = msgnum;
 }
 
-/* Open a form or components file */
-int
-open_form(char **form, char *def)
-{
-       int in;
-       if (*form) {
-               if ((in = open (etcpath (*form), O_RDONLY)) == NOTOK)
-                       adios (*form, "unable to open form file");
-       } else {
-               if ((in = open (etcpath (def), O_RDONLY)) == NOTOK)
-                       adios (def, "unable to open default components file");
-               *form = def;
-       }
-       return in;
-}
-
 
 /*
  * Finds first occurrence of str in buf.  buf is not a C string but a
@@ -547,24 +526,30 @@ nmh_version_changed (int older) {
 }
 
 
-/*
- * Scan for any 8-bit characters.  Return 1 if they exist.
- *
- * Scan up until the given endpoint (but not the actual endpoint itself).
- * If the endpoint is NULL, scan until a '\0' is reached.
- */
-
-int
-contains8bit(const char *start, const char *end)
+/* contains8bit returns true if any byte from start onwards fails
+ * isascii(3), i.e. is outside [0, 0x7f].  If start is NULL it returns
+ * false.  Bytes are examined until a NUL byte, or, if end is not NULL,
+ * whilst start is before end. */
+bool contains8bit(const char *start, const char *end)
 {
-    if (! start)
-       return 0;
+    const char *p;
+    char c;
 
-    while (*start != '\0' && (!end || (start < end)))
-       if (! isascii((unsigned char) *start++))
-           return 1;
+    if (!start)
+        return false;
 
-    return 0;
+    p = start;
+    if (end) {
+        while (p < end && (c = (*p++)))
+            if (!isascii((unsigned char)c))
+                return true;
+    } else {
+        while ((c = (*p++)))
+            if (!isascii((unsigned char)c))
+                return true;
+    }
+
+    return false;
 }
 
 
@@ -577,7 +562,7 @@ scan_input (int fd, int *eightbit) {
     char buf[BUFSIZ];
 
     *eightbit = 0;
-    lseek (fd, (off_t) 0, SEEK_SET);
+    lseek(fd, 0, SEEK_SET);
 
     while ((state = read (fd, buf, sizeof buf)) > 0) {
         if (contains8bit (buf, buf + state)) {
@@ -588,3 +573,32 @@ scan_input (int fd, int *eightbit) {
 
     return state == NOTOK  ?  NOTOK  :  OK;
 }
+
+
+/*
+ * Convert an int to a char string.
+ */
+char *
+m_str(int value) {
+    return m_strn(value, 0);
+}
+
+
+/*
+ * Convert an int to a char string, of limited width if > 0.
+ */
+#define STR(s) #s
+/* SIZE(n) includes NUL.  n must just be digits, not an equation. */
+#define SIZE(n) (sizeof STR(n))
+
+char *
+m_strn(int value, unsigned int width) {
+    /* Need to include space for negative sign.  But don't use INT_MIN
+       because it could be a macro that would fool SIZE(n). */
+    static char buffer[SIZE(-INT_MAX)];
+    const int num_chars = snprintf(buffer, sizeof buffer, "%d", value);
+
+    return num_chars > 0  &&  (width == 0 || (unsigned int) num_chars <= width)
+        ? buffer
+        : "?";
+}