changeset 157:49d4a18c4928

- Switched URL_DATA type from char* to a dStr.
author jcid
date Sat, 29 Mar 2008 15:28:06 +0100
parents 14f50d7607ed
children 5a0ce35806df
files ChangeLog dlib/dlib.c dlib/dlib.h src/IO/IO.c src/IO/Url.h src/IO/http.c src/cache.c src/capi.c src/html.cc src/url.c src/url.h
diffstat 11 files changed, 67 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Mar 26 15:46:46 2008 +0100
+++ b/ChangeLog	Sat Mar 29 15:28:06 2008 +0100
@@ -92,6 +92,7 @@
  - Made a cleanup in cache's parse header code.
  - Added support for "charset" in the META element.
  - Added a_Capi_get_flags(). It requests a cache entry's status as flags.
+ - Switched URL_DATA type from char* to a dStr.
    Patch: place, Jorge Arellano Cid
 +- Fixed a va_list-related SEGFAULT on 64bit-arch in dStr_vsprintfa().
    Added const declarations in html parser.
--- a/dlib/dlib.c	Wed Mar 26 15:46:46 2008 +0100
+++ b/dlib/dlib.c	Sat Mar 29 15:28:06 2008 +0100
@@ -210,7 +210,7 @@
 
    Dstr *ds = dNew(Dstr, 1);
    ds->str = NULL;
-   dStr_resize(ds, sz, 0);
+   dStr_resize(ds, sz + 1, 0); /* (sz + 1) for the extra '\0' */
    return ds;
 }
 
@@ -403,6 +403,18 @@
 }
 
 /*
+ * Compare two dStrs.
+ */
+int dStr_cmp(Dstr *ds1, Dstr *ds2)
+{
+   int ret = 0;
+
+   if (ds1 && ds2)
+      ret = memcmp(ds1->str, ds2->str, MIN(ds1->len+1, ds2->len+1));
+   return ret;
+}
+
+/*
  *- dList ---------------------------------------------------------------------
  */
 
--- a/dlib/dlib.h	Wed Mar 26 15:46:46 2008 +0100
+++ b/dlib/dlib.h	Sat Mar 29 15:28:06 2008 +0100
@@ -106,6 +106,7 @@
 void dStr_vsprintf (Dstr *ds, const char *format, va_list argp);
 void dStr_sprintf (Dstr *ds, const char *format, ...);
 void dStr_sprintfa (Dstr *ds, const char *format, ...);
+int  dStr_cmp(Dstr *ds1, Dstr *ds2);
 
 /*
  *-- dList --------------------------------------------------------------------
--- a/src/IO/IO.c	Wed Mar 26 15:46:46 2008 +0100
+++ b/src/IO/IO.c	Sat Mar 29 15:28:06 2008 +0100
@@ -354,6 +354,7 @@
          case OpAbort:
             io = Info->LocalKey;
             if (io->Buf->len > 0) {
+               /* MSG can be truncated by embedded NULLs */
                MSG_WARN("IO_write, closing with pending data not sent\n");
                MSG_WARN(" \"%s\"\n", io->Buf->str);
             }
--- a/src/IO/Url.h	Wed Mar 26 15:46:46 2008 +0100
+++ b/src/IO/Url.h	Sat Mar 29 15:28:06 2008 +0100
@@ -3,7 +3,7 @@
 
 #include "../chain.h"
 #include "../url.h"
-
+#include "../../dlib/dlib.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -16,7 +16,7 @@
 int a_Http_init(void);
 int a_Http_proxy_auth(void);
 void a_Http_set_proxy_passwd(char *str);
-char *a_Http_make_query_str(const DilloUrl *url, bool_t use_proxy);
+Dstr *a_Http_make_query_str(const DilloUrl *url, bool_t use_proxy);
 
 void a_Http_ccc (int Op, int Branch, int Dir, ChainLink *Info,
                  void *Data1, void *Data2);
--- a/src/IO/http.c	Wed Mar 26 15:46:46 2008 +0100
+++ b/src/IO/http.c	Sat Mar 29 15:28:06 2008 +0100
@@ -180,9 +180,9 @@
    if (URL_FLAGS(url) & URL_MultipartEnc) {
       MSG("submitting multipart/form-data!\n");
       dstr = dStr_new("multipart/form-data; boundary=\"");
-      if (strlen(URL_DATA(url)) > 2) {
+      if (URL_DATA(url)->len > 2) {
          /* boundary lines have "--" prepended. Skip that. */
-         const char *start = URL_DATA(url) + 2;
+         const char *start = URL_DATA(url)->str + 2;
          char *eol = strchr(start, '\r');
          if (eol)
             dStr_append_l(dstr, start, eol - start);
@@ -200,9 +200,9 @@
 /*
  * Make the http query string
  */
-char *a_Http_make_query_str(const DilloUrl *url, bool_t use_proxy)
+Dstr *a_Http_make_query_str(const DilloUrl *url, bool_t use_proxy)
 {
-   char *str, *ptr, *cookies, *referer;
+   char *ptr, *cookies, *referer;
    Dstr *s_port     = dStr_new(""),
         *query      = dStr_new(""),
         *full_path  = dStr_new(""),
@@ -246,12 +246,12 @@
          "Content-Length: %ld\r\n"
          "Content-Type: %s\r\n"
          "%s"
-         "\r\n"
-         "%s",
+         "\r\n",
          full_path->str, URL_HOST(url), s_port->str,
          proxy_auth->str, referer, VERSION,
-         (long)strlen(URL_DATA(url)), content_type->str,
-         cookies, URL_DATA(url));
+         URL_DATA(url)->len, content_type->str,
+         cookies);
+      dStr_append_l(query, URL_DATA(url)->str, URL_DATA(url)->len);
       dStr_free(content_type, TRUE);
    } else {
       dStr_sprintfa(
@@ -276,13 +276,12 @@
    dFree(referer);
    dFree(cookies);
 
-   str = query->str;
-   dStr_free(query, FALSE);
    dStr_free(s_port, TRUE);
    dStr_free(full_path, TRUE);
    dStr_free(proxy_auth, TRUE);
-   DEBUG_MSG(4, "Query:\n%s", str);
-   return str;
+   /* debug msg will fail on embedded NULLs */
+   DEBUG_MSG(4, "Query:\n%s", query->str);
+   return query;
 }
 
 /*
@@ -290,12 +289,12 @@
  */
 static void Http_send_query(ChainLink *Info, SocketData_t *S)
 {
-   char *query;
+   Dstr *query;
    DataBuf *dbuf;
 
    /* Create the query */
    query = a_Http_make_query_str(S->Url, S->use_proxy);
-   dbuf = a_Chain_dbuf_new(query, (int)strlen(query), 0);
+   dbuf = a_Chain_dbuf_new(query->str, query->len, 0);
 
    /* actually this message is sent too early.
     * It should go when the socket is ready for writing (i.e. connected) */
@@ -306,7 +305,7 @@
    a_Chain_bcb(OpStart, Info, &S->SockFD, NULL);
    a_Chain_bcb(OpSend, Info, dbuf, NULL);
    dFree(dbuf);
-   dFree(query);
+   dStr_free(query, 1);
 
    /* Tell the cache to start the receiving CCC for the answer */
    a_Chain_fcb(OpSend, Info, &S->SockFD, "SockFD");
--- a/src/cache.c	Wed Mar 26 15:46:46 2008 +0100
+++ b/src/cache.c	Sat Mar 29 15:28:06 2008 +0100
@@ -576,7 +576,7 @@
        * with huge files (e.g. iso files).
        * Note: the buffer grows automatically. */
       dStr_free(entry->Data, 1);
-      entry->Data = dStr_sized_new(MIN(entry->ExpectedSize+1, MAX_INIT_BUF));
+      entry->Data = dStr_sized_new(MIN(entry->ExpectedSize, MAX_INIT_BUF));
    }
 
    /* Get Content-Type */
--- a/src/capi.c	Wed Mar 26 15:46:46 2008 +0100
+++ b/src/capi.c	Sat Mar 29 15:28:06 2008 +0100
@@ -212,7 +212,7 @@
 
    /* test POST and GET */
    if (dStrcasecmp(URL_SCHEME(web->url), "dpi") == 0 &&
-       (strchr(URL_STR(web->url), '?') || URL_DATA_(web->url))) {
+       URL_FLAGS(web->url) & (URL_Post + URL_Get)) {
       /* only allow dpi requests from dpi-generated urls */
       if (a_Nav_stack_size(web->bw)) {
          referer = a_History_get_url(NAV_TOP_UIDX(web->bw));
@@ -227,8 +227,10 @@
    if (!allow) {
       MSG("Capi_dpi_verify_request: Permission Denied!\n");
       MSG("  URL_STR : %s\n", URL_STR(web->url));
-      if (URL_DATA_(web->url))
-         MSG("  URL_DATA: %s\n", URL_DATA(web->url));
+      if (URL_FLAGS(web->url) & URL_Post) {
+         /* MSG will fail on embedded NULLs */
+         MSG("  URL_DATA: %s\n", URL_DATA(web->url)->str);
+      }
    }
    return allow;
 }
@@ -271,14 +273,15 @@
  */
 static char *Capi_dpi_build_cmd(DilloWeb *web, char *server)
 {
-   char *cmd, *http_query;
+   char *cmd;
 
    if (strcmp(server, "proto.https") == 0) {
       /* Let's be kind and make the HTTP query string for the dpi */
-      http_query = a_Http_make_query_str(web->url, FALSE);
+      Dstr *http_query = a_Http_make_query_str(web->url, FALSE);
+      /* BUG: embedded NULLs in query data will truncate message */
       cmd = a_Dpip_build_cmd("cmd=%s url=%s query=%s",
-                             "open_url", URL_STR(web->url), http_query);
-      dFree(http_query);
+                             "open_url", URL_STR(web->url), http_query->str);
+      dStr_free(http_query, 1);
 
    } else if (strcmp(server, "downloads") == 0) {
       /* let the downloads server get it */
--- a/src/html.cc	Wed Mar 26 15:46:46 2008 +0100
+++ b/src/html.cc	Sat Mar 29 15:28:06 2008 +0100
@@ -4150,7 +4150,8 @@
   
       if (form->method == DILLO_HTML_METHOD_POST) {
          new_url = a_Url_new(action_str, NULL, 0, 0, 0);
-         a_Url_set_data(new_url, DataStr->str);
+         /* new_url keeps the dStr and sets DataStr to NULL */
+         a_Url_set_data(new_url, &DataStr);
          a_Url_set_flags(new_url, URL_FLAGS(new_url) | URL_Post);
          if (form->enc == DILLO_HTML_ENC_MULTIPART) {
             a_Url_set_flags(new_url, URL_FLAGS(new_url) | URL_MultipartEnc);
@@ -4171,7 +4172,7 @@
       a_Nav_push(html->bw, new_url);
       dFree(action_str);
       dStr_free(boundary, 1);
-      dStr_free(DataStr, TRUE);
+      dStr_free(DataStr, 1);
       if (encoder != (iconv_t) -1)
          (void)iconv_close(encoder);
       a_Url_free(new_url);
--- a/src/url.c	Wed Mar 26 15:46:46 2008 +0100
+++ b/src/url.c	Sat Mar 29 15:28:06 2008 +0100
@@ -55,6 +55,11 @@
 
 static const char *HEX = "0123456789ABCDEF";
 
+/* URL-field compare methods */
+#define URL_STR_FIELD_CMP(s1,s2) \
+   (s1) && (s2) ? strcmp(s1,s2) : !(s1) && !(s2) ? 0 : (s1) ? 1 : -1
+#define URL_STR_FIELD_I_CMP(s1,s2) \
+   (s1) && (s2) ? dStrcasecmp(s1,s2) : !(s1) && !(s2) ? 0 : (s1) ? 1 : -1
 
 /*
  * Return the url as a string.
@@ -183,7 +188,7 @@
       if (url->hostname != url->authority)
          dFree((char *)url->hostname);
       dFree((char *)url->buffer);
-      dFree((char *)url->data);
+      dStr_free(url->data, 1);
       dFree((char *)url->alt);
       dFree(url);
    }
@@ -334,7 +339,7 @@
  *     hostname           = "dillo.sf.net"
  *     port               = 8080
  *     flags              = 0
- *     data               = NULL
+ *     data               = Dstr * ("")
  *     alt                = NULL
  *     ismap_url_len      = 0
  *     scrolling_position = 0
@@ -392,6 +397,7 @@
 
    /* Fill url data */
    url = Url_object_new(SolvedUrl->str);
+   url->data = dStr_new("");
    url->url_string = SolvedUrl;
    url->flags = flags;
    url->scrolling_position_x = posx;
@@ -418,14 +424,14 @@
    url->url_string           = dStr_new(URL_STR(ori));
    url->port                 = ori->port;
    url->flags                = ori->flags;
-   url->data                 = dStrdup(ori->data);
    url->alt                  = dStrdup(ori->alt);
    url->ismap_url_len        = ori->ismap_url_len;
    url->scrolling_position_x = ori->scrolling_position_x;
    url->scrolling_position_y = ori->scrolling_position_y;
    url->illegal_chars        = ori->illegal_chars;
    url->illegal_chars_spc    = ori->illegal_chars_spc;
-
+   url->data                 = dStr_sized_new(URL_DATA(ori)->len);
+   dStr_append_l(url->data, URL_DATA(ori)->str, URL_DATA(ori)->len);
    return url;
 }
 
@@ -452,7 +458,7 @@
                      B->path ? B->path + (*B->path == '/') : "")) == 0 &&
         //(st = URL_STR_FIELD_CMP(A->path, B->path)) == 0 &&
         (st = URL_STR_FIELD_CMP(A->query, B->query)) == 0 &&
-        (st = URL_STR_FIELD_CMP(A->data, B->data)) == 0 &&
+        (st = dStr_cmp(A->data, B->data)) == 0 &&
         (st = URL_STR_FIELD_I_CMP(A->scheme, B->scheme) == 0)))
       return 0;
    return st;
@@ -470,11 +476,12 @@
 /*
  * Set DilloUrl data (like POST info, etc.)
  */
-void a_Url_set_data(DilloUrl *u, char *data)
+void a_Url_set_data(DilloUrl *u, Dstr **data)
 {
    if (u) {
-      dFree((char *)u->data);
-      u->data = dStrdup(data);
+      dStr_free(u->data, 1);
+      u->data = *data;
+      *data = NULL;
    }
 }
 
--- a/src/url.h	Wed Mar 26 15:46:46 2008 +0100
+++ b/src/url.h	Sat Mar 29 15:28:06 2008 +0100
@@ -55,9 +55,10 @@
 #define URL_QUERY_(u)               u->query
 #define URL_FRAGMENT_(u)            u->fragment
 #define URL_HOST_(u)                a_Url_hostname(u)
-#define URL_DATA_(u)                u->data
 #define URL_ALT_(u)                 u->alt
 #define URL_STR_(u)                 a_Url_str(u)
+/* this returns a Dstr* */
+#define URL_DATA_(u)                u->data
 /* these return an integer */
 #define URL_PORT_(u)                (URL_HOST(u) ? u->port : u->port)
 #define URL_FLAGS_(u)               u->flags
@@ -67,7 +68,7 @@
 #define URL_ILLEGAL_CHARS_SPC_(u)   url->illegal_chars_spc
 
 /*
- * Access methods that always return a string:
+ * Access methods that never return NULL.
  * When the "empty" and "undefined" concepts of RFC-2396 are irrelevant to
  * the caller, and a string is required, use these methods instead:
  */
@@ -78,7 +79,7 @@
 #define URL_QUERY(u)                NPTR2STR(URL_QUERY_(u))
 #define URL_FRAGMENT(u)             NPTR2STR(URL_FRAGMENT_(u))
 #define URL_HOST(u)                 NPTR2STR(URL_HOST_(u))
-#define URL_DATA(u)                 NPTR2STR(URL_DATA_(u))
+#define URL_DATA(u)                 URL_DATA_(u)
 #define URL_ALT(u)                  NPTR2STR(URL_ALT_(u))
 #define URL_STR(u)                  NPTR2STR(URL_STR_(u))
 #define URL_PORT(u)                 URL_PORT_(u)
@@ -89,13 +90,6 @@
 #define URL_ILLEGAL_CHARS_SPC(u)    URL_ILLEGAL_CHARS_SPC_(u)
 
 
-/* URL-field compare methods */
-#define URL_STR_FIELD_CMP(s1,s2) \
-   (s1) && (s2) ? strcmp(s1,s2) : !(s1) && !(s2) ? 0 : (s1) ? 1 : -1
-#define URL_STR_FIELD_I_CMP(s1,s2) \
-   (s1) && (s2) ? dStrcasecmp(s1,s2) : !(s1) && !(s2) ? 0 : (s1) ? 1 : -1
-
-
 typedef struct _DilloUrl DilloUrl;
 
 #ifdef __cplusplus
@@ -113,7 +107,7 @@
    const char *hostname;          //
    int port;
    int flags;
-   const char *data;              /* POST */
+   Dstr *data;                    /* POST */
    const char *alt;               /* "alt" text (used by image maps) */
    int ismap_url_len;             /* Used by server side image maps */
    int32_t scrolling_position_x,  /* remember position of visited urls */
@@ -131,7 +125,7 @@
 DilloUrl* a_Url_dup(const DilloUrl *u);
 int a_Url_cmp(const DilloUrl *A, const DilloUrl *B);
 void a_Url_set_flags(DilloUrl *u, int flags);
-void a_Url_set_data(DilloUrl *u, char *data);
+void a_Url_set_data(DilloUrl *u, Dstr **data);
 void a_Url_set_alt(DilloUrl *u, const char *alt);
 void a_Url_set_pos(DilloUrl *u, int32_t posx, int32_t posy);
 void a_Url_set_ismap_coords(DilloUrl *u, char *coord_str);