From: Simon McVittie Date: Fri, 3 Feb 2012 14:13:32 +0000 (+0000) Subject: SoupURI: add SOUP_URI_IS_VALID() and use it for basic precondition checks X-Git-Tag: LIBSOUP_2_37_5~2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=675979d4aa6a72d8415294f989aeb20a6eae2ab6;p=platform%2Fupstream%2Flibsoup.git SoupURI: add SOUP_URI_IS_VALID() and use it for basic precondition checks In this patch, field setters don't have precondition checks for the validity of the URI object itself, only a non-NULL check, to avoid breaking existing code if it calls soup_uri_new (NULL) and then sets fields in an unexpected order: uri = soup_uri_new (NULL); /* uri is invalid */ soup_uri_set_host (uri, "www.google.com"); soup_uri_set_query (uri, "q=badgers"); soup_uri_set_scheme (uri, "http"); /* still invalid... */ soup_uri_set_path (uri, "/search"); /* finally valid */ Also annotate nullable setter parameters as (allow-none), to justify why they don't have a precondition check. Signed-off-by: Simon McVittie Bug: https://bugzilla.gnome.org/show_bug.cgi?id=667637 Bug-NB: NB#294977 --- diff --git a/libsoup/soup-uri.c b/libsoup/soup-uri.c index f53decd..0e4c31c 100644 --- a/libsoup/soup-uri.c +++ b/libsoup/soup-uri.c @@ -81,6 +81,21 @@ **/ /** + * SOUP_URI_IS_VALID: + * @uri: a #SoupURI + * + * Tests whether @uri is a valid #SoupURI; that is, that it is non-%NULL + * and its @scheme and @path members are also non-%NULL. + * + * This macro does not check whether http and https URIs have a non-%NULL + * @host member. + * + * Return value: %TRUE if @uri is valid for use. + * + * Since: 2.38 + **/ + +/** * SOUP_URI_VALID_FOR_HTTP: * @uri: a #SoupURI * @@ -148,6 +163,9 @@ soup_uri_new_with_base (SoupURI *base, const char *uri_string) gboolean remove_dot_segments = TRUE; int len; + g_return_val_if_fail (base == NULL || SOUP_URI_IS_VALID (base), NULL); + g_return_val_if_fail (uri_string != NULL, NULL); + /* First some cleanup steps (which are supposed to all be no-ops, * but...). Skip initial whitespace, strip out internal tabs and * line breaks, and ignore trailing whitespace. @@ -428,7 +446,7 @@ soup_uri_to_string (SoupURI *uri, gboolean just_path_and_query) GString *str; char *return_result; - g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL); /* IF YOU CHANGE ANYTHING IN THIS FUNCTION, RUN * tests/uri-parsing AFTERWARD. @@ -487,7 +505,7 @@ soup_uri_copy (SoupURI *uri) { SoupURI *dup; - g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL); dup = g_slice_new0 (SoupURI); dup->scheme = uri->scheme; @@ -524,6 +542,9 @@ parts_equal (const char *one, const char *two, gboolean insensitive) gboolean soup_uri_equal (SoupURI *uri1, SoupURI *uri2) { + g_return_val_if_fail (SOUP_URI_IS_VALID (uri1), FALSE); + g_return_val_if_fail (SOUP_URI_IS_VALID (uri2), FALSE); + if (uri1->scheme != uri2->scheme || uri1->port != uri2->port || !parts_equal (uri1->user, uri2->user, FALSE) || @@ -591,6 +612,8 @@ soup_uri_encode (const char *part, const char *escape_extra) GString *str; char *encoded; + g_return_val_if_fail (part != NULL, NULL); + str = g_string_new (NULL); append_uri_encoded (str, part, escape_extra); encoded = str->str; @@ -608,6 +631,8 @@ uri_decoded_copy (const char *part, int length) unsigned char *s, *d; char *decoded = g_strndup (part, length); + g_return_val_if_fail (part != NULL, NULL); + s = d = (unsigned char *)decoded; do { if (*s == '%') { @@ -640,6 +665,8 @@ uri_decoded_copy (const char *part, int length) char * soup_uri_decode (const char *part) { + g_return_val_if_fail (part != NULL, NULL); + return uri_decoded_copy (part, strlen (part)); } @@ -727,6 +754,8 @@ uri_normalized_copy (const char *part, int length, char * soup_uri_normalize (const char *part, const char *unescape_extra) { + g_return_val_if_fail (part != NULL, NULL); + return uri_normalized_copy (part, strlen (part), unescape_extra); } @@ -744,6 +773,9 @@ soup_uri_normalize (const char *part, const char *unescape_extra) gboolean soup_uri_uses_default_port (SoupURI *uri) { + g_return_val_if_fail (uri != NULL, FALSE); + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), FALSE); + return uri->port == soup_scheme_default_port (uri->scheme); } @@ -774,6 +806,8 @@ soup_uri_uses_default_port (SoupURI *uri) const char * soup_uri_get_scheme (SoupURI *uri) { + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL); + return uri->scheme; } @@ -788,6 +822,9 @@ soup_uri_get_scheme (SoupURI *uri) void soup_uri_set_scheme (SoupURI *uri, const char *scheme) { + g_return_if_fail (uri != NULL); + g_return_if_fail (scheme != NULL); + uri->scheme = soup_uri_parse_scheme (scheme, strlen (scheme)); uri->port = soup_scheme_default_port (uri->scheme); } @@ -805,19 +842,23 @@ soup_uri_set_scheme (SoupURI *uri, const char *scheme) const char * soup_uri_get_user (SoupURI *uri) { + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL); + return uri->user; } /** * soup_uri_set_user: * @uri: a #SoupURI - * @user: the username, or %NULL + * @user: (allow-none): the username, or %NULL * * Sets @uri's user to @user. **/ void soup_uri_set_user (SoupURI *uri, const char *user) { + g_return_if_fail (uri != NULL); + g_free (uri->user); uri->user = g_strdup (user); } @@ -835,19 +876,23 @@ soup_uri_set_user (SoupURI *uri, const char *user) const char * soup_uri_get_password (SoupURI *uri) { + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL); + return uri->password; } /** * soup_uri_set_password: * @uri: a #SoupURI - * @password: the password, or %NULL + * @password: (allow-none): the password, or %NULL * * Sets @uri's password to @password. **/ void soup_uri_set_password (SoupURI *uri, const char *password) { + g_return_if_fail (uri != NULL); + g_free (uri->password); uri->password = g_strdup (password); } @@ -865,23 +910,29 @@ soup_uri_set_password (SoupURI *uri, const char *password) const char * soup_uri_get_host (SoupURI *uri) { + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL); + return uri->host; } /** * soup_uri_set_host: * @uri: a #SoupURI - * @host: the hostname or IP address, or %NULL + * @host: (allow-none): the hostname or IP address, or %NULL * * Sets @uri's host to @host. * * If @host is an IPv6 IP address, it should not include the brackets * required by the URI syntax; they will be added automatically when * converting @uri to a string. + * + * http and https URIs should not have a %NULL @host. **/ void soup_uri_set_host (SoupURI *uri, const char *host) { + g_return_if_fail (uri != NULL); + g_free (uri->host); uri->host = g_strdup (host); } @@ -899,6 +950,8 @@ soup_uri_set_host (SoupURI *uri, const char *host) guint soup_uri_get_port (SoupURI *uri) { + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), 0); + return uri->port; } @@ -913,6 +966,8 @@ soup_uri_get_port (SoupURI *uri) void soup_uri_set_port (SoupURI *uri, guint port) { + g_return_if_fail (uri != NULL); + uri->port = port; } @@ -929,19 +984,24 @@ soup_uri_set_port (SoupURI *uri, guint port) const char * soup_uri_get_path (SoupURI *uri) { + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL); + return uri->path; } /** * soup_uri_set_path: * @uri: a #SoupURI - * @path: the path + * @path: the non-%NULL path * * Sets @uri's path to @path. **/ void soup_uri_set_path (SoupURI *uri, const char *path) { + g_return_if_fail (uri != NULL); + g_return_if_fail (path != NULL); + g_free (uri->path); uri->path = g_strdup (path); } @@ -959,19 +1019,23 @@ soup_uri_set_path (SoupURI *uri, const char *path) const char * soup_uri_get_query (SoupURI *uri) { + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL); + return uri->query; } /** * soup_uri_set_query: * @uri: a #SoupURI - * @query: the query + * @query: (allow-none): the query * * Sets @uri's query to @query. **/ void soup_uri_set_query (SoupURI *uri, const char *query) { + g_return_if_fail (uri != NULL); + g_free (uri->query); uri->query = g_strdup (query); } @@ -988,6 +1052,8 @@ soup_uri_set_query (SoupURI *uri, const char *query) void soup_uri_set_query_from_form (SoupURI *uri, GHashTable *form) { + g_return_if_fail (uri != NULL); + g_free (uri->query); uri->query = soup_form_encode_hash (form); } @@ -1010,6 +1076,8 @@ soup_uri_set_query_from_fields (SoupURI *uri, { va_list args; + g_return_if_fail (uri != NULL); + g_free (uri->query); va_start (args, first_field); uri->query = soup_form_encode_valist (first_field, args); @@ -1029,19 +1097,23 @@ soup_uri_set_query_from_fields (SoupURI *uri, const char * soup_uri_get_fragment (SoupURI *uri) { + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL); + return uri->fragment; } /** * soup_uri_set_fragment: * @uri: a #SoupURI - * @fragment: the fragment + * @fragment: (allow-none): the fragment * * Sets @uri's fragment to @fragment. **/ void soup_uri_set_fragment (SoupURI *uri, const char *fragment) { + g_return_if_fail (uri != NULL); + g_free (uri->fragment); uri->fragment = g_strdup (fragment); } @@ -1061,7 +1133,7 @@ soup_uri_copy_host (SoupURI *uri) { SoupURI *dup; - g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), NULL); dup = soup_uri_new (NULL); dup->scheme = uri->scheme; @@ -1074,7 +1146,7 @@ soup_uri_copy_host (SoupURI *uri) /** * soup_uri_host_hash: - * @key: (type Soup.URI): a #SoupURI + * @key: (type Soup.URI): a #SoupURI with a non-%NULL @host member * * Hashes @key, considering only the scheme, host, and port. * @@ -1087,7 +1159,8 @@ soup_uri_host_hash (gconstpointer key) { const SoupURI *uri = key; - g_return_val_if_fail (uri != NULL && uri->host != NULL, 0); + g_return_val_if_fail (SOUP_URI_IS_VALID (uri), 0); + g_return_val_if_fail (uri->host != NULL, 0); return GPOINTER_TO_UINT (uri->scheme) + uri->port + soup_str_case_hash (uri->host); @@ -1095,8 +1168,8 @@ soup_uri_host_hash (gconstpointer key) /** * soup_uri_host_equal: - * @v1: (type Soup.URI): a #SoupURI - * @v2: (type Soup.URI): a #SoupURI + * @v1: (type Soup.URI): a #SoupURI with a non-%NULL @host member + * @v2: (type Soup.URI): a #SoupURI with a non-%NULL @host member * * Compares @v1 and @v2, considering only the scheme, host, and port. * @@ -1112,6 +1185,8 @@ soup_uri_host_equal (gconstpointer v1, gconstpointer v2) const SoupURI *two = v2; g_return_val_if_fail (one != NULL && two != NULL, one == two); + g_return_val_if_fail (SOUP_URI_IS_VALID (one), FALSE); + g_return_val_if_fail (SOUP_URI_IS_VALID (two), FALSE); g_return_val_if_fail (one->host != NULL && two->host != NULL, one->host == two->host); if (one->scheme != two->scheme) diff --git a/libsoup/soup-uri.h b/libsoup/soup-uri.h index a5c54a6..b851dbe 100644 --- a/libsoup/soup-uri.h +++ b/libsoup/soup-uri.h @@ -97,6 +97,7 @@ guint soup_uri_host_hash (gconstpointer key); gboolean soup_uri_host_equal (gconstpointer v1, gconstpointer v2); +#define SOUP_URI_IS_VALID(uri) ((uri) && (uri)->scheme && (uri)->path) #define SOUP_URI_VALID_FOR_HTTP(uri) ((uri) && ((uri)->scheme == SOUP_URI_SCHEME_HTTP || (uri)->scheme == SOUP_URI_SCHEME_HTTPS) && (uri)->host && (uri)->path) G_END_DECLS