Add an error check for correct formatting in Deflate uncompressed
[sgt/halibut] / misc.c
diff --git a/misc.c b/misc.c
index a20c5b4..3f2483c 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -90,13 +90,16 @@ void rdaddc(rdstringc *rs, char c) {
     rs->text[rs->pos] = 0;
 }
 void rdaddsc(rdstringc *rs, char const *p) {
-    int len = strlen(p);
+    rdaddsn(rs, p, strlen(p));
+}
+void rdaddsn(rdstringc *rs, char const *p, int len) {
     if (rs->pos >= rs->size - len) {
        rs->size = rs->pos + len + 128;
        rs->text = sresize(rs->text, rs->size, char);
     }
-    strcpy(rs->text + rs->pos, p);
+    memcpy(rs->text + rs->pos, p, len);
     rs->pos += len;
+    rs->text[rs->pos] = 0;
 }
 char *rdtrimc(rdstringc *rs) {
     rs->text = sresize(rs->text, rs->pos + 1, char);
@@ -234,17 +237,32 @@ void mark_attr_ends(word *words)
 
     wp = NULL;
     for (w = words; w; w = w->next) {
-       if (isattr(w->type)) {
-           int before = (wp && isattr(wp->type) &&
-                         sameattr(wp->type, w->type));
-           int after = (w->next && isattr(w->next->type) &&
-                        sameattr(w->next->type, w->type));
-           w->aux |= (before ?
-                      (after ? attr_Always : attr_Last) :
-                      (after ? attr_First : attr_Only));
+       int both;
+       if (!isvis(w->type))
+           /* Invisible elements should not affect this calculation */
+           continue;
+       both = (isattr(w->type) &&
+               wp && isattr(wp->type) &&
+               sameattr(wp->type, w->type));
+       w->aux |= both ? attr_Always : attr_First;
+       if (wp && !both) {
+           /* If previous considered word turns out to have been
+            * the end of a run, tidy it up. */
+           int wp_attr = attraux(wp->aux);
+           wp->aux = (wp->aux & ~attr_mask) |
+               ((wp_attr == attr_Always) ? attr_Last
+                        /* attr_First */ : attr_Only);
        }
        wp = w;
     }
+
+    /* Tidy up last word touched */
+    if (wp) {
+       int wp_attr = attraux(wp->aux);
+       wp->aux = (wp->aux & ~attr_mask) |
+           ((wp_attr == attr_Always) ? attr_Last
+                    /* attr_First */ : attr_Only);
+    }
 }
 
 /*