]> diplodocus.org Git - nmh/blobdiff - uip/mhparse.c
check curl_ctx->res_len > 0 not res_body != NULL
[nmh] / uip / mhparse.c
index e7782f14eec442491901adece5a159f7b58ad1f0..1193d5648cc75216b1e42a5be0a4b5755922dde9 100644 (file)
@@ -9,7 +9,6 @@
 
 #include <h/mh.h>
 #include <fcntl.h>
 
 #include <h/mh.h>
 #include <fcntl.h>
-#include <h/signals.h>
 #include <h/md5.h>
 #include <h/mts.h>
 #include <h/tws.h>
 #include <h/md5.h>
 #include <h/mts.h>
 #include <h/tws.h>
@@ -34,10 +33,21 @@ int checksw = 0;    /* check Content-MD5 field */
  * 1) Instruct parser not to detect invalid Content-Transfer-Encoding
  *    in a multipart.
  * 2) Suppress the warning about bogus multipart content, and report it.
  * 1) Instruct parser not to detect invalid Content-Transfer-Encoding
  *    in a multipart.
  * 2) Suppress the warning about bogus multipart content, and report it.
+ * 3) Suppress the warning about extraneous trailing ';' in header parameter
+ *    lists, and report it.
  */
 int skip_mp_cte_check;
 int suppress_bogus_mp_content_warning;
 int bogus_mp_content;
  */
 int skip_mp_cte_check;
 int suppress_bogus_mp_content_warning;
 int bogus_mp_content;
+int suppress_extraneous_trailing_semicolon_warning;
+int extraneous_trailing_semicolon;
+int suppress_multiple_mime_version_warning = 1;
+
+/* list of preferred type/subtype pairs, for -prefer */
+char *preferred_types[NPREFS],
+     *preferred_subtypes[NPREFS];
+int npreferred;
+
 
 /*
  * Structures for TEXT messages
 
 /*
  * Structures for TEXT messages
@@ -59,6 +69,7 @@ struct k2v SubMultiPart[] = {
     { "alternative", MULTI_ALTERNATE },
     { "digest",      MULTI_DIGEST },
     { "parallel",    MULTI_PARALLEL },
     { "alternative", MULTI_ALTERNATE },
     { "digest",      MULTI_DIGEST },
     { "parallel",    MULTI_PARALLEL },
+    { "related",     MULTI_RELATED },
     { NULL,          MULTI_UNKNOWN }    /* this one must be last! */
 };
 
     { NULL,          MULTI_UNKNOWN }    /* this one must be last! */
 };
 
@@ -99,7 +110,7 @@ static struct k2v EncodingType[] = {
 int find_cache (CT, int, int *, char *, char *, int);
 
 /* mhmisc.c */
 int find_cache (CT, int, int *, char *, char *, int);
 
 /* mhmisc.c */
-int part_ok (CT, int);
+int part_ok (CT);
 int type_ok (CT, int);
 void content_error (char *, CT, char *, ...);
 
 int type_ok (CT, int);
 void content_error (char *, CT, char *, ...);
 
@@ -116,6 +127,7 @@ static int InitGeneric (CT);
 static int InitText (CT);
 static int InitMultiPart (CT);
 static void reverse_parts (CT);
 static int InitText (CT);
 static int InitMultiPart (CT);
 static void reverse_parts (CT);
+static void prefer_parts(CT ct);
 static int InitMessage (CT);
 static int InitApplication (CT);
 static int init_encoding (CT, OpenCEFunc);
 static int InitMessage (CT);
 static int InitApplication (CT);
 static int init_encoding (CT, OpenCEFunc);
@@ -283,7 +295,7 @@ get_content (FILE *in, char *file, int toplevel)
     m_getfld_state_t gstate = 0;
 
     /* allocate the content structure */
     m_getfld_state_t gstate = 0;
 
     /* allocate the content structure */
-    if (!(ct = (CT) calloc (1, sizeof(*ct))))
+    if (!(ct = (CT) mh_xcalloc (1, sizeof(*ct))))
        adios (NULL, "out of memory");
 
     ct->c_fp = in;
        adios (NULL, "out of memory");
 
     ct->c_fp = in;
@@ -354,16 +366,12 @@ get_content (FILE *in, char *file, int toplevel)
        if (!strcasecmp (hp->name, VRSN_FIELD)) {
            int ucmp;
            char c, *cp, *dp;
        if (!strcasecmp (hp->name, VRSN_FIELD)) {
            int ucmp;
            char c, *cp, *dp;
+           char *vrsn;
 
 
-           if (ct->c_vrsn) {
-               advise (NULL, "message %s has multiple %s: fields",
-                       ct->c_file, VRSN_FIELD);
-               goto next_header;
-           }
-           ct->c_vrsn = add (hp->value, NULL);
+           vrsn = add (hp->value, NULL);
 
            /* Now, cleanup this field */
 
            /* Now, cleanup this field */
-           cp = ct->c_vrsn;
+           cp = vrsn;
 
            while (isspace ((unsigned char) *cp))
                cp++;
 
            while (isspace ((unsigned char) *cp))
                cp++;
@@ -390,6 +398,14 @@ get_content (FILE *in, char *file, int toplevel)
                admonish (NULL, "message %s has unknown value for %s: field (%s)",
                ct->c_file, VRSN_FIELD, cp);
            }
                admonish (NULL, "message %s has unknown value for %s: field (%s)",
                ct->c_file, VRSN_FIELD, cp);
            }
+           if (!ct->c_vrsn) {
+               ct->c_vrsn = vrsn;
+           } else {
+               if (! suppress_multiple_mime_version_warning)
+                   advise (NULL, "message %s has multiple %s: fields",
+                           ct->c_file, VRSN_FIELD);
+               free(vrsn);
+           }
        }
        else if (!strcasecmp (hp->name, TYPE_FIELD)) {
        /* Get Content-Type field */
        }
        else if (!strcasecmp (hp->name, TYPE_FIELD)) {
        /* Get Content-Type field */
@@ -1003,7 +1019,6 @@ InitText (CT ct)
     char *chset = NULL;
     char *cp;
     PM pm;
     char *chset = NULL;
     char *cp;
     PM pm;
-    struct k2v *kv;
     struct text *t;
     CI ci = &ct->c_ctinfo;
 
     struct text *t;
     CI ci = &ct->c_ctinfo;
 
@@ -1012,13 +1027,10 @@ InitText (CT ct)
        ci->ci_subtype = add ("plain", ci->ci_subtype);
 
     /* match subtype */
        ci->ci_subtype = add ("plain", ci->ci_subtype);
 
     /* match subtype */
-    for (kv = SubText; kv->kv_key; kv++)
-       if (!strcasecmp (ci->ci_subtype, kv->kv_key))
-           break;
-    ct->c_subtype = kv->kv_value;
+    ct->c_subtype = ct_str_subtype (CT_TEXT, ci->ci_subtype);
 
     /* allocate text character set structure */
 
     /* allocate text character set structure */
-    if ((t = (struct text *) calloc (1, sizeof(*t))) == NULL)
+    if ((t = (struct text *) mh_xcalloc (1, sizeof(*t))) == NULL)
        adios (NULL, "out of memory");
     ct->c_ctparams = (void *) t;
 
        adios (NULL, "out of memory");
     ct->c_ctparams = (void *) t;
 
@@ -1068,7 +1080,6 @@ InitMultiPart (CT ct)
     size_t buflen;
     ssize_t gotlen;
     struct multipart *m;
     size_t buflen;
     ssize_t gotlen;
     struct multipart *m;
-    struct k2v *kv;
     struct part *part, **next;
     CI ci = &ct->c_ctinfo;
     CT p;
     struct part *part, **next;
     CI ci = &ct->c_ctinfo;
     CT p;
@@ -1090,8 +1101,9 @@ InitMultiPart (CT ct)
 
        admonish (NULL,
                  "\"%s/%s\" type in message %s must be encoded in\n"
 
        admonish (NULL,
                  "\"%s/%s\" type in message %s must be encoded in\n"
-                 "7bit, 8bit, or binary, per RFC 2045 (6.4).  One workaround "
-                 "is to\nmanually edit the file and change the \"%s\"\n"
+                 "7bit, 8bit, or binary, per RFC 2045 (6.4).  "
+                  "mhfixmsg -fixcte can fix it, or\n"
+                  "manually edit the file and change the \"%s\"\n"
                  "Content-Transfer-Encoding to one of those.  For now",
                  ci->ci_type, ci->ci_subtype, ct->c_file, bp);
        free (cte);
                  "Content-Transfer-Encoding to one of those.  For now",
                  ci->ci_type, ci->ci_subtype, ct->c_file, bp);
        free (cte);
@@ -1100,10 +1112,7 @@ InitMultiPart (CT ct)
     }
 
     /* match subtype */
     }
 
     /* match subtype */
-    for (kv = SubMultiPart; kv->kv_key; kv++)
-       if (!strcasecmp (ci->ci_subtype, kv->kv_key))
-           break;
-    ct->c_subtype = kv->kv_value;
+    ct->c_subtype = ct_str_subtype (CT_MULTIPART, ci->ci_subtype);
 
     /*
      * Check for "boundary" parameter, which is
 
     /*
      * Check for "boundary" parameter, which is
@@ -1126,7 +1135,7 @@ InitMultiPart (CT ct)
     }
 
     /* allocate primary structure for multipart info */
     }
 
     /* allocate primary structure for multipart info */
-    if ((m = (struct multipart *) calloc (1, sizeof(*m))) == NULL)
+    if ((m = (struct multipart *) mh_xcalloc (1, sizeof(*m))) == NULL)
        adios (NULL, "out of memory");
     ct->c_ctparams = (void *) m;
 
        adios (NULL, "out of memory");
     ct->c_ctparams = (void *) m;
 
@@ -1171,7 +1180,7 @@ InitMultiPart (CT ct)
            if (strcmp (bufp + 2, m->mp_start))
                continue;
 next_part:
            if (strcmp (bufp + 2, m->mp_start))
                continue;
 next_part:
-           if ((part = (struct part *) calloc (1, sizeof(*part))) == NULL)
+           if ((part = (struct part *) mh_xcalloc (1, sizeof(*part))) == NULL)
                adios (NULL, "out of memory");
            *next = part;
            next = &part->mp_next;
                adios (NULL, "out of memory");
            *next = part;
            next = &part->mp_next;
@@ -1179,7 +1188,6 @@ next_part:
            if (!(p = get_content (fp, ct->c_file,
                        ct->c_subtype == MULTI_DIGEST ? -1 : 0))) {
                free(bufp);
            if (!(p = get_content (fp, ct->c_file,
                        ct->c_subtype == MULTI_DIGEST ? -1 : 0))) {
                free(bufp);
-               fclose (ct->c_fp);
                ct->c_fp = NULL;
                return NOTOK;
            }
                ct->c_fp = NULL;
                return NOTOK;
            }
@@ -1227,8 +1235,10 @@ end_part:
 
 last_part:
     /* reverse the order of the parts for multipart/alternative */
 
 last_part:
     /* reverse the order of the parts for multipart/alternative */
-    if (ct->c_subtype == MULTI_ALTERNATE)
+    if (ct->c_subtype == MULTI_ALTERNATE) {
        reverse_parts (ct);
        reverse_parts (ct);
+       prefer_parts (ct);
+    }
 
     /*
      * label all subparts with part number, and
 
     /*
      * label all subparts with part number, and
@@ -1274,9 +1284,15 @@ last_part:
 
 
 /*
 
 
 /*
- * reverse the order of the parts of a multipart/alternative
+ * reverse the order of the parts of a multipart/alternative,
+ * presumably to put the "most favored" alternative first, for
+ * ease of choosing/displaying it later on.  from a mail message on
+ * nmh-workers, from kenh:
+ *  "Stock" MH 6.8.5 did not have a reverse_parts() function, but I
+ *  see code in mhn that did the same thing...  Acccording to the RCS
+ *  logs, that code was around from the initial checkin of mhn.c by
+ *  John Romine in 1992, which is as far back as we have."
  */
  */
-
 static void
 reverse_parts (CT ct)
 {
 static void
 reverse_parts (CT ct)
 {
@@ -1293,6 +1309,60 @@ reverse_parts (CT ct)
     }
 }
 
     }
 }
 
+static void
+move_preferred_part (CT ct, char *type, char *subtype)
+{
+    struct multipart *m = (struct multipart *) ct->c_ctparams;
+    struct part *part, *prev, *head, *nhead, *ntail;
+    struct part h, n;
+    CI ci;
+
+    /* move the matching part(s) to the head of the list:  walk the
+     * list of parts, move matching parts to a new list (maintaining
+     * their order), and finally, concatenate the old list onto the
+     * new.
+     */
+
+    head = &h;
+    nhead = &n;
+
+    head->mp_next = m->mp_parts;
+    nhead->mp_next = NULL;
+    ntail = nhead;
+
+    prev = head;
+    part = head->mp_next;
+    while (part != NULL) {
+       ci = &part->mp_part->c_ctinfo;
+       if (!strcasecmp(ci->ci_type, type) &&
+               (!subtype || !strcasecmp(ci->ci_subtype, subtype))) {
+           prev->mp_next = part->mp_next;
+           part->mp_next = NULL;
+           ntail->mp_next = part;
+           ntail = part;
+           part = prev->mp_next;
+       } else {
+           prev = part;
+           part = prev->mp_next;
+       }
+    }
+    ntail->mp_next = head->mp_next;
+    m->mp_parts = nhead->mp_next;
+
+}
+
+/*
+ * move parts that match the user's preferences (-prefer) to the head
+ * of the line.  process preferences in reverse so first one given
+ * ends up first in line
+ */
+static void
+prefer_parts(CT ct)
+{
+    int i;
+    for (i = npreferred-1; i >= 0; i--)
+       move_preferred_part(ct, preferred_types[i], preferred_subtypes[i]);
+}
 
 
 
 
 
 
@@ -1325,7 +1395,6 @@ reverse_alternative_parts (CT ct) {
 static int
 InitMessage (CT ct)
 {
 static int
 InitMessage (CT ct)
 {
-    struct k2v *kv;
     CI ci = &ct->c_ctinfo;
 
     if ((ct->c_encoding != CE_7BIT) && (ct->c_encoding != CE_8BIT)) {
     CI ci = &ct->c_ctinfo;
 
     if ((ct->c_encoding != CE_7BIT) && (ct->c_encoding != CE_8BIT)) {
@@ -1340,10 +1409,7 @@ InitMessage (CT ct)
        ci->ci_subtype = add ("rfc822", ci->ci_subtype);
 
     /* match subtype */
        ci->ci_subtype = add ("rfc822", ci->ci_subtype);
 
     /* match subtype */
-    for (kv = SubMessage; kv->kv_key; kv++)
-       if (!strcasecmp (ci->ci_subtype, kv->kv_key))
-           break;
-    ct->c_subtype = kv->kv_value;
+    ct->c_subtype = ct_str_subtype (CT_MESSAGE, ci->ci_subtype);
 
     switch (ct->c_subtype) {
        case MESSAGE_RFC822:
 
     switch (ct->c_subtype) {
        case MESSAGE_RFC822:
@@ -1354,7 +1420,7 @@ InitMessage (CT ct)
                PM pm;
                struct partial *p;
 
                PM pm;
                struct partial *p;
 
-               if ((p = (struct partial *) calloc (1, sizeof(*p))) == NULL)
+               if ((p = (struct partial *) mh_xcalloc (1, sizeof(*p))) == NULL)
                    adios (NULL, "out of memory");
                ct->c_ctparams = (void *) p;
 
                    adios (NULL, "out of memory");
                ct->c_ctparams = (void *) p;
 
@@ -1403,7 +1469,7 @@ invalid_param:
                CT p;
                FILE *fp;
 
                CT p;
                FILE *fp;
 
-               if ((e = (struct exbody *) calloc (1, sizeof(*e))) == NULL)
+               if ((e = (struct exbody *) mh_xcalloc (1, sizeof(*e))) == NULL)
                    adios (NULL, "out of memory");
                ct->c_ctparams = (void *) e;
 
                    adios (NULL, "out of memory");
                ct->c_ctparams = (void *) e;
 
@@ -1593,14 +1659,10 @@ params_external (CT ct, int composing)
 static int
 InitApplication (CT ct)
 {
 static int
 InitApplication (CT ct)
 {
-    struct k2v *kv;
     CI ci = &ct->c_ctinfo;
 
     /* match subtype */
     CI ci = &ct->c_ctinfo;
 
     /* match subtype */
-    for (kv = SubApplication; kv->kv_key; kv++)
-       if (!strcasecmp (ci->ci_subtype, kv->kv_key))
-           break;
-    ct->c_subtype = kv->kv_value;
+    ct->c_subtype = ct_str_subtype (CT_APPLICATION, ci->ci_subtype);
 
     return OK;
 }
 
     return OK;
 }
@@ -2127,6 +2189,7 @@ ready_to_go:
       fclose (ct->c_fp);
       ct->c_fp = NULL;
     }
       fclose (ct->c_fp);
       ct->c_fp = NULL;
     }
+    free (bufp);
     return fileno (ce->ce_fp);
 
 clean_up:
     return fileno (ce->ce_fp);
 
 clean_up:
@@ -2135,6 +2198,7 @@ clean_up:
       fclose (ct->c_fp);
       ct->c_fp = NULL;
     }
       fclose (ct->c_fp);
       ct->c_fp = NULL;
     }
+    free (bufp);
     return NOTOK;
 }
 
     return NOTOK;
 }
 
@@ -2274,7 +2338,9 @@ open7Bit (CT ct, char **file)
                cc = len;
            len -= cc;
 
                cc = len;
            len -= cc;
 
-           fwrite (buffer, sizeof(*buffer), cc, ce->ce_fp);
+           if ((int) fwrite (buffer, sizeof(*buffer), cc, ce->ce_fp) < cc) {
+               advise ("open7Bit", "fwrite");
+           }
            if (ferror (ce->ce_fp)) {
                content_error (ce->ce_file, ct, "error writing to");
                goto clean_up;
            if (ferror (ce->ce_fp)) {
                content_error (ce->ce_file, ct, "error writing to");
                goto clean_up;
@@ -2409,7 +2475,9 @@ openFile (CT ct, char **file)
 
            while ((cc = fread (buffer, sizeof(*buffer), sizeof(buffer), gp))
                       > 0)
 
            while ((cc = fread (buffer, sizeof(*buffer), sizeof(buffer), gp))
                       > 0)
-               fwrite (buffer, sizeof(*buffer), cc, fp);
+               if ((int) fwrite (buffer, sizeof(*buffer), cc, fp) < cc) {
+                   advise ("openFile", "fwrite");
+               }
            fflush (fp);
 
            if (ferror (gp)) {
            fflush (fp);
 
            if (ferror (gp)) {
@@ -2618,7 +2686,9 @@ openFTP (CT ct, char **file)
 
                while ((cc= fread (buffer, sizeof(*buffer), sizeof(buffer), gp))
                           > 0)
 
                while ((cc= fread (buffer, sizeof(*buffer), sizeof(buffer), gp))
                           > 0)
-                   fwrite (buffer, sizeof(*buffer), cc, fp);
+                   if ((int) fwrite (buffer, sizeof(*buffer), cc, fp) < cc) {
+                       advise ("openFTP", "fwrite");
+                   }
                fflush (fp);
 
                if (ferror (gp)) {
                fflush (fp);
 
                if (ferror (gp)) {
@@ -2878,7 +2948,9 @@ openURL (CT ct, char **file)
 
                while ((cc = fread(buffer, sizeof(*buffer),
                                   sizeof(buffer), gp)) > 0)
 
                while ((cc = fread(buffer, sizeof(*buffer),
                                   sizeof(buffer), gp)) > 0)
-                   fwrite(buffer, sizeof(*buffer), cc, fp);
+                   if ((int) fwrite(buffer, sizeof(*buffer), cc, fp) < cc) {
+                       advise ("openURL", "fwrite");
+                   }
 
                fflush(fp);
 
 
                fflush(fp);
 
@@ -3140,6 +3212,8 @@ ct_subtype_str (int type, int subtype) {
             return "digest";
         case MULTI_PARALLEL:
             return "parallel";
             return "digest";
         case MULTI_PARALLEL:
             return "parallel";
+        case MULTI_RELATED:
+            return "related";
         default:
             return "unknown_multipart_subtype";
         }
         default:
             return "unknown_multipart_subtype";
         }
@@ -3160,6 +3234,62 @@ ct_subtype_str (int type, int subtype) {
 }
 
 
 }
 
 
+int
+ct_str_type (const char *type) {
+    struct str2init *s2i;
+
+    for (s2i = str2cts; s2i->si_key; ++s2i) {
+        if (! strcasecmp (type, s2i->si_key)) {
+            break;
+        }
+    }
+    if (! s2i->si_key  &&  ! uprf (type, "X-")) {
+        ++s2i;
+    }
+
+    return s2i->si_val;
+}
+
+
+int
+ct_str_subtype (int type, const char *subtype) {
+    struct k2v *kv;
+
+    switch (type) {
+    case CT_APPLICATION:
+        for (kv = SubApplication; kv->kv_key; ++kv) {
+            if (! strcasecmp (subtype, kv->kv_key)) {
+                break;
+            }
+        }
+        return kv->kv_value;
+    case CT_MESSAGE:
+        for (kv = SubMessage; kv->kv_key; ++kv) {
+            if (! strcasecmp (subtype, kv->kv_key)) {
+                break;
+            }
+        }
+        return kv->kv_value;
+    case CT_MULTIPART:
+        for (kv = SubMultiPart; kv->kv_key; ++kv) {
+            if (! strcasecmp (subtype, kv->kv_key)) {
+                break;
+            }
+        }
+        return kv->kv_value;
+    case CT_TEXT:
+        for (kv = SubText; kv->kv_key; ++kv) {
+            if (! strcasecmp (subtype, kv->kv_key)) {
+                break;
+            }
+        }
+        return kv->kv_value;
+    default:
+        return 0;
+    }
+}
+
+
 /* Find the content type and InitFunc for the CT. */
 const struct str2init *
 get_ct_init (int type) {
 /* Find the content type and InitFunc for the CT. */
 const struct str2init *
 get_ct_init (int type) {
@@ -3264,10 +3394,13 @@ parse_header_attrs (const char *filename, const char *fieldname,
         }
 
        if (*cp == 0) {
         }
 
        if (*cp == 0) {
-           advise (NULL,
-                   "extraneous trailing ';' in message %s's %s: "
-                    "parameter list",
-                   filename, fieldname);
+           if (! suppress_extraneous_trailing_semicolon_warning) {
+               advise (NULL,
+                       "extraneous trailing ';' in message %s's %s: "
+                       "parameter list",
+                       filename, fieldname);
+           }
+           extraneous_trailing_semicolon = 1;
            return DONE;
        }
 
            return DONE;
        }
 
@@ -3542,6 +3675,7 @@ bad_quote:
                                "%s's %s: field\n%*s(parameter %s)", sp->index,
                                filename, fieldname, strlen(invo_name) + 2, "",
                                nameptr);
                                "%s's %s: field\n%*s(parameter %s)", sp->index,
                                filename, fieldname, strlen(invo_name) + 2, "",
                                nameptr);
+                       free (nameptr);
                        return NOTOK;
                    }
                    if (sp2->index < sp->index &&
                        return NOTOK;
                    }
                    if (sp2->index < sp->index &&
@@ -3557,6 +3691,7 @@ bad_quote:
                           "param in message %s's %s: field\n%*s(parameter %s)",
                           filename, fieldname, strlen(invo_name) + 2, "",
                           nameptr);
                           "param in message %s's %s: field\n%*s(parameter %s)",
                           filename, fieldname, strlen(invo_name) + 2, "",
                           nameptr);
+                   free (nameptr);
                    return NOTOK;
                }
            }
                    return NOTOK;
                }
            }
@@ -3632,21 +3767,16 @@ bad_quote:
 }
 
 /*
 }
 
 /*
- * Return the charset for a particular content type.  Return pointer is
- * only valid until the next call to content_charset().
+ * Return the charset for a particular content type.
  */
 
 char *
 content_charset (CT ct) {
  */
 
 char *
 content_charset (CT ct) {
-    static char *ret_charset = NULL;
-
-    if (ret_charset != NULL) {
-       free(ret_charset);
-    }
+    char *ret_charset = NULL;
 
     ret_charset = get_param(ct->c_ctinfo.ci_first_pm, "charset", '?', 0);
 
 
     ret_charset = get_param(ct->c_ctinfo.ci_first_pm, "charset", '?', 0);
 
-    return ret_charset ? ret_charset : "US-ASCII";
+    return ret_charset ? ret_charset : getcpy ("US-ASCII");
 }
 
 
 }
 
 
@@ -4204,7 +4334,7 @@ char *get_param_value(PM pm, char replace)
            }
            if (utf8) {
                for (++p, --inbytes;
            }
            if (utf8) {
                for (++p, --inbytes;
-                    inbytes > 0 && (((unsigned char) *q) & 0xc0) == 0x80;
+                    inbytes > 0 && (((unsigned char) *p) & 0xc0) == 0x80;
                     ++p, --inbytes)
                    continue;
            } else {
                     ++p, --inbytes)
                    continue;
            } else {