diff options
-rw-r--r-- | desktop/browser.c | 28 | ||||
-rw-r--r-- | desktop/imagemap.c | 298 | ||||
-rw-r--r-- | desktop/imagemap.h | 2 | ||||
-rw-r--r-- | desktop/loginlist.c | 291 |
4 files changed, 389 insertions, 230 deletions
diff --git a/desktop/browser.c b/desktop/browser.c index b61dfafb4..1f87fc7dc 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -1543,6 +1543,7 @@ void browser_window_input_callback(struct browser_window *bw, char key_to_insert; char *utf8key; size_t utf8keySize; + char *value; /** \todo: text_box has data in UTF-8 and its length in * bytes is not necessarily equal to number of characters. @@ -1557,7 +1558,15 @@ void browser_window_input_callback(struct browser_window *bw, if ((utf8key = cnv_local_enc_str(&key_to_insert, 1)) == NULL) return; utf8keySize = strlen(utf8key); - input->gadget->value = xrealloc(input->gadget->value, input->gadget->length + utf8keySize + 1); + + value = realloc(input->gadget->value, input->gadget->length + utf8keySize + 1); + if (!value) { + free(utf8key); + warn_user("NoMemory", 0); + return; + } + input->gadget->value = value; + memmove(input->gadget->value + form_offset + utf8keySize, input->gadget->value + form_offset, input->gadget->length - form_offset); @@ -1573,7 +1582,15 @@ void browser_window_input_callback(struct browser_window *bw, if ((utf8key = cnv_local_enc_str(&key_to_insert, 1)) == NULL) return; utf8keySize = strlen(utf8key); - text_box->text = xrealloc(text_box->text, text_box->length + utf8keySize + 1); + + value = realloc(text_box->text, text_box->length + utf8keySize + 1); + if (!value) { + free(utf8key); + warn_user("NoMemory", 0); + return; + } + text_box->text = value; + memmove(text_box->text + box_offset + utf8keySize, text_box->text + box_offset, text_box->length - box_offset); @@ -1910,7 +1927,12 @@ void browser_form_submit(struct browser_window *bw, struct form *form, warn_user("NoMemory", 0); return; } - url = xcalloc(1, strlen(form->action) + strlen(data) + 2); + url = calloc(1, strlen(form->action) + strlen(data) + 2); + if (!url) { + form_free_successful(success); + warn_user("NoMemory", 0); + return; + } if(form->action[strlen(form->action)-1] == '?') { sprintf(url, "%s%s", form->action, data); } diff --git a/desktop/imagemap.c b/desktop/imagemap.c index db79cb960..17eff7461 100644 --- a/desktop/imagemap.c +++ b/desktop/imagemap.c @@ -49,15 +49,17 @@ struct imagemap { struct imagemap *next; /**< next entry in this hash chain */ }; -static void imagemap_add(struct content *c, const char *key, - struct mapentry *list); -static void imagemap_create(struct content *c); -static struct mapentry *imagemap_extract_map(xmlNode *node, struct content *c, - struct mapentry *entry); -static struct mapentry *imagemap_addtolist(xmlNode *n, struct mapentry *entry); +static bool imagemap_add(struct content *c, const char *key, + struct mapentry *list); +static bool imagemap_create(struct content *c); +static bool imagemap_extract_map(xmlNode *node, struct content *c, + struct mapentry **entry); +static bool imagemap_addtolist(xmlNode *n, struct mapentry **entry); static void imagemap_freelist(struct mapentry *list); static unsigned int imagemap_hash(const char *key); -static int imagemap_point_in_poly(int num, float *xpt, float *ypt, unsigned long x, unsigned long y, unsigned long click_x, unsigned long click_y); +static int imagemap_point_in_poly(int num, float *xpt, float *ypt, + unsigned long x, unsigned long y, unsigned long click_x, + unsigned long click_y); /** * Add an imagemap to the hashtable, creating it if it doesn't exist @@ -65,37 +67,58 @@ static int imagemap_point_in_poly(int num, float *xpt, float *ypt, unsigned long * @param c The containing content * @param key The name of the imagemap * @param list List of map regions + * \return true on succes, false otherwise */ -void imagemap_add(struct content *c, const char *key, struct mapentry *list) { +bool imagemap_add(struct content *c, const char *key, struct mapentry *list) +{ struct imagemap *map; unsigned int slot; + assert(c != NULL); assert(c->type == CONTENT_HTML); + assert(key != NULL); + assert(list != NULL); imagemap_create(c); - map = xcalloc(1, sizeof(*map)); - map->key = xstrdup(key); + map = calloc(1, sizeof(*map)); + if (!map) { + return false; + } + map->key = strdup(key); + if (!map->key) { + free(map); + return false; + } map->list = list; slot = imagemap_hash(key); map->next = c->data.html.imagemaps[slot]; c->data.html.imagemaps[slot] = map; + + return true; } /** * Create hashtable of imagemaps * * @param c The containing content + * \return true on success, false otherwise */ -void imagemap_create(struct content *c) { - +bool imagemap_create(struct content *c) +{ + assert(c != NULL); assert(c->type == CONTENT_HTML); if (c->data.html.imagemaps == 0) { - c->data.html.imagemaps = xcalloc(HASH_SIZE, + c->data.html.imagemaps = calloc(HASH_SIZE, sizeof(struct imagemap)); + if (!c->data.html.imagemaps) { + return false; + } } + + return true; } /** @@ -103,8 +126,8 @@ void imagemap_create(struct content *c) { * * @param c The containing content */ -void imagemap_destroy(struct content *c) { - +void imagemap_destroy(struct content *c) +{ unsigned int i; assert(c->type == CONTENT_HTML); @@ -116,15 +139,15 @@ void imagemap_destroy(struct content *c) { struct imagemap *map, *next; map = c->data.html.imagemaps[i]; while (map != 0) { - next = map->next; - imagemap_freelist(map->list); - xfree(map->key); - xfree(map); - map = next; + next = map->next; + imagemap_freelist(map->list); + free(map->key); + free(map); + map = next; } } - xfree(c->data.html.imagemaps); + free(c->data.html.imagemaps); } /** @@ -132,8 +155,8 @@ void imagemap_destroy(struct content *c) { * * @param c The containing content */ -void imagemap_dump(struct content *c) { - +void imagemap_dump(struct content *c) +{ unsigned int i; int j; @@ -147,42 +170,40 @@ void imagemap_dump(struct content *c) { struct mapentry *entry; map = c->data.html.imagemaps[i]; while (map != 0) { - LOG(("Imagemap: %s", map->key)); - for (entry = map->list; entry; entry = entry->next) { - switch (entry->type) { - case IMAGEMAP_DEFAULT: - LOG(("\tDefault: %s", entry->url)); - break; - case IMAGEMAP_RECT: - LOG(("\tRectangle: %s: [(%d,%d),(%d,%d)]", - entry->url, - entry->bounds.rect.x0, - entry->bounds.rect.y0, - entry->bounds.rect.x1, - entry->bounds.rect.y1)); - break; - case IMAGEMAP_CIRCLE: - LOG(("\tCircle: %s: [(%d,%d),%d]", - entry->url, - entry->bounds.circle.x, - entry->bounds.circle.y, - entry->bounds.circle.r)); - break; - case IMAGEMAP_POLY: - LOG(("\tPolygon: %s:", - entry->url)); - for (j=0; - j!=entry->bounds.poly.num; - j++) { - fprintf(stderr, "(%d,%d) ", - (int)entry->bounds.poly.xcoords[j], - (int)entry->bounds.poly.ycoords[j]); - } - fprintf(stderr,"\n"); - break; - } - } - map = map->next; + LOG(("Imagemap: %s", map->key)); + for (entry = map->list; entry; entry = entry->next) { + switch (entry->type) { + case IMAGEMAP_DEFAULT: + LOG(("\tDefault: %s", entry->url)); + break; + case IMAGEMAP_RECT: + LOG(("\tRectangle: %s: [(%d,%d),(%d,%d)]", + entry->url, + entry->bounds.rect.x0, + entry->bounds.rect.y0, + entry->bounds.rect.x1, + entry->bounds.rect.y1)); + break; + case IMAGEMAP_CIRCLE: + LOG(("\tCircle: %s: [(%d,%d),%d]", + entry->url, + entry->bounds.circle.x, + entry->bounds.circle.y, + entry->bounds.circle.r)); + break; + case IMAGEMAP_POLY: + LOG(("\tPolygon: %s:", entry->url)); + for (j=0; j!=entry->bounds.poly.num; + j++) { + fprintf(stderr, "(%d,%d) ", + (int)entry->bounds.poly.xcoords[j], + (int)entry->bounds.poly.ycoords[j]); + } + fprintf(stderr,"\n"); + break; + } + } + map = map->next; } } } @@ -192,9 +213,10 @@ void imagemap_dump(struct content *c) { * * @param node Root node of tree * @param c The containing content + * \return false on memory exhaustion, true otherwise */ -void imagemap_extract(xmlNode *node, struct content *c) { - +bool imagemap_extract(xmlNode *node, struct content *c) +{ xmlNode *this_node; struct mapentry *entry = 0; char *name; @@ -202,22 +224,41 @@ void imagemap_extract(xmlNode *node, struct content *c) { if (node->type == XML_ELEMENT_NODE) { if (strcmp(node->name, "map") == 0) { if ((name = (char*)xmlGetProp(node, (const xmlChar*)"name")) == NULL) - return; - entry = imagemap_extract_map(node, c, entry); - imagemap_add(c, name, entry); + return true; + if (!imagemap_extract_map(node, c, &entry)) { + xmlFree(name); + return false; + } + if (!imagemap_add(c, name, entry)) { + xmlFree(name); + return false; + } xmlFree(name); - return; + return true; } } - else return; + else return true; /* now recurse */ for (this_node = node->children; this_node != 0; this_node = this_node->next) { - imagemap_extract(this_node, c); + if (!imagemap_extract(this_node, c)) + return false; } + + return true; } -struct mapentry *imagemap_extract_map(xmlNode *node, struct content *c, struct mapentry *entry) { +/** + * Extract an imagemap from html source + * + * \param node XML node containing map + * \param c Content containing document + * \param entry List of map entries + * \return false on memory exhaustion, true otherwise + */ +bool imagemap_extract_map(xmlNode *node, struct content *c, + struct mapentry **entry) +{ xmlNode *this_node; @@ -227,34 +268,44 @@ struct mapentry *imagemap_extract_map(xmlNode *node, struct content *c, struct m */ if (strcmp(node->name, "area") == 0 || strcmp(node->name, "a") == 0) { - entry = imagemap_addtolist(node, entry); - return entry; + return imagemap_addtolist(node, entry); } } - else return entry; + else return true; for (this_node = node->children; this_node != 0; this_node = this_node->next) { - entry = imagemap_extract_map(this_node, c, entry); + if (!imagemap_extract_map(this_node, c, entry)) + return false; } - return entry; + return true; } -struct mapentry *imagemap_addtolist(xmlNode *n, struct mapentry *entry) { - +/** + * Adds an imagemap entry to the list + * + * \param n The xmlNode representing the entry to add + * \param entry Pointer to list of entries + * \return false on memory exhaustion, true otherwise + */ +bool imagemap_addtolist(xmlNode *n, struct mapentry **entry) +{ char *shape, *coords = 0, *href, *val; int num; struct mapentry *new_map, *temp; + assert(n != NULL); + assert(entry != NULL); + if (strcmp(n->name, "area") == 0) { /* nohref attribute present - ignore this entry */ if (xmlGetProp(n, (const xmlChar*)"nohref") != 0) { - return entry; + return true; } } /* no href -> ignore */ if ((href = (char*)xmlGetProp(n, (const xmlChar*)"href")) == NULL) { - return entry; + return true; } /* no shape -> shape is a rectangle */ if ((shape = (char*)xmlGetProp(n, (const xmlChar*)"shape")) == NULL) { @@ -265,11 +316,14 @@ struct mapentry *imagemap_addtolist(xmlNode *n, struct mapentry *entry) { if ((coords = (char*)xmlGetProp(n, (const xmlChar*)"coords")) == NULL) { xmlFree(href); xmlFree(shape); - return entry; + return true; } } - new_map = xcalloc(1, sizeof(*new_map)); + new_map = calloc(1, sizeof(*new_map)); + if (!new_map) { + return false; + } /* extract area shape */ if (strcasecmp(shape, "rect") == 0) { @@ -287,14 +341,21 @@ struct mapentry *imagemap_addtolist(xmlNode *n, struct mapentry *entry) { new_map->type = IMAGEMAP_DEFAULT; } else { /* unknown shape -> bail */ - xfree(new_map); + free(new_map); xmlFree(href); xmlFree(shape); xmlFree(coords); - return entry; + return true; } - new_map->url = xstrdup(href); + new_map->url = strdup(href); + if (!new_map->url) { + free(new_map); + xmlFree(href); + xmlFree(shape); + xmlFree(coords); + return false; + } if (new_map->type != IMAGEMAP_DEFAULT) { @@ -331,7 +392,8 @@ struct mapentry *imagemap_addtolist(xmlNode *n, struct mapentry *entry) { case 1: new_map->bounds.circle.x = atoi(val); break; - case 2: new_map->bounds.circle.y = atoi(val); + case 2: + new_map->bounds.circle.y = atoi(val); break; case 3: new_map->bounds.circle.r = atoi(val); @@ -343,22 +405,64 @@ struct mapentry *imagemap_addtolist(xmlNode *n, struct mapentry *entry) { break; case IMAGEMAP_POLY: new_map->bounds.poly.xcoords = - xcalloc(0, sizeof(*new_map->bounds.poly.xcoords)); + calloc(0, sizeof(*new_map->bounds.poly.xcoords)); + if (!new_map->bounds.poly.xcoords) { + free(new_map->url); + free(new_map); + xmlFree(href); + xmlFree(shape); + xmlFree(coords); + return false; + } new_map->bounds.poly.ycoords = - xcalloc(0, sizeof(*new_map->bounds.poly.ycoords)); + calloc(0, sizeof(*new_map->bounds.poly.ycoords)); + if (!new_map->bounds.poly.ycoords) { + free(new_map->bounds.poly.xcoords); + free(new_map->url); + free(new_map); + xmlFree(href); + xmlFree(shape); + xmlFree(coords); + return false; + } int x, y; + float *xcoords, *ycoords; while (val) { x = atoi(val); val = strtok('\0', ","); if (!val) break; y = atoi(val); - new_map->bounds.poly.xcoords = - xrealloc(new_map->bounds.poly.xcoords, + xcoords = + realloc(new_map->bounds.poly.xcoords, num*sizeof(*new_map->bounds.poly.xcoords)); - new_map->bounds.poly.ycoords = - xrealloc(new_map->bounds.poly.ycoords, + if (!xcoords) { + free(new_map->bounds.poly.ycoords); + free(new_map->bounds.poly.xcoords); + free(new_map->url); + free(new_map); + xmlFree(href); + xmlFree(shape); + xmlFree(coords); + return false; + } + ycoords = + realloc(new_map->bounds.poly.ycoords, num*sizeof(*new_map->bounds.poly.ycoords)); + if (!ycoords) { + free(new_map->bounds.poly.ycoords); + free(new_map->bounds.poly.xcoords); + free(new_map->url); + free(new_map); + xmlFree(href); + xmlFree(shape); + xmlFree(coords); + return false; + } + + new_map->bounds.poly.xcoords = xcoords; + new_map->bounds.poly.ycoords = ycoords; + new_map->bounds.poly.xcoords[num-1] = x; new_map->bounds.poly.ycoords[num-1] = y; @@ -375,21 +479,21 @@ struct mapentry *imagemap_addtolist(xmlNode *n, struct mapentry *entry) { } new_map->next = 0; - if (entry) { + if (entry && (*entry)) { /* add to END of list */ - for (temp = entry; temp->next != 0; temp = temp->next) + for (temp = (*entry); temp->next != 0; temp = temp->next) ; temp->next = new_map; } else { - entry = new_map; + (*entry) = new_map; } xmlFree(href); xmlFree(shape); xmlFree(coords); - return entry; + return true; } /** @@ -405,13 +509,13 @@ void imagemap_freelist(struct mapentry *list) { while (entry != 0) { prev = entry; - xfree(entry->url); + free(entry->url); if (entry->type == IMAGEMAP_POLY) { - xfree(entry->bounds.poly.xcoords); - xfree(entry->bounds.poly.ycoords); + free(entry->bounds.poly.xcoords); + free(entry->bounds.poly.ycoords); } entry = entry->next; - xfree(prev); + free(prev); } } diff --git a/desktop/imagemap.h b/desktop/imagemap.h index c233f92c5..8c636ed67 100644 --- a/desktop/imagemap.h +++ b/desktop/imagemap.h @@ -14,7 +14,7 @@ struct content; void imagemap_destroy(struct content *c); void imagemap_dump(struct content *c); -void imagemap_extract(xmlNode *node, struct content *c); +bool imagemap_extract(xmlNode *node, struct content *c); char *imagemap_get(struct content *c, const char *key, unsigned long x, unsigned long y, unsigned long click_x, unsigned long click_y); diff --git a/desktop/loginlist.c b/desktop/loginlist.c index 3161bbd11..3702953c6 100644 --- a/desktop/loginlist.c +++ b/desktop/loginlist.c @@ -28,154 +28,187 @@ static struct login *loginlist = &login; /** * Adds an item to the list of login details */ -void login_list_add(char *host, char* logindets) { - - struct login *nli = xcalloc(1, sizeof(*nli)); - char *temp; - char *i; - url_func_result res; - - res = url_host(host, &temp); - - assert(res == URL_FUNC_OK); - - /* Go back to the path base ie strip the document name - * eg. http://www.blah.com/blah/test.htm becomes - * http://www.blah.com/blah/ - * This does, however, mean that directories MUST have a '/' at the end - */ - if (strlen(temp) < strlen(host)) { - - xfree(temp); - temp = xstrdup(host); - if (temp[strlen(temp)-1] != '/') { - i = strrchr(temp, '/'); - temp[(i-temp)+1] = 0; - } - } - - nli->host = xstrdup(temp); - nli->logindetails = xstrdup(logindets); - nli->prev = loginlist->prev; - nli->next = loginlist; - loginlist->prev->next = nli; - loginlist->prev = nli; - - LOG(("Adding %s", temp)); -#ifndef NDEBUG - login_list_dump(); -#endif - xfree(temp); +void login_list_add(char *host, char* logindets) +{ + struct login *nli; + char *temp; + char *i; + url_func_result res; + + nli = calloc(1, sizeof(*nli)); + if (!nli) { + warn_user("NoMemory", 0); + return; + } + + res = url_host(host, &temp); + + if (res != URL_FUNC_OK) { + free(temp); + free(nli); + warn_user("NoMemory", 0); + return; + } + + /* Go back to the path base ie strip the document name + * eg. http://www.blah.com/blah/test.htm becomes + * http://www.blah.com/blah/ + * This does, however, mean that directories MUST have a '/' at the end + */ + if (strlen(temp) < strlen(host)) { + free(temp); + temp = strdup(host); + if (!temp) { + free(nli); + warn_user("NoMemory", 0); + return; + } + if (temp[strlen(temp)-1] != '/') { + i = strrchr(temp, '/'); + temp[(i-temp)+1] = 0; + } + } + + nli->host = strdup(temp); + if (!nli->host) { + free(temp); + free(nli); + warn_user("NoMemory", 0); + return; + } + nli->logindetails = strdup(logindets); + if (!nli->logindetails) { + free(nli->host); + free(temp); + free(nli); + warn_user("NoMemory", 0); + return; + } + nli->prev = loginlist->prev; + nli->next = loginlist; + loginlist->prev->next = nli; + loginlist->prev = nli; + + LOG(("Adding %s", temp)); + #ifndef NDEBUG + login_list_dump(); + #endif + free(temp); } /** * Retrieves an element from the login list */ /** \todo Make the matching spec compliant (see RFC 2617) */ -struct login *login_list_get(char *url) { - - struct login *nli; - char *temp, *host; - char *i; - int reached_scheme = 0; - url_func_result res; - - if (url == NULL) - return NULL; - - if ((strncasecmp(url, "http://", 7) != 0) && - (strncasecmp(url, "https://", 8) != 0)) - return NULL; - - res = url_host(url, &host); - if (res != URL_FUNC_OK || strlen(host) == 0) return NULL; - - temp = xstrdup(url); - - /* Smallest thing to check for is the scheme + host name + trailing '/' - * So make sure we've got that at least - */ - if (strlen(host) > strlen(temp)) { - xfree(temp); - res = url_host(url, &temp); - if (res != URL_FUNC_OK || strlen(temp) == 0) { - xfree(host); - return NULL; - } - } - xfree(host); - - /* Work backwards through the path, directory at at time. - * Finds the closest match. - * eg. http://www.blah.com/moo/ matches the url - * http://www.blah.com/moo/test/index.htm - * This allows multiple realms (and login details) per host. - * Only one set of login details per realm are allowed. - */ - do { - - LOG(("%s, %d", temp, strlen(temp))); - - for (nli = loginlist->next; nli != loginlist && - (strcasecmp(nli->host, temp)!=0); - nli = nli->next) ; - - if (nli != loginlist) { - LOG(("Got %s", nli->host)); - xfree(temp); - return nli; - } - else { - - if (temp[strlen(temp)-1] == '/') { - temp[strlen(temp)-1] = 0; - } - - i = strrchr(temp, '/'); - - if (temp[(i-temp)-1] != '/') /* reached the scheme? */ - temp[(i-temp)+1] = 0; - else { - reached_scheme = 1; - } - } - } while (reached_scheme == 0); - - xfree(temp); - return NULL; +struct login *login_list_get(char *url) +{ + struct login *nli; + char *temp, *host; + char *i; + int reached_scheme = 0; + url_func_result res; + + if (url == NULL) + return NULL; + + if ((strncasecmp(url, "http://", 7) != 0) && + (strncasecmp(url, "https://", 8) != 0)) + return NULL; + + res = url_host(url, &host); + if (res != URL_FUNC_OK || strlen(host) == 0) return NULL; + + temp = strdup(url); + if (!temp) { + warn_user("NoMemory", 0); + free(host); + return NULL; + } + + /* Smallest thing to check for is the scheme + host name + + * trailing '/' + * So make sure we've got that at least + */ + if (strlen(host) > strlen(temp)) { + free(temp); + res = url_host(url, &temp); + if (res != URL_FUNC_OK || strlen(temp) == 0) { + free(host); + return NULL; + } + } + free(host); + + /* Work backwards through the path, directory at at time. + * Finds the closest match. + * eg. http://www.blah.com/moo/ matches the url + * http://www.blah.com/moo/test/index.htm + * This allows multiple realms (and login details) per host. + * Only one set of login details per realm are allowed. + */ + do { + LOG(("%s, %d", temp, strlen(temp))); + + for (nli = loginlist->next; nli != loginlist && + (strcasecmp(nli->host, temp)!=0); + nli = nli->next) + /* do nothing */; + + if (nli != loginlist) { + LOG(("Got %s", nli->host)); + free(temp); + return nli; + } + else { + if (temp[strlen(temp)-1] == '/') { + temp[strlen(temp)-1] = 0; + } + + i = strrchr(temp, '/'); + + if (temp[(i-temp)-1] != '/') /* reached the scheme? */ + temp[(i-temp)+1] = 0; + else { + reached_scheme = 1; + } + } + } while (reached_scheme == 0); + + free(temp); + return NULL; } /** * Remove a realm's login details from the list */ -void login_list_remove(char *host) { - - struct login *nli = login_list_get(host); - - if (nli != NULL) { - nli->prev->next = nli->next; - nli->next->prev = nli->prev; - xfree(nli->logindetails); - xfree(nli->host); - xfree(nli); - } - - LOG(("Removing %s", host)); +void login_list_remove(char *host) +{ + struct login *nli = login_list_get(host); + + if (nli != NULL) { + nli->prev->next = nli->next; + nli->next->prev = nli->prev; + free(nli->logindetails); + free(nli->host); + free(nli); + } + + LOG(("Removing %s", host)); #ifndef NDEBUG - login_list_dump(); + login_list_dump(); #endif } /** * Dumps the list of login details (base paths only) */ -void login_list_dump(void) { - - struct login *nli; +void login_list_dump(void) +{ + struct login *nli; - for (nli = loginlist->next; nli != loginlist; nli = nli->next) { - LOG(("%s", nli->host)); - } + for (nli = loginlist->next; nli != loginlist; nli = nli->next) { + LOG(("%s", nli->host)); + } } #endif |