From 6f7c6de0c990630575ce8721ee72b306b29feeb0 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Thu, 11 Oct 2012 20:02:52 +0100 Subject: Use nsurl_replace_query instead of url_get_components and url_reform_components. --- render/form.c | 65 +++++++++++++++++++++++++++++++++++------------------------ render/form.h | 2 +- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/render/form.c b/render/form.c index 776ebdc7a..f62e6f6ff 100644 --- a/render/form.c +++ b/render/form.c @@ -674,26 +674,41 @@ char *form_textarea_value(struct form_control *textarea) * * \param form form to which successful controls relate * \param control linked list of fetch_multipart_data + * \param query_string iff true add '?' to the start of returned data * \return URL-encoded form, or 0 on memory exhaustion */ char *form_url_encode(struct form *form, - struct fetch_multipart_data *control) + struct fetch_multipart_data *control, + bool query_string) { char *name, *value; - char *s = malloc(1), *s2; - unsigned int len = 0, len1; + char *s, *s2; + unsigned int len, len1; url_func_result url_err; - if (!s) - return 0; - s[0] = 0; + if (query_string) + s = malloc(2); + else + s = malloc(1); + + if (s == NULL) + return NULL; + + if (query_string) { + s[0] = '?'; + s[1] = '\0'; + len = 1; + } else { + s[0] = '\0'; + len = 0; + } for (; control; control = control->next) { url_err = url_escape(control->name, 0, true, NULL, &name); if (url_err == URL_FUNC_NOMEM) { free(s); - return 0; + return NULL; } assert(url_err == URL_FUNC_OK); @@ -702,7 +717,7 @@ char *form_url_encode(struct form *form, if (url_err == URL_FUNC_NOMEM) { free(name); free(s); - return 0; + return NULL; } assert(url_err == URL_FUNC_OK); @@ -713,7 +728,7 @@ char *form_url_encode(struct form *form, free(value); free(name); free(s); - return 0; + return NULL; } s = s2; sprintf(s + len, "%s=%s&", name, value); @@ -723,7 +738,7 @@ char *form_url_encode(struct form *form, } if (len) - s[len - 1] = 0; + s[len - 1] = '\0'; return s; } @@ -1460,10 +1475,10 @@ void form_radio_set(html_content *html, void form_submit(nsurl *page_url, struct browser_window *target, struct form *form, struct form_control *submit_button) { - char *data = NULL, *url = NULL; + char *data = NULL; struct fetch_multipart_data *success; - struct url_components components; - url_func_result res; + nsurl *action; + nsurl *action_query; assert(form != NULL); @@ -1474,7 +1489,7 @@ void form_submit(nsurl *page_url, struct browser_window *target, switch (form->method) { case method_GET: - data = form_url_encode(form, success); + data = form_url_encode(form, success, true); if (data == NULL) { fetch_multipart_data_destroy(success); warn_user("NoMemory", 0); @@ -1482,8 +1497,7 @@ void form_submit(nsurl *page_url, struct browser_window *target, } /* Decompose action */ - res = url_get_components(form->action, &components); - if (res != URL_FUNC_OK) { + if (nsurl_create(form->action, &action) != NSERROR_OK) { free(data); fetch_multipart_data_destroy(success); warn_user("NoMemory", 0); @@ -1491,24 +1505,24 @@ void form_submit(nsurl *page_url, struct browser_window *target, } /* Replace query segment */ - components.query = data; - - /* Construct submit url */ - url = url_reform_components(&components); - if (url == NULL) { + if (nsurl_replace_query(action, data, &action_query) != + NSERROR_OK) { + nsurl_unref(action); free(data); fetch_multipart_data_destroy(success); warn_user("NoMemory", 0); return; } - url_destroy_components(&components); - - browser_window_go(target, url, nsurl_access(page_url), true); + /* Construct submit url */ + browser_window_go(target, nsurl_access(action_query), + nsurl_access(page_url), true); + nsurl_unref(action); + nsurl_unref(action_query); break; case method_POST_URLENC: - data = form_url_encode(form, success); + data = form_url_encode(form, success, false); if (data == NULL) { fetch_multipart_data_destroy(success); warn_user("NoMemory", 0); @@ -1527,5 +1541,4 @@ void form_submit(nsurl *page_url, struct browser_window *target, fetch_multipart_data_destroy(success); free(data); - free(url); } diff --git a/render/form.h b/render/form.h index c769dc960..f7b211ddf 100644 --- a/render/form.h +++ b/render/form.h @@ -152,7 +152,7 @@ bool form_successful_controls(struct form *form, struct form_control *submit_button, struct fetch_multipart_data **successful_controls); char *form_url_encode(struct form *form, - struct fetch_multipart_data *control); + struct fetch_multipart_data *control, bool query_string); bool form_open_select_menu(void *client_data, struct form_control *control, -- cgit v1.2.3 From 0c8b03474e79ae7cbc14842d0a4dd42c42335f16 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Thu, 11 Oct 2012 20:05:36 +0100 Subject: Make form_url_encode static. --- render/form.c | 2 +- render/form.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/render/form.c b/render/form.c index f62e6f6ff..f60a2bad3 100644 --- a/render/form.c +++ b/render/form.c @@ -678,7 +678,7 @@ char *form_textarea_value(struct form_control *textarea) * \return URL-encoded form, or 0 on memory exhaustion */ -char *form_url_encode(struct form *form, +static char *form_url_encode(struct form *form, struct fetch_multipart_data *control, bool query_string) { diff --git a/render/form.h b/render/form.h index f7b211ddf..67372d5d5 100644 --- a/render/form.h +++ b/render/form.h @@ -151,8 +151,6 @@ bool form_add_option(struct form_control *control, char *value, char *text, bool form_successful_controls(struct form *form, struct form_control *submit_button, struct fetch_multipart_data **successful_controls); -char *form_url_encode(struct form *form, - struct fetch_multipart_data *control, bool query_string); bool form_open_select_menu(void *client_data, struct form_control *control, -- cgit v1.2.3 From 672fa0a8e2124399c827f6a0bab0e00a557cd671 Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Thu, 11 Oct 2012 20:12:06 +0100 Subject: Make url_{get|reform|destroy}_components static. --- utils/url.c | 382 ++++++++++++++++++++++++++++++------------------------------ utils/url.h | 5 - 2 files changed, 191 insertions(+), 196 deletions(-) diff --git a/utils/url.c b/utils/url.c index f7a7cd634..447f85c5a 100644 --- a/utils/url.c +++ b/utils/url.c @@ -167,6 +167,197 @@ out_true: return true; } +/** + * Split a URL into separate components + * + * URLs passed to this function are assumed to be valid and no error checking + * or recovery is attempted. + * + * See RFC 3986 for reference. + * + * \param url a valid absolute or relative URL + * \param result pointer to buffer to hold components + * \return URL_FUNC_OK on success + */ + +static url_func_result url_get_components(const char *url, + struct url_components *result) +{ + int storage_length; + char *storage_end; + const char *scheme; + const char *authority; + const char *path; + const char *query; + const char *fragment; + struct url_components_internal *internal; + + assert(url); + + /* clear our return value */ + internal = (struct url_components_internal *)result; + memset(result, 0x00, sizeof(struct url_components)); + + /* get enough storage space for a URL with termination at each node */ + storage_length = strlen(url) + 8; + internal->buffer = malloc(storage_length); + if (!internal->buffer) + return URL_FUNC_NOMEM; + storage_end = internal->buffer; + + /* look for a valid scheme */ + scheme = url; + if (isalpha(*scheme)) { + for (scheme = url + 1; + ((*scheme != ':') && (*scheme != '\0')); + scheme++) { + if (!isalnum(*scheme) && (*scheme != '+') && + (*scheme != '-') && (*scheme != '.')) + break; + } + + if (*scheme == ':') { + memcpy(storage_end, url, scheme - url); + storage_end[scheme - url] = '\0'; + result->scheme = storage_end; + storage_end += scheme - url + 1; + scheme++; + } else { + scheme = url; + } + } + + + /* look for an authority */ + authority = scheme; + if ((authority[0] == '/') && (authority[1] == '/')) { + authority = strpbrk(scheme + 2, "/?#"); + if (!authority) + authority = scheme + strlen(scheme); + memcpy(storage_end, scheme + 2, authority - scheme - 2); + storage_end[authority - scheme - 2] = '\0'; + result->authority = storage_end; + storage_end += authority - scheme - 1; + } + + + /* look for a path */ + path = authority; + if ((*path != '?') && (*path != '#') && (*path != '\0')) { + path = strpbrk(path, "?#"); + if (!path) + path = authority + strlen(authority); + memcpy(storage_end, authority, path - authority); + storage_end[path - authority] = '\0'; + result->path = storage_end; + storage_end += path - authority + 1; + } + + + /* look for a query */ + query = path; + if (*query == '?') { + query = strchr(query, '#'); + if (!query) + query = path + strlen(path); + memcpy(storage_end, path + 1, query - path - 1); + storage_end[query - path - 1] = '\0'; + result->query = storage_end; + storage_end += query - path; + } + + + /* look for a fragment */ + fragment = query; + if (*fragment == '#') { + fragment = query + strlen(query); + + /* make a copy of the result for the caller */ + memcpy(storage_end, query + 1, fragment - query - 1); + storage_end[fragment - query - 1] = '\0'; + result->fragment = storage_end; + storage_end += fragment - query; + } + + assert((result->buffer + storage_length) >= storage_end); + return URL_FUNC_OK; +} + + +/** + * Reform a URL from separate components + * + * See RFC 3986 for reference. + * + * \param components the components to reform into a URL + * \return a new URL allocated on the heap, or NULL on failure + */ + +static char *url_reform_components(const struct url_components *components) +{ + int scheme_len = 0, authority_len = 0, path_len = 0, query_len = 0, + fragment_len = 0; + char *result, *url; + + /* 5.3 */ + if (components->scheme) + scheme_len = strlen(components->scheme) + 1; + if (components->authority) + authority_len = strlen(components->authority) + 2; + if (components->path) + path_len = strlen(components->path); + if (components->query) + query_len = strlen(components->query) + 1; + if (components->fragment) + fragment_len = strlen(components->fragment) + 1; + + /* claim memory */ + url = result = malloc(scheme_len + authority_len + path_len + + query_len + fragment_len + 1); + if (!url) { + LOG(("malloc failed")); + return NULL; + } + + /* rebuild URL */ + if (components->scheme) { + sprintf(url, "%s:", components->scheme); + url += scheme_len; + } + if (components->authority) { + sprintf(url, "//%s", components->authority); + url += authority_len; + } + if (components->path) { + sprintf(url, "%s", components->path); + url += path_len; + } + if (components->query) { + sprintf(url, "?%s", components->query); + url += query_len; + } + if (components->fragment) + sprintf(url, "#%s", components->fragment); + return result; +} + + +/** + * Release some url components from memory + * + * \param result pointer to buffer containing components + */ +static void url_destroy_components(const struct url_components *components) +{ + const struct url_components_internal *internal; + + assert(components); + + internal = (const struct url_components_internal *)components; + if (internal->buffer) + free(internal->buffer); +} + /** * Resolve a relative URL to absolute form. @@ -685,197 +876,6 @@ url_func_result url_escape(const char *unescaped, size_t toskip, return URL_FUNC_OK; } -/** - * Split a URL into separate components - * - * URLs passed to this function are assumed to be valid and no error checking - * or recovery is attempted. - * - * See RFC 3986 for reference. - * - * \param url a valid absolute or relative URL - * \param result pointer to buffer to hold components - * \return URL_FUNC_OK on success - */ - -url_func_result url_get_components(const char *url, - struct url_components *result) -{ - int storage_length; - char *storage_end; - const char *scheme; - const char *authority; - const char *path; - const char *query; - const char *fragment; - struct url_components_internal *internal; - - assert(url); - - /* clear our return value */ - internal = (struct url_components_internal *)result; - memset(result, 0x00, sizeof(struct url_components)); - - /* get enough storage space for a URL with termination at each node */ - storage_length = strlen(url) + 8; - internal->buffer = malloc(storage_length); - if (!internal->buffer) - return URL_FUNC_NOMEM; - storage_end = internal->buffer; - - /* look for a valid scheme */ - scheme = url; - if (isalpha(*scheme)) { - for (scheme = url + 1; - ((*scheme != ':') && (*scheme != '\0')); - scheme++) { - if (!isalnum(*scheme) && (*scheme != '+') && - (*scheme != '-') && (*scheme != '.')) - break; - } - - if (*scheme == ':') { - memcpy(storage_end, url, scheme - url); - storage_end[scheme - url] = '\0'; - result->scheme = storage_end; - storage_end += scheme - url + 1; - scheme++; - } else { - scheme = url; - } - } - - - /* look for an authority */ - authority = scheme; - if ((authority[0] == '/') && (authority[1] == '/')) { - authority = strpbrk(scheme + 2, "/?#"); - if (!authority) - authority = scheme + strlen(scheme); - memcpy(storage_end, scheme + 2, authority - scheme - 2); - storage_end[authority - scheme - 2] = '\0'; - result->authority = storage_end; - storage_end += authority - scheme - 1; - } - - - /* look for a path */ - path = authority; - if ((*path != '?') && (*path != '#') && (*path != '\0')) { - path = strpbrk(path, "?#"); - if (!path) - path = authority + strlen(authority); - memcpy(storage_end, authority, path - authority); - storage_end[path - authority] = '\0'; - result->path = storage_end; - storage_end += path - authority + 1; - } - - - /* look for a query */ - query = path; - if (*query == '?') { - query = strchr(query, '#'); - if (!query) - query = path + strlen(path); - memcpy(storage_end, path + 1, query - path - 1); - storage_end[query - path - 1] = '\0'; - result->query = storage_end; - storage_end += query - path; - } - - - /* look for a fragment */ - fragment = query; - if (*fragment == '#') { - fragment = query + strlen(query); - - /* make a copy of the result for the caller */ - memcpy(storage_end, query + 1, fragment - query - 1); - storage_end[fragment - query - 1] = '\0'; - result->fragment = storage_end; - storage_end += fragment - query; - } - - assert((result->buffer + storage_length) >= storage_end); - return URL_FUNC_OK; -} - - -/** - * Reform a URL from separate components - * - * See RFC 3986 for reference. - * - * \param components the components to reform into a URL - * \return a new URL allocated on the heap, or NULL on failure - */ - -char *url_reform_components(const struct url_components *components) -{ - int scheme_len = 0, authority_len = 0, path_len = 0, query_len = 0, - fragment_len = 0; - char *result, *url; - - /* 5.3 */ - if (components->scheme) - scheme_len = strlen(components->scheme) + 1; - if (components->authority) - authority_len = strlen(components->authority) + 2; - if (components->path) - path_len = strlen(components->path); - if (components->query) - query_len = strlen(components->query) + 1; - if (components->fragment) - fragment_len = strlen(components->fragment) + 1; - - /* claim memory */ - url = result = malloc(scheme_len + authority_len + path_len + - query_len + fragment_len + 1); - if (!url) { - LOG(("malloc failed")); - return NULL; - } - - /* rebuild URL */ - if (components->scheme) { - sprintf(url, "%s:", components->scheme); - url += scheme_len; - } - if (components->authority) { - sprintf(url, "//%s", components->authority); - url += authority_len; - } - if (components->path) { - sprintf(url, "%s", components->path); - url += path_len; - } - if (components->query) { - sprintf(url, "?%s", components->query); - url += query_len; - } - if (components->fragment) - sprintf(url, "#%s", components->fragment); - return result; -} - - -/** - * Release some url components from memory - * - * \param result pointer to buffer containing components - */ -void url_destroy_components(const struct url_components *components) -{ - const struct url_components_internal *internal; - - assert(components); - - internal = (const struct url_components_internal *)components; - if (internal->buffer) - free(internal->buffer); -} - #ifdef TEST diff --git a/utils/url.h b/utils/url.h index fa27a4874..7c716d723 100644 --- a/utils/url.h +++ b/utils/url.h @@ -58,11 +58,6 @@ url_func_result url_escape(const char *unescaped, size_t toskip, url_func_result url_unescape(const char *str, char **result); url_func_result url_path(const char *url, char **result); -url_func_result url_get_components(const char *url, - struct url_components *result); -char *url_reform_components(const struct url_components *components); -void url_destroy_components(const struct url_components *components); - char *path_to_url(const char *path); char *url_to_path(const char *url); -- cgit v1.2.3