chiark / gitweb /
More tests for mime.c
authorRichard Kettlewell <rjk@greenend.org.uk>
Fri, 11 Jan 2008 11:16:54 +0000 (11:16 +0000)
committerRichard Kettlewell <rjk@greenend.org.uk>
Fri, 11 Jan 2008 11:16:54 +0000 (11:16 +0000)
lib/mime.c
lib/mime.h
lib/t-mime.c

index 0e7d0976fb5afc931c1ca41e2c6dec54deece6d4..d79cc2a55696c433a306adc72074d371a8f713e6 100644 (file)
@@ -51,7 +51,7 @@ static int whitespace(int c) {
 }
 
 /** @brief Match RFC2045 tspecial characters */
 }
 
 /** @brief Match RFC2045 tspecial characters */
-static int tspecial(int c) {
+int mime_tspecial(int c) {
   switch(c) {
   case '(':
   case ')':
   switch(c) {
   case '(':
   case ')':
@@ -75,7 +75,7 @@ static int tspecial(int c) {
 }
 
 /** @brief Match RFC2616 separator characters */
 }
 
 /** @brief Match RFC2616 separator characters */
-static int http_separator(int c) {
+int mime_http_separator(int c) {
   switch(c) {
   case '(':
   case ')':
   switch(c) {
   case '(':
   case ')':
@@ -151,7 +151,7 @@ static const char *skipwhite(const char *s, int rfc822_comments) {
 
 /** @brief Test for a word character
  * @param c Character to test
 
 /** @brief Test for a word character
  * @param c Character to test
- * @param special tspecial() (MIME/RFC2405) or http_separator() (HTTP/RFC2616)
+ * @param special mime_tspecial() (MIME/RFC2405) or mime_http_separator() (HTTP/RFC2616)
  * @return 1 if @p c is a word character, else 0
  */
 static int iswordchar(int c, int (*special)(int)) {
  * @return 1 if @p c is a word character, else 0
  */
 static int iswordchar(int c, int (*special)(int)) {
@@ -161,13 +161,13 @@ static int iswordchar(int c, int (*special)(int)) {
 /** @brief Parse an RFC1521/RFC2616 word
  * @param s Pointer to start of word
  * @param valuep Where to store value
 /** @brief Parse an RFC1521/RFC2616 word
  * @param s Pointer to start of word
  * @param valuep Where to store value
- * @param special tspecial() (MIME/RFC2405) or http_separator() (HTTP/RFC2616)
+ * @param special mime_tspecial() (MIME/RFC2405) or mime_http_separator() (HTTP/RFC2616)
  * @return Pointer just after end of word or NULL if there's no word
  *
  * A word is a token or a quoted-string.
  */
  * @return Pointer just after end of word or NULL if there's no word
  *
  * A word is a token or a quoted-string.
  */
-static const char *parseword(const char *s, char **valuep,
-                            int (*special)(int)) {
+const char *mime_parse_word(const char *s, char **valuep,
+                           int (*special)(int)) {
   struct dynstr value[1];
   int c;
 
   struct dynstr value[1];
   int c;
 
@@ -201,14 +201,14 @@ static const char *parseword(const char *s, char **valuep,
 /** @brief Parse an RFC1521/RFC2616 token
  * @param s Pointer to start of token
  * @param valuep Where to store value
 /** @brief Parse an RFC1521/RFC2616 token
  * @param s Pointer to start of token
  * @param valuep Where to store value
- * @param special tspecial() (MIME/RFC2405) or http_separator() (HTTP/RFC2616)
+ * @param special mime_tspecial() (MIME/RFC2405) or mime_http_separator() (HTTP/RFC2616)
  * @return Pointer just after end of token or NULL if there's no token
  */
 static const char *parsetoken(const char *s, char **valuep,
                              int (*special)(int)) {
   if(*s == '"')
     return 0;
  * @return Pointer just after end of token or NULL if there's no token
  */
 static const char *parsetoken(const char *s, char **valuep,
                              int (*special)(int)) {
   if(*s == '"')
     return 0;
-  return parseword(s, valuep, special);
+  return mime_parse_word(s, valuep, special);
 }
 
 /** @brief Parse a MIME content-type field
 }
 
 /** @brief Parse a MIME content-type field
@@ -231,7 +231,7 @@ int mime_content_type(const char *s,
     return -1;
   if(!*s)
     return -1;
     return -1;
   if(!*s)
     return -1;
-  while(*s && !tspecial(*s) && !whitespace(*s))
+  while(*s && !mime_tspecial(*s) && !whitespace(*s))
     dynstr_append(&type, tolower((unsigned char)*s++));
   if(!(s = skipwhite(s, 1)))
     return -1;
     dynstr_append(&type, tolower((unsigned char)*s++));
   if(!(s = skipwhite(s, 1)))
     return -1;
@@ -240,7 +240,7 @@ int mime_content_type(const char *s,
   dynstr_append(&type, '/');
   if(!(s = skipwhite(s, 1)))
     return -1;
   dynstr_append(&type, '/');
   if(!(s = skipwhite(s, 1)))
     return -1;
-  while(*s && !tspecial(*s) && !whitespace(*s))
+  while(*s && !mime_tspecial(*s) && !whitespace(*s))
     dynstr_append(&type, tolower((unsigned char)*s++));
   if(!(s = skipwhite(s, 1)))
     return -1;
     dynstr_append(&type, tolower((unsigned char)*s++));
   if(!(s = skipwhite(s, 1)))
     return -1;
@@ -252,7 +252,7 @@ int mime_content_type(const char *s,
       return -1;
     if(!*s)
       return -1;
       return -1;
     if(!*s)
       return -1;
-    while(*s && !tspecial(*s) && !whitespace(*s))
+    while(*s && !mime_tspecial(*s) && !whitespace(*s))
       dynstr_append(&parametername, tolower((unsigned char)*s++));
     if(!(s = skipwhite(s, 1)))
       return -1;
       dynstr_append(&parametername, tolower((unsigned char)*s++));
     if(!(s = skipwhite(s, 1)))
       return -1;
@@ -260,7 +260,7 @@ int mime_content_type(const char *s,
       return -1;
     if(!(s = skipwhite(s, 1)))
       return -1;
       return -1;
     if(!(s = skipwhite(s, 1)))
       return -1;
-    if(!(s = parseword(s, &parametervalue, tspecial)))
+    if(!(s = mime_parse_word(s, &parametervalue, mime_tspecial)))
       return -1;
     if(!(s = skipwhite(s, 1)))
       return -1;
       return -1;
     if(!(s = skipwhite(s, 1)))
       return -1;
@@ -294,7 +294,7 @@ const char *mime_parse(const char *s,
   while(*s && !iscrlf(s)) {
     dynstr_init(&name);
     dynstr_init(&value);
   while(*s && !iscrlf(s)) {
     dynstr_init(&name);
     dynstr_init(&value);
-    while(*s && !tspecial(*s) && !whitespace(*s))
+    while(*s && !mime_tspecial(*s) && !whitespace(*s))
       dynstr_append(&name, tolower((unsigned char)*s++));
     if(!(s = skipwhite(s, 1)))
       return 0;
       dynstr_append(&name, tolower((unsigned char)*s++));
     if(!(s = skipwhite(s, 1)))
       return 0;
@@ -421,7 +421,7 @@ int mime_rfc2388_content_disposition(const char *s,
     return -1;
   if(!*s)
     return -1;
     return -1;
   if(!*s)
     return -1;
-  while(*s && !tspecial(*s) && !whitespace(*s))
+  while(*s && !mime_tspecial(*s) && !whitespace(*s))
     dynstr_append(&disposition, tolower((unsigned char)*s++));
   if(!(s = skipwhite(s, 1)))
     return -1;
     dynstr_append(&disposition, tolower((unsigned char)*s++));
   if(!(s = skipwhite(s, 1)))
     return -1;
@@ -433,7 +433,7 @@ int mime_rfc2388_content_disposition(const char *s,
       return -1;
     if(!*s)
       return -1;
       return -1;
     if(!*s)
       return -1;
-    while(*s && !tspecial(*s) && !whitespace(*s))
+    while(*s && !mime_tspecial(*s) && !whitespace(*s))
       dynstr_append(&parametername, tolower((unsigned char)*s++));
     if(!(s = skipwhite(s, 1)))
       return -1;
       dynstr_append(&parametername, tolower((unsigned char)*s++));
     if(!(s = skipwhite(s, 1)))
       return -1;
@@ -441,7 +441,7 @@ int mime_rfc2388_content_disposition(const char *s,
       return -1;
     if(!(s = skipwhite(s, 1)))
       return -1;
       return -1;
     if(!(s = skipwhite(s, 1)))
       return -1;
-    if(!(s = parseword(s, parametervaluep, tspecial)))
+    if(!(s = mime_parse_word(s, parametervaluep, mime_tspecial)))
       return -1;
     if(!(s = skipwhite(s, 1)))
       return -1;
       return -1;
     if(!(s = skipwhite(s, 1)))
       return -1;
@@ -523,13 +523,13 @@ int parse_cookie(const char *s,
       s = skipwhite(s, 0);
       continue;
     }
       s = skipwhite(s, 0);
       continue;
     }
-    if(!(s = parsetoken(s, &n, http_separator)))
+    if(!(s = parsetoken(s, &n, mime_http_separator)))
       return -1;
     s = skipwhite(s, 0);
     if(*s++ != '=')
       return -1;
     s = skipwhite(s, 0);
       return -1;
     s = skipwhite(s, 0);
     if(*s++ != '=')
       return -1;
     s = skipwhite(s, 0);
-    if(!(s = parseword(s, &v, http_separator)))
+    if(!(s = mime_parse_word(s, &v, mime_http_separator)))
       return -1;
     if(n[0] == '$') {
       /* Some bit of meta-information */
       return -1;
     if(n[0] == '$') {
       /* Some bit of meta-information */
@@ -597,7 +597,7 @@ char *quote822(const char *s, int force) {
   if(!force) {
     /* See if we need to quote */
     for(t = s; (c = (unsigned char)*t); ++t) {
   if(!force) {
     /* See if we need to quote */
     for(t = s; (c = (unsigned char)*t); ++t) {
-      if(tspecial(c) || http_separator(c) || whitespace(c))
+      if(mime_tspecial(c) || mime_http_separator(c) || whitespace(c))
        break;
     }
     if(*t)
        break;
     }
     if(*t)
index d9c28ac90bf3abc51cd775bf56b6d96647ba3adb..434b373c806668e21d42c23c3b137c232bf748b3 100644 (file)
@@ -96,6 +96,10 @@ char *mime_to_qp(const char *text);
 const char *mime_encode_text(const char *text,
                             const char **charsetp,
                             const char **encodingp);
 const char *mime_encode_text(const char *text,
                             const char **charsetp,
                             const char **encodingp);
+const char *mime_parse_word(const char *s, char **valuep,
+                           int (*special)(int));
+int mime_http_separator(int c);
+int mime_tspecial(int c);
 
 #endif /* MIME_H */
 
 
 #endif /* MIME_H */
 
index 05ae8b5aea9537336dfe5a235a1b9f2dec6dd878..eb5ee7ca2b609b340507609c8240cd5ba353e61a 100644 (file)
@@ -38,7 +38,7 @@ void test_mime(void) {
   char *t, *n, *v;
   struct vector parts[1];
   struct kvp *k;
   char *t, *n, *v;
   struct vector parts[1];
   struct kvp *k;
-  const char *s;
+  const char *s, *cs, *enc;
   hash *h;
 
   fprintf(stderr, "test_mime\n");
   hash *h;
 
   fprintf(stderr, "test_mime\n");
@@ -308,6 +308,31 @@ void test_mime(void) {
   check_string(*(char **)hash_find(h, "content-type"), "text/plain");
   check_string(*(char **)hash_find(h, "content-transfer-encoding"), "BASE64");
   check_string(s, "wibble\r\n");
   check_string(*(char **)hash_find(h, "content-type"), "text/plain");
   check_string(*(char **)hash_find(h, "content-transfer-encoding"), "BASE64");
   check_string(s, "wibble\r\n");
+
+#define CHECK_QUOTE(INPUT, EXPECT) do {                 \
+  s = quote822(INPUT, 0);                               \
+  insist(s != 0);                                       \
+  check_string(s, EXPECT);                              \
+  s = mime_parse_word(s, &t, mime_http_separator);      \
+  check_string(t, INPUT);                               \
+} while(0)
+  CHECK_QUOTE("wibble", "wibble");
+  CHECK_QUOTE("wibble spong", "\"wibble spong\"");
+  CHECK_QUOTE("wibble\\spong", "\"wibble\\\\spong\"");
+  CHECK_QUOTE("wibble\"spong", "\"wibble\\\"spong\"");
+  CHECK_QUOTE("(wibble)", "\"(wibble)\"");
+
+  s = mime_encode_text("wibble\n", &cs, &enc);
+  insist(s != 0);
+  check_string(s, "wibble\n");
+  check_string(cs, "us-ascii");
+  check_string(enc, "7bit");
+
+  s = mime_encode_text("wibble\xC3\xB7\n", &cs, &enc);
+  insist(s != 0);
+  check_string(s, "wibble=C3=B7\n");
+  check_string(cs, "utf-8");
+  check_string(enc, "quoted-printable");
 }
 
 /*
 }
 
 /*