* moved url argument list to hash.
authorWilfried Göesgens <willi@citadel.org>
Wed, 2 Apr 2008 23:45:08 +0000 (23:45 +0000)
committerWilfried Göesgens <willi@citadel.org>
Wed, 2 Apr 2008 23:45:08 +0000 (23:45 +0000)
* carry length of parameter value in the hash for later use
* added Bstr, BSTR and bstr. bstr mustn't be used for dynamic keys, use BSTR instead.
* use BSTR where apropriate.
* fixed crash condition with message posting Mrs. Foobar found out

webcit/addressbook_popup.c
webcit/calendar_tools.c
webcit/iconbar.c
webcit/messages.c
webcit/sieve.c
webcit/webcit.c
webcit/webcit.h

index 89c52b5bc9c7c5679012845e9db0d8531012149f..3004a826095afc5a3023e75efe2f6bc914ba1b6d 100644 (file)
@@ -158,7 +158,7 @@ void display_address_book_inner_div() {
                }
                DeleteHashPos(&it);
                DeleteHash(&List);
-               gotoroom(bstr(saved_roomname));
+               gotoroom((char*)BSTR(saved_roomname)); /* TODO: get rid of typecast */
        }
 
        wprintf("</select>\n");
index 17862aa6c27cc29c2a6130c154e71ab62733bab1..d07fd6f38f18f8e673d577770dea7297e456a775 100644 (file)
@@ -153,11 +153,11 @@ void icaltime_from_webform(struct icaltimetype *t, char *prefix) {
        char timestr[32];
        int month, mday, year, hour, minute;
 
-        sprintf(vname, "%s_month", prefix);     month = atoi(bstr(vname));
-        sprintf(vname, "%s_day", prefix);       mday = atoi(bstr(vname));
-        sprintf(vname, "%s_year", prefix);      year = atoi(bstr(vname));
-        sprintf(vname, "%s_hour", prefix);      hour = atoi(bstr(vname));
-        sprintf(vname, "%s_minute", prefix);    minute = atoi(bstr(vname));
+        sprintf(vname, "%s_month", prefix);     month = atoi(BSTR(vname));
+        sprintf(vname, "%s_day", prefix);       mday = atoi(BSTR(vname));
+        sprintf(vname, "%s_year", prefix);      year = atoi(BSTR(vname));
+        sprintf(vname, "%s_hour", prefix);      hour = atoi(BSTR(vname));
+        sprintf(vname, "%s_minute", prefix);    minute = atoi(BSTR(vname));
 
        sprintf(timestr, "%04d%02d%02dT%02d%02d00", year, month, mday, hour, minute);
         t2 = icaltime_from_string(timestr);
@@ -177,9 +177,9 @@ void icaltime_from_webform_dateonly(struct icaltimetype *t, char *prefix) {
 
        memset(t, 0, sizeof(struct icaltimetype));
 
-        sprintf(vname, "%s_month", prefix);     t->month = atoi(bstr(vname));
-        sprintf(vname, "%s_day", prefix);       t->day = atoi(bstr(vname));
-        sprintf(vname, "%s_year", prefix);      t->year = atoi(bstr(vname));
+        sprintf(vname, "%s_month", prefix);     t->month = atoi(BSTR(vname));
+        sprintf(vname, "%s_day", prefix);       t->day = atoi(BSTR(vname));
+        sprintf(vname, "%s_year", prefix);      t->year = atoi(BSTR(vname));
        t->is_utc = 1;
        t->is_date = 1;
 }
index 6dd17c810ff13d0a7289bb9f954d7b2bb588d206..eceb4c86426ad13166ef87a09d9fab9423564bf8 100644 (file)
@@ -773,10 +773,10 @@ void commit_iconbar(void) {
 
        for (i=0; i<(sizeof(boxen)/sizeof(char *)); ++i) {
                char *Val;
-               if (!strcasecmp(bstr(boxen[i]), "yes")) {
+               if (!strcasecmp(BSTR(boxen[i]), "yes")) {
                        Val = "1";
                }
-               else if (!strcasecmp(bstr(boxen[i]), "yeslist")) {
+               else if (!strcasecmp(BSTR(boxen[i]), "yeslist")) {
                        Val = "2";
                }
                else {
index a9353a93e5097c89420bc8a7871db43d16a7c526..f42def11aac7305408549f301c13056f14cf6054 100644 (file)
@@ -275,39 +275,59 @@ inline void utf8ify_rfc822_string(char *a){};
  * \param      target          Target buffer.
  * \param      maxlen          Maximum size of target buffer.
  * \param      source          Source string to be encoded.
+ * \param       SourceLen       Length of the source string
+ * \returns     encoded length; -1 if non success.
  */
-void webcit_rfc2047encode(char *target, int maxlen, char *source)
+int webcit_rfc2047encode(char *target, int maxlen, char *source, long SourceLen)
 {
+       const char headerStr[] = "=?UTF-8?Q?";
        int need_to_encode = 0;
-       int i, len;
+       int i = 0;
+       int len;
        unsigned char ch;
 
-       if (target == NULL) return;
-       len = strlen(source);
-       for (i=0; i<len; ++i) {
-               if ((source[i] < 32) || (source[i] > 126)) {
+       if ((source == NULL) || 
+           (target == NULL) ||
+           (SourceLen > maxlen)) return -1;
+
+       while ((!IsEmptyStr (&source[i])) && 
+              (need_to_encode == 0) &&
+              (i < SourceLen) ) {
+               if (((unsigned char) source[i] < 32) || 
+                   ((unsigned char) source[i] > 126)) {
                        need_to_encode = 1;
-                       i = len; ///< shortcut. won't become more than 1
                }
+               i++;
        }
 
        if (!need_to_encode) {
-               safestrncpy(target, source, maxlen);
-               return;
+               memcpy (target, source, SourceLen);
+               return SourceLen;
        }
-
-       strcpy(target, "=?UTF-8?Q?");
-       for (i=0; i<len; ++i) {
+       
+       if (sizeof (headerStr + SourceLen + 2) > maxlen)
+               return -1;
+       memcpy (target, headerStr, sizeof (headerStr));
+       len = sizeof (headerStr);
+       for (i=0; (i < SourceLen) && (len < maxlen) ; ++i) {
                ch = (unsigned char) source[i];
                if ((ch < 32) || (ch > 126) || (ch == 61)) {
-                       sprintf(&target[strlen(target)], "=%02X", ch);
+                       sprintf(&target[len], "=%02X", ch);
+                       len += 3;
                }
                else {
-                       sprintf(&target[strlen(target)], "%c", ch);
+                       sprintf(&target[len], "%c", ch);
+                       len ++;
                }
        }
        
-       strcat(target, "?=");
+       if (len + 2 < maxlen) {
+               strcat(&target[len], "?=");
+               len +=2;
+               return len;
+       }
+       else
+               return -1;
 }
 
 
@@ -2973,40 +2993,51 @@ void post_mime_to_server(void) {
  */
 void post_message(void)
 {
+       urlcontent *u;
+       void *U;
        char buf[1024];
-       char encoded_subject[1024];
+       char *encoded_subject;
        static long dont_post = (-1L);
        struct wc_attachment *att, *aptr;
        int is_anonymous = 0;
-       char *display_name;
+       const char *display_name;
+       long dpLen = 0;
+       struct wcsession *WCC = WC;
 
        if (!IsEmptyStr(bstr("force_room"))) {
                gotoroom(bstr("force_room"));
        }
 
-       display_name = bstr("display_name");
+       if (GetHash(WCC->urlstrings, HKEY("display_name"), &U)) {
+               u = (urlcontent*) U;
+               display_name = u->url_data;
+               dpLen = u->url_data_size;
+       }
+       else {
+               display_name="";
+       }
        if (!strcmp(display_name, "__ANONYMOUS__")) {
                display_name = "";
                is_anonymous = 1;
        }
 
-       if (WC->upload_length > 0) {
+       if (WCC->upload_length > 0) {
 
-               lprintf(9, "%s:%d: we are uploading %d bytes\n", __FILE__, __LINE__, WC->upload_length);
+               lprintf(9, "%s:%d: we are uploading %d bytes\n", __FILE__, __LINE__, WCC->upload_length);
                /** There's an attachment.  Save it to this struct... */
                att = malloc(sizeof(struct wc_attachment));
                memset(att, 0, sizeof(struct wc_attachment));
-               att->length = WC->upload_length;
-               strcpy(att->content_type, WC->upload_content_type);
-               strcpy(att->filename, WC->upload_filename);
+               att->length = WCC->upload_length;
+               strcpy(att->content_type, WCC->upload_content_type);
+               strcpy(att->filename, WCC->upload_filename);
                att->next = NULL;
 
                /** And add it to the list. */
-               if (WC->first_attachment == NULL) {
-                       WC->first_attachment = att;
+               if (WCC->first_attachment == NULL) {
+                       WCC->first_attachment = att;
                }
                else {
-                       aptr = WC->first_attachment;
+                       aptr = WCC->first_attachment;
                        while (aptr->next != NULL) aptr = aptr->next;
                        aptr->next = att;
                }
@@ -3027,44 +3058,102 @@ void post_message(void)
                 * Transfer control of this memory from the upload struct
                 * to the attachment struct.
                 */
-               att->data = WC->upload;
-               WC->upload_length = 0;
-               WC->upload = NULL;
+               att->data = WCC->upload;
+               WCC->upload_length = 0;
+               WCC->upload = NULL;
                display_enter();
                return;
        }
 
        if (!IsEmptyStr(bstr("cancel_button"))) {
-               sprintf(WC->ImportantMessage, 
+               sprintf(WCC->ImportantMessage, 
                        _("Cancelled.  Message was not posted."));
        } else if (!IsEmptyStr(bstr("attach_button"))) {
                display_enter();
                return;
        } else if (atol(bstr("postseq")) == dont_post) {
-               sprintf(WC->ImportantMessage, 
+               sprintf(WCC->ImportantMessage, 
                        _("Automatically cancelled because you have already "
                        "saved this message."));
        } else {
-               webcit_rfc2047encode(encoded_subject, sizeof encoded_subject, bstr("subject"));
-               sprintf(buf, "ENT0 1|%s|%d|4|%s|%s||%s|%s|%s|%s",
-                       bstr("recp"),
-                       is_anonymous,
-                       encoded_subject,
-                       display_name,
-                       bstr("cc"),
-                       bstr("bcc"),
-                       bstr("wikipage"),
-                       bstr("my_email_addr")
-               );
-               serv_puts(buf);
+               const char CMD[] = "ENT0 1|%s|%d|4|%s|%s||%s|%s|%s|%s";
+               const char *Recp = ""; 
+               const char *Cc = "";
+               const char *Bcc = "";
+               const char *Wikipage = "";
+               const char *my_email_addr = "";
+               char *CmdBuf = NULL;;
+               long len = 0;
+
+               if (GetHash(WCC->urlstrings, HKEY("subject"), &U)) {
+                       u = (urlcontent*) U;
+                       /** 
+                        * make enough room for the encoded string; 
+                        * plus the QP header 
+                        */
+                       len = u->url_data_size * 3 + 32;
+                       encoded_subject = malloc (len);
+                       len = webcit_rfc2047encode(encoded_subject, len, 
+                                                  u->url_data, u->url_data_size);
+                       if (len < 0) {
+                               free (encoded_subject);
+                               return;
+                       }
+               }
+               len += sizeof (CMD) + dpLen;
+
+               if (GetHash(WCC->urlstrings, HKEY("recp"), &U)) {
+                       u = (urlcontent*) U;
+                       Recp = u->url_data;
+                       len += u->url_data_size;                }
+
+               if (GetHash(WCC->urlstrings, HKEY("cc"), &U)) {
+                       u = (urlcontent*) U;
+                       Cc = u->url_data;
+                       len += u->url_data_size;
+               }
+
+               if (GetHash(WCC->urlstrings, HKEY("bcc"), &U)) {
+                       u = (urlcontent*) U;
+                       Bcc = u->url_data;
+                       len += u->url_data_size;
+               }
+
+               if (GetHash(WCC->urlstrings, HKEY("wikipage"), &U)) {
+                       u = (urlcontent*) U;
+                       Wikipage = u->url_data;
+                       len += u->url_data_size;
+               }
+
+               if (GetHash(WCC->urlstrings, HKEY("my_email_addr"), &U)) {
+                       u = (urlcontent*) U;
+                       my_email_addr = u->url_data;
+                       len += u->url_data_size;
+               }
+
+               CmdBuf = (char*) malloc (len + 1);
+
+
+               snprintf(CmdBuf, len + 1, CMD,
+                        Recp,
+                        is_anonymous,
+                        encoded_subject,
+                        display_name,
+                        Cc,
+                        Bcc,
+                        Wikipage,
+                        my_email_addr);
+               serv_puts(CmdBuf);
                serv_getln(buf, sizeof buf);
+               free (CmdBuf);
+               free (encoded_subject);
                if (buf[0] == '4') {
                        post_mime_to_server();
                        if (  (!IsEmptyStr(bstr("recp")))
                           || (!IsEmptyStr(bstr("cc"  )))
                           || (!IsEmptyStr(bstr("bcc" )))
                        ) {
-                               sprintf(WC->ImportantMessage, _("Message has been sent.\n"));
+                               sprintf(WCC->ImportantMessage, _("Message has been sent.\n"));
                        }
                        else {
                                sprintf(WC->ImportantMessage, _("Message has been posted.\n"));
@@ -3078,7 +3167,7 @@ void post_message(void)
                }
        }
 
-       free_attachments(WC);
+       free_attachments(WCC);
 
        /**
         *  We may have been supplied with instructions regarding the location
index 494555b31f51fcf380e53b10e8f5da47a7197262..2187d8296c2d4f3c3ddd91f8a821995a43397ceb 100644 (file)
@@ -496,39 +496,39 @@ void parse_fields_from_rule_editor(void) {
                strcpy(rule, "");
 
                sprintf(fname, "active%d", i);
-               active = !strcasecmp(bstr(fname), "on") ;
+               active = !strcasecmp(BSTR(fname), "on") ;
 
                if (active) {
 
                        sprintf(fname, "hfield%d", i);
-                       safestrncpy(hfield, bstr(fname), sizeof hfield);
+                       safestrncpy(hfield, BSTR(fname), sizeof hfield);
        
                        sprintf(fname, "compare%d", i);
-                       safestrncpy(compare, bstr(fname), sizeof compare);
+                       safestrncpy(compare, BSTR(fname), sizeof compare);
        
                        sprintf(fname, "htext%d", i);
-                       safestrncpy(htext, bstr(fname), sizeof htext);
+                       safestrncpy(htext, BSTR(fname), sizeof htext);
        
                        sprintf(fname, "sizecomp%d", i);
-                       safestrncpy(sizecomp, bstr(fname), sizeof sizecomp);
+                       safestrncpy(sizecomp, BSTR(fname), sizeof sizecomp);
        
                        sprintf(fname, "sizeval%d", i);
-                       sizeval = atoi(bstr(fname));
+                       sizeval = atoi(BSTR(fname));
        
                        sprintf(fname, "action%d", i);
-                       safestrncpy(action, bstr(fname), sizeof action);
+                       safestrncpy(action, BSTR(fname), sizeof action);
        
                        sprintf(fname, "fileinto%d", i);
-                       safestrncpy(fileinto, bstr(fname), sizeof fileinto);
+                       safestrncpy(fileinto, BSTR(fname), sizeof fileinto);
        
                        sprintf(fname, "redirect%d", i);
-                       safestrncpy(redirect, bstr(fname), sizeof redirect);
+                       safestrncpy(redirect, BSTR(fname), sizeof redirect);
        
                        sprintf(fname, "automsg%d", i);
-                       safestrncpy(automsg, bstr(fname), sizeof automsg);
+                       safestrncpy(automsg, BSTR(fname), sizeof automsg);
        
                        sprintf(fname, "final%d", i);
-                       safestrncpy(final, bstr(fname), sizeof final);
+                       safestrncpy(final, BSTR(fname), sizeof final);
        
                        snprintf(rule, sizeof rule, "%d|%s|%s|%s|%s|%d|%s|%s|%s|%s|%s",
                                active, hfield, compare, htext, sizecomp, sizeval, action, fileinto,
@@ -613,7 +613,7 @@ void save_sieve(void) {
                                serv_getln(buf, sizeof buf);
                                if (buf[0] == '4') {
                                        snprintf(this_name, sizeof this_name, "text_%s", script_names[i]);
-                                       striplt(bstr(this_name));
+                                       striplt((char*)BSTR(this_name)); /* TODO: get rid of typecast*/
                                        serv_printf("%s", bstr(this_name));
                                        serv_puts("000");
                                }
index 22d816ac960ce0b4cbae9484837ecbb7c8825ec4..f578fe98ba529a42ca1fad9b29659ae9bc7e6ceb 100644 (file)
@@ -24,7 +24,7 @@ static char *unset = "; expires=28-May-1971 18:10:00 GMT";
  * \brief remove escaped strings from i.e. the url string (like %20 for blanks)
  * \param buf the buffer to examine
  */
-void unescape_input(char *buf)
+long unescape_input(char *buf)
 {
        int a, b;
        char hex[3];
@@ -64,7 +64,14 @@ void unescape_input(char *buf)
                }
                a++;
        }
+       return a;
+}
 
+void free_url(void *U)
+{
+       urlcontent *u = (urlcontent*) U;
+       free(u->url_data);
+       free(u);
 }
 
 /**
@@ -76,9 +83,12 @@ void addurls(char *url)
        char *aptr, *bptr, *eptr;
        char *up;
        char buf[SIZ];
-       int len, n;
-       struct urlcontent *u;
+       int len, n, keylen;
+       urlcontent *u;
+       struct wcsession *WCC = WC;
 
+       if (WCC->urlstrings == NULL)
+               WCC->urlstrings = NewHash();
        eptr = buf + sizeof (buf);
        up = url;
        /** locate the = sign */
@@ -101,22 +111,25 @@ void addurls(char *url)
                       (*bptr != '&') && (*bptr != ' '))
                        bptr++;
                *bptr = '\0';
-               u = (struct urlcontent *) malloc(sizeof(struct urlcontent));
-               u->next = WC->urlstrings;
-               WC->urlstrings = u;
+               u = (urlcontent *) malloc(sizeof(urlcontent));
 
-               if (safestrncpy(u->url_key, up, sizeof u->url_key) < 0)
+
+               keylen = safestrncpy(u->url_key, up, sizeof u->url_key);
+               if (keylen < 0){
                        lprintf(1, "URLkey to long! [%s]", up);
+                       continue;
+               }
 
+               Put(WCC->urlstrings, u->url_key, keylen, u, free_url);
                len = bptr - aptr;
                u->url_data = malloc(len + 2);
                safestrncpy(u->url_data, aptr, len + 2);
-               u->url_data[len] = 0;
-               unescape_input(u->url_data);
+               u->url_data_size = unescape_input(u->url_data);
+               u->url_data[u->url_data_size] = '\0';
                up = bptr;
                ++up;
 
-               lprintf(9, "%s = %s\n", u->url_key, u->url_data); 
+               lprintf(9, "%s = [%ld]  %s\n", u->url_key, u->url_data_size, u->url_data); 
        }
 }
 
@@ -125,24 +138,25 @@ void addurls(char *url)
  */
 void free_urls(void)
 {
-       struct urlcontent *u;
-
-       while (WC->urlstrings != NULL) {
-               free(WC->urlstrings->url_data);
-               u = WC->urlstrings->next;
-               free(WC->urlstrings);
-               WC->urlstrings = u;
-       }
+       DeleteHash(&WC->urlstrings);
 }
 
 /**
  * \brief Diagnostic function to display the contents of all variables
  */
+
 void dump_vars(void)
 {
-       struct urlcontent *u;
-
-       for (u = WC->urlstrings; u != NULL; u = u->next) {
+       struct wcsession *WCC = WC;
+       urlcontent *u;
+       void *U;
+       long HKLen;
+       char *HKey;
+       HashPos *Cursor;
+       
+       Cursor = GetNewHashPos ();
+       while (GetNextHashPos(WCC->urlstrings, Cursor, &HKLen, &HKey, &U)) {
+               u = (urlcontent*) U;
                wprintf("%38s = %s\n", u->url_key, u->url_data);
        }
 }
@@ -151,15 +165,26 @@ void dump_vars(void)
  * \brief Return the value of a variable supplied to the current web page (from the url or a form)
  * \param key The name of the variable we want
  */
-char *bstr(char *key)
+const char *BSTR(char *key)
 {
-       struct urlcontent *u;
+       void *U;
 
-       for (u = WC->urlstrings; u != NULL; u = u->next) {
-               if (!strcasecmp(u->url_key, key))
-                       return (u->url_data);
-       }
-       return ("");
+       if ((WC->urlstrings != NULL) &&
+           GetHash(WC->urlstrings, key, strlen (key), &U))
+               return ((urlcontent *)U)->url_data;
+       else    
+               return ("");
+}
+
+const char *Bstr(char *key, size_t keylen)
+{
+       void *U;
+
+       if ((WC->urlstrings != NULL) && 
+           GetHash(WC->urlstrings, key, keylen, &U))
+               return ((urlcontent *)U)->url_data;
+       else    
+               return ("");
 }
 
 /**
@@ -988,19 +1013,24 @@ void upload_handler(char *name, char *filename, char *partnum, char *disp,
                        void *content, char *cbtype, char *cbcharset,
                        size_t length, char *encoding, void *userdata)
 {
-       struct urlcontent *u;
+       urlcontent *u;
 
        lprintf(9, "upload_handler() name=%s, type=%s, len=%d\n", name, cbtype, length);
 
+       if (WC->urlstrings == NULL)
+               WC->urlstrings = NewHash();
+
        /* Form fields */
        if ( (length > 0) && (IsEmptyStr(cbtype)) ) {
-               u = (struct urlcontent *) malloc(sizeof(struct urlcontent));
-               u->next = WC->urlstrings;
-               WC->urlstrings = u;
+               u = (urlcontent *) malloc(sizeof(urlcontent));
+               
                safestrncpy(u->url_key, name, sizeof(u->url_key));
                u->url_data = malloc(length + 1);
+               u->url_data_size = length;
                memcpy(u->url_data, content, length);
                u->url_data[length] = 0;
+               Put(WC->urlstrings, u->url_key, strlen(u->url_key), u, free_url);
+
                /* lprintf(9, "Key: <%s>  Data: <%s>\n", u->url_key, u->url_data); */
        }
 
index ce0be5daab2a10a80aafe72937c98f4cda7020f8..c0f37eb0fd5f429e1f12c7a49e75bef9f9c55b0e 100644 (file)
@@ -225,10 +225,12 @@ struct httprequest {
 /**
  * \brief      Linked list of session variables encoded in an x-www-urlencoded content type
  */
+typedef struct urlcontent urlcontent;
 struct urlcontent {
        struct urlcontent *next;   /**< the next variable in the list */ 
        char url_key[32];          /**< the variable name */
        char *url_data;            /**< its value */
+       size_t url_data_size;      /**< how big is it? */
 };
 
 /**
@@ -383,7 +385,7 @@ struct wcsession {
        int num_summ;                           /**< number of messages in mailbox summary view */
        struct message_summary *summ;           /**< array of messages for mailbox summary view */
        int is_wap;                             /**< Client is a WAP gateway */
-       struct urlcontent *urlstrings;          /**< variables passed to webcit in a URL */
+       HashList *urlstrings;                   /**< variables passed to webcit in a URL */
        struct wcsubst *vars;                   /**< HTTP variable substitutions for this page */
        char this_page[512];                    /**< URL of current page */
        char http_host[512];                    /**< HTTP Host: header */
@@ -501,7 +503,10 @@ void fmout(char *align);
 void pullquote_fmout(void);
 void wDumpContent(int);
 void serv_printf(const char *format,...);
-char *bstr(char *key);
+const char *Bstr(char *key, size_t keylen);
+/* TODO: get rid of the non-const-typecast */
+#define bstr(a) (char*) Bstr(a, sizeof(a) - 1)
+const char *BSTR(char *key);
 void urlescputs(char *);
 void jsesc(char *, size_t, char *);
 void jsescputs(char *);
@@ -731,7 +736,7 @@ long locate_user_vcard(char *username, long usernum);
 void sleeeeeeeeeep(int);
 void http_transmit_thing(char *thing, size_t length, const char *content_type,
                         int is_static);
-void unescape_input(char *buf);
+long unescape_input(char *buf);
 void do_iconbar(void);
 void do_iconbar_roomlist(void);
 void do_selected_iconbar(void);