[tor-commits] [stegotorus/master] Thorough spring-cleaning on pdfSteg.cc; less thorough on swfSteg.cc

zwol at torproject.org zwol at torproject.org
Fri Jul 20 23:17:07 UTC 2012


commit 177ba0f8b4265d09c321d6903eeab040faeca430
Author: Zack Weinberg <zackw at cmu.edu>
Date:   Mon Apr 23 14:49:52 2012 -0700

    Thorough spring-cleaning on pdfSteg.cc; less thorough on swfSteg.cc
    and some other headers.  Add beginnings of unit tests for pdfSteg.
---
 Makefile.am                  |    1 +
 src/steg/pdfSteg.cc          |  389 +++++++++++++-----------------------------
 src/steg/pdfSteg.h           |   38 +++--
 src/steg/swfSteg.cc          |   18 +--
 src/steg/swfSteg.h           |   23 +---
 src/steg/zpack.h             |   11 +-
 src/test/tinytest_macros.h   |    8 +-
 src/test/unittest_pdfsteg.cc |   82 +++++++++
 src/util.cc                  |    3 -
 src/util.h                   |    3 +
 10 files changed, 249 insertions(+), 327 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 6ba1b51..86ed489 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -49,6 +49,7 @@ stegotorus_SOURCES = \
 
 UTGROUPS = \
 	src/test/unittest_crypt.cc \
+	src/test/unittest_pdfsteg.cc \
 	src/test/unittest_socks.cc \
 	src/test/unittest_config.cc \
 	src/test/unittest_transfer.cc
diff --git a/src/steg/pdfSteg.cc b/src/steg/pdfSteg.cc
index c67b0f8..3b4bbf0 100644
--- a/src/steg/pdfSteg.cc
+++ b/src/steg/pdfSteg.cc
@@ -1,7 +1,13 @@
-#include "payloads.h"
+#include "util.h"
 #include "pdfSteg.h"
+#include "connections.h"
+#include "payloads.h"
+#include <event2/buffer.h>
+
+/* pdfSteg: A PDF-based steganography module */
 
-void buf_dump(unsigned char* buf, int len, FILE *out);
+#define PDF_DELIMITER    '?'
+#define PDF_DELIMITER2   '.'
 
 #define STREAM_BEGIN       ">>stream"
 #define STREAM_BEGIN_SIZE  8
@@ -10,45 +16,42 @@ void buf_dump(unsigned char* buf, int len, FILE *out);
 
 #define DEBUG
 
-
 /*
- * pdfSteg: A PDF-based steganography module
- *
- */
-
-
-/*
- * addDelimiter processes the input buffer (inbuf) of length inbuflen,
- * copies it to output buffer (outbuf) of size outbufsize,
+ * pdf_add_delimiter processes the input buffer (inbuf) of length
+ * inbuflen, copies it to output buffer (outbuf) of size outbufsize,
  * and adds a two-char-long, end-of-data pattern at the end of outbuf
  * based on delimiter1 and delimiter2.
  *
  * The end-of-data pattern consists of delimiter1 followed by a char
  * that is not delimiter1. Thus, delimiter1 and delimiter2 must be
  * different.
- * 
- * If delimiter1 appears in the input buffer, addDelimiter puts two
- * delimiter1 char in output buffer (to enable removeDelimiter to perform
- * the back transformation)
  *
- * addDelimiter returns the length of the data written to outbuf, including
- * the end-of-data pattern, if the transformation succeeds;
- * otherwise, it returns -1
+ * If delimiter1 appears in the input buffer, pdf_add_delimiter puts two
+ * delimiter1 characters in the output buffer, so that the transformation
+ * is reversible.
+ *
+ * pdf_add_delimiter returns the length of the data written to outbuf,
+ * including the end-of-data pattern, if the transformation succeeds;
+ * otherwise, it returns -1.
  *
  */
-int
-addDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, 
-             const char delimiter1, const char delimiter2)
+ssize_t
+pdf_add_delimiter(const char *inbuf, size_t inbuflen,
+                  char *outbuf, size_t outbuflen,
+                  const char delimiter1, const char delimiter2)
 {
-  int cnt;
-  char *ibp, ic, rc;
+  size_t cnt;
+  const char *ibp;
+  char ic, rc;
 
-  if (delimiter1 == delimiter2) return -1;  
+  log_assert(delimiter1 != delimiter2);
+  if (inbuflen > SIZE_T_CEILING || outbuflen > SIZE_T_CEILING)
+    return -1;
 
   cnt = 0;
   ibp = inbuf;
-  while ((ibp-inbuf)<inbuflen && cnt<(outbuflen-2)) {
-    ic = *(ibp++);
+  while (size_t(ibp-inbuf) < inbuflen && cnt < outbuflen-2) {
+    ic = *ibp++;
     if (ic != delimiter1) {
       outbuf[cnt++] = ic;
     } else {
@@ -57,8 +60,9 @@ addDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen,
     }
   }
 
-  // error if outbuf is no large enough for storing the resulting data
-  if (cnt >= (outbuflen-2)) return -1;
+  // error if outbuf is not large enough for storing the resulting data
+  if (cnt >= outbuflen-2)
+    return -1;
 
   // put delimiter1 and a char that is not a delimiter1
   // as the end-of-data pattern at the end of outbuf
@@ -75,8 +79,9 @@ addDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen,
 
 
 /*
- * removeDelimiter performs the reverse transformation of addDelimiter.
- * 
+ * pdf_remove_delimiter performs the reverse transformation of
+ * pdf_add_delimiter.
+ *
  * returns the length of data written to outbuf, if succeed;
  * otherwise, it returns -1
  *
@@ -84,20 +89,23 @@ addDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen,
  * delimiter1 followed by non-delimiter1) is detected
  *
  * escape indicates if a dangling delimiter1 has been
- * seen in the previous invocation of removeDelimiter
+ * seen in the previous invocation of pdf_remove_delimiter
  */
-int
-removeDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, 
-                const char delimiter1, int *endFlag, int *escape)
+ssize_t
+pdf_remove_delimiter(const char *inbuf, size_t inbuflen,
+                     char *outbuf, size_t outbuflen,
+                     char delimiter1, bool *endFlag, bool *escape)
 {
-  int cnt;
-  char *ibp, ic1, ic2;
+  size_t cnt;
+  const char *ibp;
+  char ic1, ic2;
 
   cnt = 0;
-  *endFlag = 0;
+  *endFlag = false;
   ibp = inbuf;
 
-  if (inbuflen <= 0) return -1;
+  if (inbuflen > SIZE_T_CEILING || outbuflen > SIZE_T_CEILING)
+    return -1;
 
   // special case: 2-char, end-of-data pattern could be in two buffers
   // if *escape == true, we need to see if
@@ -113,9 +121,9 @@ removeDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen,
     }
   }
 
-  *escape = 0;
-  while ((ibp-inbuf+1)<inbuflen && cnt<outbuflen) {
-    ic1 = *(ibp++);
+  *escape = false;
+  while (size_t(ibp-inbuf+1) < inbuflen && cnt < outbuflen) {
+    ic1 = *ibp++;
     if (ic1 != delimiter1) {
       outbuf[cnt++] = ic1;
     } else {
@@ -125,13 +133,14 @@ removeDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen,
       if (ic2 == delimiter1) {
         outbuf[cnt++] = delimiter1; ibp++;
       } else { // end-of-data pattern detected
-        *endFlag = 1;
+        *endFlag = true;
         return cnt;
       }
     }
   }
 
-  if (ibp-inbuf == inbuflen) return cnt;
+  if (size_t(ibp-inbuf) == inbuflen)
+    return cnt;
 
   // handling the last char in inbuf, if needed
   ic1 = *ibp;
@@ -139,40 +148,46 @@ removeDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen,
     outbuf[cnt++] = ic1;
   } else {
     // look at the next stream obj to handle the special cases
-    *escape = 1;
+    *escape = true;
   }
 
   return cnt;
 }
 
-
-
 /*
- * pdfWrap embeds data of length dlen inside the stream objects of the PDF
+ * pdf_wrap embeds data of length dlen inside the stream objects of the PDF
  * document (length plen) that appears in the body of a HTTP msg, and
  * stores the result in the output buffer of size outsize
  *
- * pdfWrap returns the length of the pdf document with the data embedded
+ * pdf_wrap returns the length of the pdf document with the data embedded
  * inside, if succeed; otherwise, it returns -1 to indicate an error
- *  
- */ 
-int 
-pdfWrap (char *data, unsigned int dlen,
-         char *pdfTemplate, unsigned int plen,
-         char *outbuf, unsigned int outbufsize)
+ *
+ */
+ssize_t
+pdf_wrap(const char *data, size_t dlen,
+         const char *pdfTemplate, size_t plen,
+         char *outbuf, size_t outbufsize)
 {
   char data2[dlen*2+2];
-  char *tp, *dp, *op, *streamStart, *streamEnd, *plimit;
-  int data2len, cnt, size, size2;
+  const char *tp, *dp, *plimit;
+  char *op, *streamStart, *streamEnd;
+  size_t data2len, cnt, size, size2;
+  ssize_t rv;
 
-  // assumption: pdfWrap is length-preserving
-  if (outbufsize < plen) return -1;
+  if (dlen > SIZE_T_CEILING || plen > SIZE_T_CEILING ||
+      outbufsize > SIZE_T_CEILING)
+    return -1;
 
-  data2len = addDelimiter(data, dlen, data2, HTTP_MSG_BUF_SIZE, PDF_DELIMITER, PDF_DELIMITER2);
-  if (data2len < 1) return -1;
+  // assumption: pdf_wrap is length-preserving
+  if (outbufsize < plen) return -1;
 
+  rv = pdf_add_delimiter(data, dlen, data2, HTTP_MSG_BUF_SIZE,
+                               PDF_DELIMITER, PDF_DELIMITER2);
+  if (rv < 1)
+    return -1;
+  data2len = rv;
 
-  op = outbuf;       // current pointer for output buffer 
+  op = outbuf;       // current pointer for output buffer
   tp = pdfTemplate;  // current pointer for http msg template
   dp = data2;        // current pointer for data2
   cnt = 0;           // number of data char encoded
@@ -185,7 +200,7 @@ pdfWrap (char *data, unsigned int dlen,
       log_warn("Cannot find stream in pdf");
       return -1;
     }
- 
+
     // copy everything between tp and "stream" (inclusive) to outbuf
     size = streamStart - tp + STREAM_BEGIN_SIZE;
     memcpy(op, tp, size);
@@ -206,18 +221,17 @@ pdfWrap (char *data, unsigned int dlen,
         size2 = data2len - cnt;
         if (size < size2) {
           memcpy(op, dp, size);
-          op += size; tp += size; dp += size; 
+          op += size; tp += size; dp += size;
           memcpy(op, tp, STREAM_END_SIZE);
           op += STREAM_END_SIZE; tp += STREAM_END_SIZE;
           cnt += size;
         } else { // done encoding data
           memcpy(op, dp, size2);
-          op += size2; tp += size2; dp += size2; 
+          op += size2; tp += size2; dp += size2;
           cnt += size2;
-          // printf("Encoded %d char in pdf. Done encoding\n", size2);
           break;
         }
-        log_debug("Encoded %d char in pdf", size);
+        log_debug("Encoded %lu bytes in pdf", (unsigned long)size);
     } else { // empty stream
       memcpy(op, tp, STREAM_END_SIZE);
       op += STREAM_END_SIZE; tp += STREAM_END_SIZE;
@@ -228,25 +242,27 @@ pdfWrap (char *data, unsigned int dlen,
 
   // copy the rest of pdfTemplate to outbuf
   size = plimit-tp;
-  log_debug("copying the rest of pdfTemplate to outbuf (size %d)", size); 
+  log_debug("copying the rest of pdfTemplate to outbuf (size %lu)",
+            (unsigned long)size);
   memcpy(op, tp, size);
   op += size;
   return (op-outbuf);
 }
 
-
-
-
 /*
- * pdfUnwrap is the inverse operation of pdfWrap
+ * pdf_unwrap is the inverse operation of pdf_wrap
  */
-int 
-pdfUnwrap (char *data, unsigned int dlen,
-           char *outbuf, unsigned int outbufsize)
+ssize_t
+pdf_unwrap(const char *data, size_t dlen,
+           char *outbuf, size_t outbufsize)
 {
-  char *dp, *op, *streamStart, *streamEnd, *dlimit, *olimit;
-  int cnt, size, size2, endFlag;
-  int escape = 0;
+  const char *dp, *dlimit;
+  char *op, *streamStart, *streamEnd, *olimit;
+  size_t cnt, size, size2;
+  bool endFlag, escape = false;
+
+  if (dlen > SIZE_T_CEILING || outbufsize > SIZE_T_CEILING)
+    return -1;
 
   dp = data;   // current pointer for data
   op = outbuf; // current pointer for outbuf
@@ -272,11 +288,13 @@ pdfUnwrap (char *data, unsigned int dlen,
     // count the number of usable char between tp and streamEnd
     size = streamEnd-dp;
 
-    if (size > 0) { 
-      size2 = removeDelimiter(dp, size, op, olimit-op, PDF_DELIMITER, &endFlag, &escape);
-      if (size2 < 0) {
+    if (size > 0) {
+      ssize_t rv = pdf_remove_delimiter(dp, size, op, olimit-op, PDF_DELIMITER,
+                                        &endFlag, &escape);
+      if (rv < 0)
         return -1;
-      }
+
+      size2 = rv;
       cnt += size2;
       if (endFlag) { // Done decoding
         break;
@@ -292,22 +310,16 @@ pdfUnwrap (char *data, unsigned int dlen,
   return cnt;
 }
 
-
-
-
-
 int
-http_server_PDF_transmit (payloads& pl, struct evbuffer *source,
-                          conn_t *conn)
+http_server_PDF_transmit(payloads &pl, struct evbuffer *source,
+                         conn_t *conn)
 {
-
   struct evbuffer *dest = conn->outbound();
   size_t sbuflen = evbuffer_get_length(source);
   unsigned int mpdf;
   char *pdfTemplate = NULL, *hend;
   int pdfTemplateSize = 0;
-  // char data1[HTTP_MSG_BUF_SIZE];
-  char data1[(int) sbuflen];
+  char data1[sbuflen];
   char outbuf[HTTP_MSG_BUF_SIZE];
   int cnt, hLen, outbuflen, i;
 
@@ -317,10 +329,6 @@ http_server_PDF_transmit (payloads& pl, struct evbuffer *source,
   struct evbuffer_iovec *iv;
   int nv;
 
-  // for debugging pdfWrap and pdfUnwrap
-  // char data2[(int) sbuflen];
-  // int data2len;
-
   log_debug("Entering SERVER PDF transmit with sbuflen %d", (int)sbuflen);
 
   nv = evbuffer_peek(source, sbuflen, NULL, NULL, 0);
@@ -357,8 +365,10 @@ http_server_PDF_transmit (payloads& pl, struct evbuffer *source,
     return -1;
   }
 
-  if (get_payload(pl, HTTP_CONTENT_PDF, sbuflen, &pdfTemplate, &pdfTemplateSize) == 1) {
-    log_debug("SERVER found the next HTTP response template with size %d", pdfTemplateSize);
+  if (get_payload(pl, HTTP_CONTENT_PDF, sbuflen, &pdfTemplate,
+                  &pdfTemplateSize) == 1) {
+    log_debug("SERVER found the next HTTP response template with size %d",
+              pdfTemplateSize);
   } else {
     log_warn("SERVER couldn't find the next HTTP response template");
     return -1;
@@ -371,39 +381,19 @@ http_server_PDF_transmit (payloads& pl, struct evbuffer *source,
   }
 
   hLen = hend+4-pdfTemplate;
-  
-  log_debug("SERVER calling pdfWrap for data1 with length %d", cnt);
-  outbuflen = pdfWrap(data1, cnt, hend+4, pdfTemplateSize-hLen, outbuf, HTTP_MSG_BUF_SIZE);
+
+  log_debug("SERVER calling pdf_wrap for data1 with length %d", cnt);
+  outbuflen = pdf_wrap(data1, cnt, hend+4, pdfTemplateSize-hLen, outbuf,
+                      HTTP_MSG_BUF_SIZE);
   if (outbuflen < 0) {
-    log_warn("SERVER pdfWrap fails");
+    log_warn("SERVER pdf_wrap fails");
     return -1;
   }
-  log_debug("SERVER pdfSteg sends resp with hdr len %d body len %d", hLen, outbuflen);
-
-
-  // debugging
-  // buf_dump((unsigned char *)data1, cnt, stderr);
-
-  // data2len = pdfUnwrap(outbuf, outbuflen, data2, sbuflen);
-  // if ((int)sbuflen == data2len) {
-  //   log_warn("sbuflen == data2len == %d", (int)sbuflen);
-  //   if (memcmp(data1, data2, sbuflen) == 0) {
-  //     log_warn("data1 and data2 match");
-  //   } else {
-  //     log_warn("data1 and data2 DO NOT match!! Dumping data1 ...");
-  //     buf_dump((unsigned char *)data1, cnt, stderr);
-  //     log_warn("data1 and data2 DO NOT match!! Dumping data2...");
-  //     buf_dump((unsigned char *)data2, data2len, stderr);
-  //   }
-  // } else {
-  //   log_warn("*** sbuflen = %d, data2len = %d *** Dumping data1 ...", (int)sbuflen, data2len);
-  //   buf_dump((unsigned char *)data1, cnt, stderr);
-  //   log_warn("*** sbuflen = %d, data2len = %d *** Dumping data2 ...", (int)sbuflen, data2len);
-  //   buf_dump((unsigned char *)data2, data2len, stderr);
-  // }
-
-
-  newHdrLen = gen_response_header((char*) "application/pdf", 0, outbuflen, newHdr, sizeof(newHdr));
+  log_debug("SERVER pdfSteg sends resp with hdr len %d body len %d",
+            hLen, outbuflen);
+
+  newHdrLen = gen_response_header((char*) "application/pdf", 0,
+                                  outbuflen, newHdr, sizeof(newHdr));
   if (newHdrLen < 0) {
     log_warn("SERVER ERROR: gen_response_header fails for pdfSteg");
     return -1;
@@ -413,10 +403,6 @@ http_server_PDF_transmit (payloads& pl, struct evbuffer *source,
     log_warn("SERVER ERROR: evbuffer_add() fails for newHdr");
     return -1;
   }
-  // if (evbuffer_add(dest, pdfTemplate, hLen)) {
-  //   log_warn("SERVER ERROR: evbuffer_add() fails for pdfTemplate");
-  //   return -1;
-  // }
 
   if (evbuffer_add(dest, outbuf, outbuflen)) {
     log_warn("SERVER ERROR: evbuffer_add() fails for outbuf");
@@ -426,14 +412,13 @@ http_server_PDF_transmit (payloads& pl, struct evbuffer *source,
   evbuffer_drain(source, sbuflen);
 
   conn->cease_transmission();
-  //  downcast_steg(s)->have_transmitted = 1;
   return 0;
 }
 
-
-
 int
-http_handle_client_PDF_receive(steg_t *, conn_t *conn, struct evbuffer *dest, struct evbuffer* source) {
+http_handle_client_PDF_receive(steg_t *, conn_t *conn, struct evbuffer *dest,
+                               struct evbuffer* source)
+{
   struct evbuffer_ptr s2;
   unsigned int response_len = 0, hdrLen;
   char outbuf[HTTP_MSG_BUF_SIZE];
@@ -444,8 +429,8 @@ http_handle_client_PDF_receive(steg_t *, conn_t *conn, struct evbuffer *dest, st
 
   s2 = evbuffer_search(source, "\r\n\r\n", sizeof ("\r\n\r\n") -1 , NULL);
   if (s2.pos == -1) {
-    log_warn("CLIENT Did not find end of HTTP header %d", (int) evbuffer_get_length(source));
-    //    evbuffer_dump(source, stderr);
+    log_warn("CLIENT Did not find end of HTTP header %d",
+             (int) evbuffer_get_length(source));
     return RECV_INCOMPLETE;
   }
 
@@ -480,154 +465,26 @@ http_handle_client_PDF_receive(steg_t *, conn_t *conn, struct evbuffer *dest, st
     return RECV_BAD;
   }
 
-
   httpBody = httpHdr + hdrLen;
 
-
-  outbuflen = pdfUnwrap(httpBody, content_len, outbuf, HTTP_MSG_BUF_SIZE);
+  outbuflen = pdf_unwrap(httpBody, content_len, outbuf, HTTP_MSG_BUF_SIZE);
   if (outbuflen < 0) {
-    log_warn("CLIENT ERROR: pdfUnwrap fails\n");
+    log_warn("CLIENT ERROR: pdf_unwrap fails\n");
     return RECV_BAD;
   }
 
   log_debug("CLIENT unwrapped data of length %d:", outbuflen);
 
-
   if (evbuffer_add(dest, outbuf, outbuflen)) {
     log_warn("CLIENT ERROR: evbuffer_add to dest fails\n");
     return RECV_BAD;
   }
 
-  // log_debug("Drained source for %d char\n", response_len);
   if (evbuffer_drain(source, response_len) == -1) {
     log_warn("CLIENT ERROR: failed to drain source\n");
     return RECV_BAD;
   }
 
-  //  downcast_steg(s)->have_received = 1;
   conn->expect_close();
   return RECV_GOOD;
 }
-
-
-
-
-/*****
-int main() {
-  char data1[] = "this is a test?? yes!";
-  char data2[100];
-  char data3[100];
-  int dlen1, dlen2, dlen3, end;
-  char last = ' ';
-  printf("hello world\n");
- 
-  dlen2 = addDelimiter(data1, strlen(data1), data2, 100, '?', '.');
-  printf("dlen2 = %d\n", dlen2);
-  dlen3 = removeDelimiter(data2, dlen2, data3, 100, '?', &end, &last);
-  printf("endflag = %d", end);
-  printf("dlen3 = %d\n", dlen3);
-  if (memcmp(data1, data3, dlen3) == 0) {
-    data1[dlen3] = 0;
-    printf("removeDelimiter(addDelimiter(x)) == x for |%s|\n", data1);
-  } else {
-    printf("removeDelimiter(addDelimiter(x)) != x for |%s|\n", data1);
-  }
-  return 1;
-}
- *****/
-
-/*****
-int main() {
-  char data1[] = "12345";
-  char data2[] = "123456789012";
-  char data3[] = "12345678901";
-  char data4[] = "1234567890?";
-  char pdf1[] = "[PDFHDR][STUFFS1]>>streamABCDEFGHIJYYendstream[STUFFS2]>>streamABCDEFGHIJYYendstream[STUFF3][PDFTRAILER]";
-  char out[200];
-  char orig[200];
-  int r1, r2;
-
-  printf("********************\n");
-  printf("pdfwrap for %s\n", data1);
-  printf("strlen(pdf1) = %d\n", (int)strlen(pdf1));
-  r1 = pdfWrap(data1, strlen(data1), pdf1, strlen(pdf1), out, (int)sizeof(out));
-  if (r1 > 0) {
-    printf("pdfWrap returns %d\n", r1);
-    out[r1] = 0;
-    printf("out[] contains |%s|\n", out);
-  } else {
-    printf("pdfWrap returns %d\n", r1);
-  }
-
-  r2 = pdfUnwrap(out, r1, orig, (int)sizeof(orig));
-  if (r2 > 0) {
-    printf("pdfUnwrap returns %d\n", r2);
-    orig[r2] = 0;
-    printf("orig[] contains |%s|\n", orig);
-  } else {
-    printf("pdfUnwrap returns %d\n", r2);
-  }
-
-  printf("********************\n");
-  printf("pdfwrap for %s\n", data2);
-  r1 = pdfWrap(data2, strlen(data2), pdf1, strlen(pdf1), out, (int)sizeof(out));
-  if (r1 > 0) {
-    printf("pdfWrap returns %d\n", r1);
-    out[r1] = 0;
-    printf("out[] contains |%s|\n", out);
-  } else {
-    printf("pdfWrap returns %d\n", r1);
-  }
-
-  r2 = pdfUnwrap(out, r1, orig, (int)sizeof(orig));
-  if (r2 > 0) {
-    printf("pdfUnwrap returns %d\n", r2);
-    orig[r2] = 0;
-    printf("orig[] contains |%s|\n", orig);
-  } else {
-    printf("pdfUnwrap returns %d\n", r2);
-  }
-
-  printf("********************\n");
-  printf("pdfwrap for %s\n", data3);
-  r1 = pdfWrap(data3, strlen(data3), pdf1, strlen(pdf1), out, (int)sizeof(out));
-  if (r1 > 0) {
-    printf("pdfWrap returns %d\n", r1);
-    out[r1] = 0;
-    printf("out[] contains |%s|\n", out);
-  } else {
-    printf("pdfWrap returns %d\n", r1);
-  }
-
-  r2 = pdfUnwrap(out, r1, orig, (int)sizeof(orig));
-  if (r2 > 0) {
-    printf("pdfUnwrap returns %d\n", r2);
-    orig[r2] = 0;
-    printf("orig[] contains |%s|\n", orig);
-  } else {
-    printf("pdfUnwrap returns %d\n", r2);
-  }
-
-  printf("********************\n");
-  printf("pdfwrap for %s\n", data4);
-  r1 = pdfWrap(data4, strlen(data4), pdf1, strlen(pdf1), out, (int)sizeof(out));
-  if (r1 > 0) {
-    printf("pdfWrap returns %d\n", r1);
-    out[r1] = 0;
-    printf("out[] contains |%s|\n", out);
-  } else {
-    printf("pdfWrap returns %d\n", r1);
-  }
-
-  r2 = pdfUnwrap(out, r1, orig, (int)sizeof(orig));
-  if (r2 > 0) {
-    printf("pdfUnwrap returns %d\n", r2);
-    orig[r2] = 0;
-    printf("orig[] contains |%s|\n", orig);
-  } else {
-    printf("pdfUnwrap returns %d\n", r2);
-  }
-
-  return 0;
-}
- *****/
diff --git a/src/steg/pdfSteg.h b/src/steg/pdfSteg.h
index 3d494e1..0bd3a43 100644
--- a/src/steg/pdfSteg.h
+++ b/src/steg/pdfSteg.h
@@ -1,29 +1,31 @@
 #ifndef _PDFSTEG_H
 #define _PDFSTEG_H
 
+struct payloads;
 
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include "util.h"
-#include "connections.h"
-#include "steg.h"
-#include <event2/buffer.h>
+// These are the public interface.
 
-struct payloads;
+int http_server_PDF_transmit(payloads &pl, struct evbuffer *source,
+                             conn_t *conn);
+int http_handle_client_PDF_receive(steg_t *s, conn_t *conn,
+                                   struct evbuffer *dest,
+                                   struct evbuffer* source);
 
-#define PDF_DELIMITER    '?'
-#define PDF_DELIMITER2   '.'
+// These are exposed only for the sake of unit tests.
 
-int pdfWrap (char *data, unsigned int dlen, char *pdfTemplate, unsigned int plen, char *outbuf, unsigned int outbufsize);
-int pdfUnwrap (char *data, unsigned int dlen, char *outbuf, unsigned int outbufsize);
+ssize_t pdf_add_delimiter(const char *inbuf, size_t inbuflen,
+                          char *outbuf, size_t outbuflen,
+                          char delimiter1, char delimiter2);
 
-int addDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, const char delimiter1, const char delimiter2);
-int removeDelimiter(char *inbuf, int inbuflen, char *outbuf, int outbuflen, const char delimiter1, int* endFlag, int* escape);
+ssize_t pdf_remove_delimiter(const char *inbuf, size_t inbuflen,
+                             char *outbuf, size_t outbuflen,
+                             char delimiter1, bool *endFlag, bool *escape);
 
-int http_server_PDF_transmit (payloads& pl, struct evbuffer *source, conn_t *conn);
-int
-http_handle_client_PDF_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source);
+ssize_t pdf_wrap(const char *data, size_t dlen,
+                 const char *pdfTemplate, size_t plen,
+                 char *outbuf, size_t outbufsize);
 
-#endif
+ssize_t pdf_unwrap(const char *data, size_t dlen,
+                   char *outbuf, size_t outbufsize);
 
+#endif
diff --git a/src/steg/swfSteg.cc b/src/steg/swfSteg.cc
index cd371f3..c8a18c1 100644
--- a/src/steg/swfSteg.cc
+++ b/src/steg/swfSteg.cc
@@ -1,5 +1,11 @@
+#include "util.h"
 #include "swfSteg.h"
+#include "connections.h"
+#include "payloads.h"
+#include "zlib.h"
+#include "zpack.h"
 
+#include <event2/buffer.h>
 
 static const char http_response_1[] =
   "HTTP/1.1 200 OK\r\n"
@@ -9,17 +15,7 @@ static const char http_response_1[] =
   "Content-Type: application/x-shockwave-flash\r\n"
   "Content-Length: ";
 
-
-
-
-
-
-
-
-
-
-
-unsigned int 
+unsigned int
 swf_wrap(payloads& pl, char* inbuf, int in_len, char* outbuf, int out_sz) {
 
   char* swf;
diff --git a/src/steg/swfSteg.h b/src/steg/swfSteg.h
index 712a3a3..b8336b2 100644
--- a/src/steg/swfSteg.h
+++ b/src/steg/swfSteg.h
@@ -1,38 +1,21 @@
 #ifndef _SWFSTEG_H
 #define _SWFSTEG_H
 
-
-#include "util.h"
-#include "connections.h"
-#include "steg.h"
-#include "payloads.h"
-#include "cookies.h"
-#include "pdfSteg.h"
-#include "zpack.h"
-
-
-#include <event2/buffer.h>
-#include <stdio.h>
-
 struct payloads;
 
 #define SWF_SAVE_HEADER_LEN 1500
 #define SWF_SAVE_FOOTER_LEN 1500
 
-
-unsigned int 
+unsigned int
 swf_wrap(payloads& pl, char* inbuf, int in_len, char* outbuf, int out_sz);
 
-unsigned int 
+unsigned int
 swf_unwrap(char* inbuf, int in_len, char* outbuf, int out_sz);
 
-int 
+int
 http_server_SWF_transmit(payloads& pl, struct evbuffer *source, conn_t *conn);
 
-
 int
 http_handle_client_SWF_receive(steg_t *s, conn_t *conn, struct evbuffer *dest, struct evbuffer* source);
 
 #endif
-
-
diff --git a/src/steg/zpack.h b/src/steg/zpack.h
index 65cd28d..d0e5cb2 100644
--- a/src/steg/zpack.h
+++ b/src/steg/zpack.h
@@ -1,10 +1,5 @@
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <time.h>
-#include <stdlib.h>
-#include "zlib.h"
-
+#ifndef _ZPACK_H
+#define _ZPACK_H
 
 int def(char *source, int slen, char *dest, int dlen, int level);
 int inf(char *source, int slen, char *dest, int dlen);
@@ -12,3 +7,5 @@ void zerr(int ret);
 int gzInflate(char *source, int slen, char *dest, int dlen);
 int gzDeflate(char* start, off_t insz, char *buf, off_t outsz, time_t mtime);
 unsigned int generate_crc32c(char *buffer, size_t length);
+
+#endif
diff --git a/src/test/tinytest_macros.h b/src/test/tinytest_macros.h
index 40d17e2..cf5a2a2 100644
--- a/src/test/tinytest_macros.h
+++ b/src/test/tinytest_macros.h
@@ -168,6 +168,10 @@
 	tt_assert_test_type(a,b,#a" "#op" "#b,void*,			\
 			    (_val1 op _val2),"%p")
 
+#define tt_char_op(a,op,b)                                              \
+        tt_assert_test_type(a,b,#a" "#op" "#b,int,                      \
+                            (_val1 op _val2),"'%c'")
+
 #define tt_str_op(a,op,b)						\
 	tt_assert_test_type(a,b,#a" "#op" "#b,const char *,		\
 			    (strcmp(_val1,_val2) op 0),"<%s>")
@@ -176,7 +180,7 @@
   tt_assert_test_fmt_type(a,b,#a" "#op" "#b,                            \
                           const char *,                                 \
                           (strncmp(_val1, _val2, len) op 0),            \
-                          char *, "%s",                                 \
+                          char *, "<%s>",                               \
                           { _print = xstrndup(_value, len); },          \
                           { free(_print); }                             \
                           );
@@ -185,7 +189,7 @@
   tt_assert_test_fmt_type(a,b,#a" "#op" "#b,                            \
                           const char *,                                 \
                           (memcmp(_val1, _val2, len) op 0),             \
-                          char *, "%s",                                 \
+                          char *, "<%s>",                               \
                           { _print = tt_base16_encode(_value, len); },  \
                           { free(_print); }                             \
                           );
diff --git a/src/test/unittest_pdfsteg.cc b/src/test/unittest_pdfsteg.cc
new file mode 100644
index 0000000..cf9e97d
--- /dev/null
+++ b/src/test/unittest_pdfsteg.cc
@@ -0,0 +1,82 @@
+/* Copyright 2011, 2012 SRI International
+   See LICENSE for other credits and copying information */
+
+#include "util.h"
+#include "unittest.h"
+#include "../steg/pdfSteg.h"
+
+static void
+test_pdf_add_remove_delimiters(void *)
+{
+  const char *data1 = "this is a test?? yes!";
+  char data2[100];
+  char data3[100];
+  int dlen2, dlen3;
+  bool end = false, escape = false;
+
+  memset(data2, 0, sizeof data2);
+  memset(data3, 0, sizeof data3);
+
+  dlen2 = pdf_add_delimiter(data1, strlen(data1), data2, 100, '?', '.');
+  tt_int_op(dlen2, ==, 25);
+  tt_stn_op(data2, ==, "this is a test???? yes!?", 24);
+  tt_char_op(data2[24], !=, '?');
+
+  dlen3 = pdf_remove_delimiter(data2, dlen2, data3, 100, '?', &end, &escape);
+  tt_int_op(dlen3, ==, 21);
+  tt_str_op(data3, ==, data1);
+  tt_bool_op(end, ==, true);
+  tt_bool_op(escape, ==, false);
+
+ end:;
+}
+
+static void
+test_pdf_wrap_unwrap(void *)
+{
+  const char *pdf =
+    "[PDFHDR][STUFFS1]>>streamABCDEFGHIJYYendstream"
+    "[STUFFS2]>>streamABCDEFGHIJYYendstream[STUFF3][PDFTRAILER]";
+
+  const char *const tests[] = {
+    "12345",
+    "123456789012",
+    "12345678901",
+    "1234567890?",
+    0
+  };
+
+  char out[200];
+  char orig[200];
+  int i;
+  size_t r1, r2;
+  ssize_t rv;
+
+  for (i = 0; tests[i]; i++) {
+    memset(out, 0, sizeof out);
+    memset(orig, 0, sizeof out);
+    rv = pdf_wrap(tests[i], strlen(tests[i]),
+                  pdf, strlen(pdf),
+                  out, sizeof out);
+    tt_int_op(rv, >, 0);
+    r1 = rv;
+    tt_int_op(r1, ==, strlen(pdf));
+
+    rv = pdf_unwrap(out, r1, orig, sizeof orig);
+    tt_int_op(rv, >, 0);
+    r2 = rv;
+    tt_int_op(r2, ==, strlen(tests[i]));
+    tt_stn_op(orig, ==, tests[i], r2);
+  }
+
+ end:;
+}
+
+#define T(name) \
+  { #name, test_pdf_##name, 0, 0, 0 }
+
+struct testcase_t pdf_tests[] = {
+  T(add_remove_delimiters),
+  T(wrap_unwrap),
+  END_OF_TESTCASES
+};
diff --git a/src/util.cc b/src/util.cc
index b813ae9..a667abd 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -17,9 +17,6 @@
 #include <sys/un.h>
 #endif
 
-/** Any size_t larger than this amount is likely to be an underflow. */
-#define SIZE_T_CEILING  (SIZE_MAX/2 - 16)
-
 /**************************** Memory Allocation ******************************/
 
 static void ATTR_NORETURN
diff --git a/src/util.h b/src/util.h
index 05bc6d0..167af8e 100644
--- a/src/util.h
+++ b/src/util.h
@@ -57,6 +57,9 @@ struct event_base;
 
 /***** Memory allocation. *****/
 
+/** Any size_t larger than this amount is likely to be an underflow. */
+#define SIZE_T_CEILING  (SIZE_MAX/2 - 16)
+
 /* Because this isn't Tor and functions named "tor_whatever" would be
    confusing, I am instead following the GNU convention of naming
    allocate-memory-or-crash functions "xwhatever". Also, at this time





More information about the tor-commits mailing list