/* GLIB - Library of useful routines for C programming
 * Copyright © 2020 Red Hat, Inc.
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, see
 * <http://www.gnu.org/licenses/>.
 */

#include "config.h"

#include <stdlib.h>
#include <string.h>

#include "glib.h"
#include "glibintl.h"
#include "glib-private.h"
#include "guriprivate.h"

/**
 * GUri:
 *
 * The `GUri` type and related functions can be used to parse URIs into
 * their components, and build valid URIs from individual components.
 *
 * Since `GUri` only represents absolute URIs, all `GUri`s will have a
 * URI scheme, so [method@GLib.Uri.get_scheme] will always return a non-`NULL`
 * answer. Likewise, by definition, all URIs have a path component, so
 * [method@GLib.Uri.get_path] will always return a non-`NULL` string (which may
 * be empty).
 *
 * If the URI string has an
 * [‘authority’ component](https://tools.ietf.org/html/rfc3986#section-3) (that
 * is, if the scheme is followed by `://` rather than just `:`), then the
 * `GUri` will contain a hostname, and possibly a port and ‘userinfo’.
 * Additionally, depending on how the `GUri` was constructed/parsed (for example,
 * using the `G_URI_FLAGS_HAS_PASSWORD` and `G_URI_FLAGS_HAS_AUTH_PARAMS` flags),
 * the userinfo may be split out into a username, password, and
 * additional authorization-related parameters.
 *
 * Normally, the components of a `GUri` will have all `%`-encoded
 * characters decoded. However, if you construct/parse a `GUri` with
 * `G_URI_FLAGS_ENCODED`, then the `%`-encoding will be preserved instead in
 * the userinfo, path, and query fields (and in the host field if also
 * created with `G_URI_FLAGS_NON_DNS`). In particular, this is necessary if
 * the URI may contain binary data or non-UTF-8 text, or if decoding
 * the components might change the interpretation of the URI.
 *
 * For example, with the encoded flag:
 *
 * ```c
 * g_autoptr(GUri) uri = g_uri_parse ("http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fparam%3Dvalue", G_URI_FLAGS_ENCODED, &err);
 * g_assert_cmpstr (g_uri_get_query (uri), ==, "query=http%3A%2F%2Fhost%2Fpath%3Fparam%3Dvalue");
 * ```
 *
 * While the default `%`-decoding behaviour would give:
 *
 * ```c
 * g_autoptr(GUri) uri = g_uri_parse ("http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fparam%3Dvalue", G_URI_FLAGS_NONE, &err);
 * g_assert_cmpstr (g_uri_get_query (uri), ==, "query=http://host/path?param=value");
 * ```
 *
 * During decoding, if an invalid UTF-8 string is encountered, parsing will fail
 * with an error indicating the bad string location:
 *
 * ```c
 * g_autoptr(GUri) uri = g_uri_parse ("http://host/path?query=http%3A%2F%2Fhost%2Fpath%3Fbad%3D%00alue", G_URI_FLAGS_NONE, &err);
 * g_assert_error (err, G_URI_ERROR, G_URI_ERROR_BAD_QUERY);
 * ```
 *
 * You should pass `G_URI_FLAGS_ENCODED` or `G_URI_FLAGS_ENCODED_QUERY` if you
 * need to handle that case manually. In particular, if the query string
 * contains `=` characters that are `%`-encoded, you should let
 * [func@GLib.Uri.parse_params] do the decoding once of the query.
 *
 * `GUri` is immutable once constructed, and can safely be accessed from
 * multiple threads. Its reference counting is atomic.
 *
 * Note that the scope of `GUri` is to help manipulate URIs in various applications,
 * following [RFC 3986](https://tools.ietf.org/html/rfc3986). In particular,
 * it doesn't intend to cover web browser needs, and doesn’t implement the
 * [WHATWG URL](https://url.spec.whatwg.org/) standard. No APIs are provided to
 * help prevent
 * [homograph attacks](https://en.wikipedia.org/wiki/IDN_homograph_attack), so
 * `GUri` is not suitable for formatting URIs for display to the user for making
 * security-sensitive decisions.
 *
 * ## Relative and absolute URIs
 *
 * As defined in [RFC 3986](https://tools.ietf.org/html/rfc3986#section-4), the
 * hierarchical nature of URIs means that they can either be ‘relative
 * references’ (sometimes referred to as ‘relative URIs’) or ‘URIs’ (for
 * clarity, ‘URIs’ are referred to in this documentation as
 * ‘absolute URIs’ — although
 * [in constrast to RFC 3986](https://tools.ietf.org/html/rfc3986#section-4.3),
 * fragment identifiers are always allowed).
 *
 * Relative references have one or more components of the URI missing. In
 * particular, they have no scheme. Any other component, such as hostname,
 * query, etc. may be missing, apart from a path, which has to be specified (but
 * may be empty). The path may be relative, starting with `./` rather than `/`.
 *
 * For example, a valid relative reference is `./path?query`,
 * `/?query#fragment` or `//example.com`.
 *
 * Absolute URIs have a scheme specified. Any other components of the URI which
 * are missing are specified as explicitly unset in the URI, rather than being
 * resolved relative to a base URI using [method@GLib.Uri.parse_relative].
 *
 * For example, a valid absolute URI is `file:///home/bob` or
 * `https://search.com?query=string`.
 *
 * A `GUri` instance is always an absolute URI. A string may be an absolute URI
 * or a relative reference; see the documentation for individual functions as to
 * what forms they accept.
 *
 * ## Parsing URIs
 *
 * The most minimalist APIs for parsing URIs are [func@GLib.Uri.split] and
 * [func@GLib.Uri.split_with_user]. These split a URI into its component
 * parts, and return the parts; the difference between the two is that
 * [func@GLib.Uri.split] treats the ‘userinfo’ component of the URI as a
 * single element, while [func@GLib.Uri.split_with_user] can (depending on the
 * [flags@GLib.UriFlags] you pass) treat it as containing a username, password,
 * and authentication parameters. Alternatively, [func@GLib.Uri.split_network]
 * can be used when you are only interested in the components that are
 * needed to initiate a network connection to the service (scheme,
 * host, and port).
 *
 * [func@GLib.Uri.parse] is similar to [func@GLib.Uri.split], but instead of
 * returning individual strings, it returns a `GUri` structure (and it requires
 * that the URI be an absolute URI).
 *
 * [func@GLib.Uri.resolve_relative] and [method@GLib.Uri.parse_relative] allow
 * you to resolve a relative URI relative to a base URI.
 * [func@GLib.Uri.resolve_relative] takes two strings and returns a string,
 * and [method@GLib.Uri.parse_relative] takes a `GUri` and a string and returns a
 * `GUri`.
 *
 * All of the parsing functions take a [flags@GLib.UriFlags] argument describing
 * exactly how to parse the URI; see the documentation for that type
 * for more details on the specific flags that you can pass. If you
 * need to choose different flags based on the type of URI, you can
 * use [func@GLib.Uri.peek_scheme] on the URI string to check the scheme
 * first, and use that to decide what flags to parse it with.
 *
 * For example, you might want to use `G_URI_PARAMS_WWW_FORM` when parsing the
 * params for a web URI, so compare the result of [func@GLib.Uri.peek_scheme]
 * against `http` and `https`.
 *
 * ## Building URIs
 *
 * [func@GLib.Uri.join] and [func@GLib.Uri.join_with_user] can be used to construct
 * valid URI strings from a set of component strings. They are the
 * inverse of [func@GLib.Uri.split] and [func@GLib.Uri.split_with_user].
 *
 * Similarly, [func@GLib.Uri.build] and [func@GLib.Uri.build_with_user] can be
 * used to construct a `GUri` from a set of component strings.
 *
 * As with the parsing functions, the building functions take a
 * [flags@GLib.UriFlags] argument. In particular, it is important to keep in mind
 * whether the URI components you are using are already `%`-encoded. If so,
 * you must pass the `G_URI_FLAGS_ENCODED` flag.
 *
 * ## `file://` URIs
 *
 * Note that Windows and Unix both define special rules for parsing
 * `file://` URIs (involving non-UTF-8 character sets on Unix, and the
 * interpretation of path separators on Windows). `GUri` does not
 * implement these rules. Use [func@GLib.filename_from_uri] and
 * [func@GLib.filename_to_uri] if you want to properly convert between
 * `file://` URIs and local filenames.
 *
 * ## URI Equality
 *
 * Note that there is no `g_uri_equal ()` function, because comparing
 * URIs usefully requires scheme-specific knowledge that `GUri` does
 * not have. `GUri` can help with normalization if you use the various
 * encoded [flags@GLib.UriFlags] as well as `G_URI_FLAGS_SCHEME_NORMALIZE`
 * however it is not comprehensive.
 * For example, `data:,foo` and `data:;base64,Zm9v` resolve to the same
 * thing according to the `data:` URI specification which GLib does not
 * handle.
 *
 * Since: 2.66
 */
struct _GUri {
  gchar     *scheme;
  gchar     *userinfo;
  gchar     *host;
  gint       port;
  gchar     *path;
  gchar     *query;
  gchar     *fragment;

  gchar     *user;
  gchar     *password;
  gchar     *auth_params;

  GUriFlags  flags;
};

/**
 * g_uri_ref: (skip)
 * @uri: a #GUri
 *
 * Increments the reference count of @uri by one.
 *
 * Returns: @uri
 *
 * Since: 2.66
 */
GUri *
g_uri_ref (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return g_atomic_rc_box_acquire (uri);
}

static void
g_uri_clear (GUri *uri)
{
  g_free (uri->scheme);
  g_free (uri->userinfo);
  g_free (uri->host);
  g_free (uri->path);
  g_free (uri->query);
  g_free (uri->fragment);
  g_free (uri->user);
  g_free (uri->password);
  g_free (uri->auth_params);
}

/**
 * g_uri_unref: (skip)
 * @uri: a #GUri
 *
 * Atomically decrements the reference count of @uri by one.
 *
 * When the reference count reaches zero, the resources allocated by
 * @uri are freed
 *
 * Since: 2.66
 */
void
g_uri_unref (GUri *uri)
{
  g_return_if_fail (uri != NULL);

  g_atomic_rc_box_release_full (uri, (GDestroyNotify)g_uri_clear);
}

static gboolean
g_uri_char_is_unreserved (gchar ch)
{
  if (g_ascii_isalnum (ch))
    return TRUE;
  return ch == '-' || ch == '.' || ch == '_' || ch == '~';
}

#define XDIGIT(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10)
#define HEXCHAR(s) ((XDIGIT (s[1]) << 4) + XDIGIT (s[2]))

static gssize
uri_decoder (gchar       **out,
             const gchar  *illegal_chars,
             const gchar  *start,
             gsize         length,
             gboolean      just_normalize,
             gboolean      www_form,
             GUriFlags     flags,
             GUriError     parse_error,
             GError      **error)
{
  gchar c;
  GString *decoded;
  const gchar *invalid, *s, *end;
  gssize len;

  if (!(flags & G_URI_FLAGS_ENCODED))
    just_normalize = FALSE;

  decoded = g_string_sized_new (length + 1);
  for (s = start, end = s + length; s < end; s++)
    {
      if (*s == '%')
        {
          if (s + 2 >= end ||
              !g_ascii_isxdigit (s[1]) ||
              !g_ascii_isxdigit (s[2]))
            {
              /* % followed by non-hex or the end of the string; this is an error */
              if (!(flags & G_URI_FLAGS_PARSE_RELAXED))
                {
                  g_set_error_literal (error, G_URI_ERROR, parse_error,
                                       /* xgettext: no-c-format */
                                       _("Invalid %-encoding in URI"));
                  g_string_free (decoded, TRUE);
                  return -1;
                }

              /* In non-strict mode, just let it through; we *don't*
               * fix it to "%25", since that might change the way that
               * the URI's owner would interpret it.
               */
              g_string_append_c (decoded, *s);
              continue;
            }

          c = HEXCHAR (s);
          if (illegal_chars && strchr (illegal_chars, c))
            {
              g_set_error_literal (error, G_URI_ERROR, parse_error,
                                   _("Illegal character in URI"));
              g_string_free (decoded, TRUE);
              return -1;
            }
          if (just_normalize && !g_uri_char_is_unreserved (c))
            {
              /* Leave the % sequence there but normalize it. */
              g_string_append_c (decoded, *s);
              g_string_append_c (decoded, g_ascii_toupper (s[1]));
              g_string_append_c (decoded, g_ascii_toupper (s[2]));
              s += 2;
            }
          else
            {
              g_string_append_c (decoded, c);
              s += 2;
            }
        }
      else if (www_form && *s == '+')
        g_string_append_c (decoded, ' ');
      /* Normalize any illegal characters. */
      else if (just_normalize && (!g_ascii_isgraph (*s)))
        g_string_append_printf (decoded, "%%%02X", (guchar)*s);
      else
        g_string_append_c (decoded, *s);
    }

  len = decoded->len;
  g_assert (len >= 0);

  if (!(flags & G_URI_FLAGS_ENCODED) &&
      !g_utf8_validate (decoded->str, len, &invalid))
    {
      g_set_error_literal (error, G_URI_ERROR, parse_error,
                           _("Non-UTF-8 characters in URI"));
      g_string_free (decoded, TRUE);
      return -1;
    }

  if (out)
    *out = g_string_free (decoded, FALSE);
  else
    g_string_free (decoded, TRUE);

  return len;
}

static gboolean
uri_decode (gchar       **out,
            const gchar  *illegal_chars,
            const gchar  *start,
            gsize         length,
            gboolean      www_form,
            GUriFlags     flags,
            GUriError     parse_error,
            GError      **error)
{
  return uri_decoder (out, illegal_chars, start, length, FALSE, www_form, flags,
                      parse_error, error) != -1;
}

static gboolean
uri_normalize (gchar       **out,
               const gchar  *start,
               gsize         length,
               GUriFlags     flags,
               GUriError     parse_error,
               GError      **error)
{
  return uri_decoder (out, NULL, start, length, TRUE, FALSE, flags,
                      parse_error, error) != -1;
}

static gboolean
is_valid (guchar       c,
          const gchar *reserved_chars_allowed)
{
  if (g_uri_char_is_unreserved (c))
    return TRUE;

  if (reserved_chars_allowed && strchr (reserved_chars_allowed, c))
    return TRUE;

  return FALSE;
}

void
_uri_encoder (GString      *out,
              const guchar *start,
              gsize         length,
              const gchar  *reserved_chars_allowed,
              gboolean      allow_utf8)
{
  static const gchar hex[] = "0123456789ABCDEF";
  const guchar *p = start;
  const guchar *end = p + length;

  while (p < end)
    {
      gunichar multibyte_utf8_char = 0;

      if (allow_utf8 && *p >= 0x80)
        multibyte_utf8_char = g_utf8_get_char_validated ((gchar *)p, end - p);

      if (multibyte_utf8_char > 0 &&
          multibyte_utf8_char != (gunichar) -1 && multibyte_utf8_char != (gunichar) -2)
        {
          gint len = g_utf8_skip [*p];
          g_string_append_len (out, (gchar *)p, len);
          p += len;
        }
      else if (is_valid (*p, reserved_chars_allowed))
        {
          g_string_append_c (out, *p);
          p++;
        }
      else
        {
          g_string_append_c (out, '%');
          g_string_append_c (out, hex[*p >> 4]);
          g_string_append_c (out, hex[*p & 0xf]);
          p++;
        }
    }
}

/* Parse the IP-literal construction from RFC 6874 (which extends RFC 3986 to
 * support IPv6 zone identifiers.
 *
 * Currently, IP versions beyond 6 (i.e. the IPvFuture rule) are unsupported.
 * There’s no point supporting them until (a) they exist and (b) the rest of the
 * stack (notably, sockets) supports them.
 *
 * Rules:
 *
 * IP-literal = "[" ( IPv6address / IPv6addrz / IPvFuture  ) "]"
 *
 * ZoneID = 1*( unreserved / pct-encoded )
 *
 * IPv6addrz = IPv6address "%25" ZoneID
 *
 * If %G_URI_FLAGS_PARSE_RELAXED is specified, this function also accepts:
 *
 * IPv6addrz = IPv6address "%" ZoneID
 */
static gboolean
parse_ip_literal (const gchar  *start,
                  gsize         length,
                  GUriFlags     flags,
                  gchar       **out,
                  GError      **error)
{
  gchar *pct, *zone_id = NULL;
  gchar *addr = NULL;
  gsize addr_length = 0;
  gsize zone_id_length = 0;
  gchar *decoded_zone_id = NULL;

  if (start[length - 1] != ']')
    goto bad_ipv6_literal;

  /* Drop the square brackets */
  addr = g_strndup (start + 1, length - 2);
  addr_length = length - 2;

  /* If there's an IPv6 scope ID, split out the zone. */
  pct = strchr (addr, '%');
  if (pct != NULL)
    {
      *pct = '\0';

      if (addr_length - (pct - addr) >= 4 &&
          *(pct + 1) == '2' && *(pct + 2) == '5')
        {
          zone_id = pct + 3;
          zone_id_length = addr_length - (zone_id - addr);
        }
      else if (flags & G_URI_FLAGS_PARSE_RELAXED &&
               addr_length - (pct - addr) >= 2)
        {
          zone_id = pct + 1;
          zone_id_length = addr_length - (zone_id - addr);
        }
      else
        goto bad_ipv6_literal;

      g_assert (zone_id_length >= 1);
    }

  /* addr must be an IPv6 address */
  if (!g_hostname_is_ip_address (addr) || !strchr (addr, ':'))
    goto bad_ipv6_literal;

  /* Zone ID must be valid. It can contain %-encoded characters. */
  if (zone_id != NULL &&
      !uri_decode (&decoded_zone_id, NULL, zone_id, zone_id_length, FALSE,
                   flags, G_URI_ERROR_BAD_HOST, NULL))
    goto bad_ipv6_literal;

  /* Success */
  if (out != NULL && decoded_zone_id != NULL)
    *out = g_strconcat (addr, "%", decoded_zone_id, NULL);
  else if (out != NULL)
    *out = g_steal_pointer (&addr);

  g_free (addr);
  g_free (decoded_zone_id);

  return TRUE;

bad_ipv6_literal:
  g_free (addr);
  g_free (decoded_zone_id);
  g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST,
               _("Invalid IPv6 address ‘%.*s’ in URI"),
               (gint)length, start);

  return FALSE;
}

static gboolean
parse_host (const gchar  *start,
            gsize         length,
            GUriFlags     flags,
            gchar       **out,
            GError      **error)
{
  gchar *decoded = NULL, *host;
  gchar *addr = NULL;

  if (*start == '[')
    {
      if (!parse_ip_literal (start, length, flags, &host, error))
        return FALSE;
      goto ok;
    }

  if (g_ascii_isdigit (*start))
    {
      addr = g_strndup (start, length);
      if (g_hostname_is_ip_address (addr))
        {
          host = addr;
          goto ok;
        }
      g_free (addr);
    }

  if (flags & G_URI_FLAGS_NON_DNS)
    {
      if (!uri_normalize (&decoded, start, length, flags,
                          G_URI_ERROR_BAD_HOST, error))
        return FALSE;
      host = g_steal_pointer (&decoded);
      goto ok;
    }

  flags &= ~G_URI_FLAGS_ENCODED;
  if (!uri_decode (&decoded, NULL, start, length, FALSE, flags,
                   G_URI_ERROR_BAD_HOST, error))
    return FALSE;

  /* You're not allowed to %-encode an IP address, so if it wasn't
   * one before, it better not be one now.
   */
  if (g_hostname_is_ip_address (decoded))
    {
      g_free (decoded);
      g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST,
                   _("Illegal encoded IP address ‘%.*s’ in URI"),
                   (gint)length, start);
      return FALSE;
    }

  if (g_hostname_is_non_ascii (decoded))
    {
      host = g_hostname_to_ascii (decoded);
      if (host == NULL)
        {
          g_free (decoded);
          g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST,
                       _("Illegal internationalized hostname ‘%.*s’ in URI"),
                       (gint) length, start);
          return FALSE;
        }
    }
  else
    {
      host = g_steal_pointer (&decoded);
    }

 ok:
  if (out)
    *out = g_steal_pointer (&host);
  g_free (host);
  g_free (decoded);

  return TRUE;
}

static gboolean
parse_port (const gchar  *start,
            gsize         length,
            gint         *out,
            GError      **error)
{
  gchar *end;
  gulong parsed_port;

  /* strtoul() allows leading + or -, so we have to check this first. */
  if (!g_ascii_isdigit (*start))
    {
      g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT,
                   _("Could not parse port ‘%.*s’ in URI"),
                   (gint)length, start);
      return FALSE;
    }

  /* We know that *(start + length) is either '\0' or a non-numeric
   * character, so strtoul() won't scan beyond it.
   */
  parsed_port = strtoul (start, &end, 10);
  if (end != start + length)
    {
      g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT,
                   _("Could not parse port ‘%.*s’ in URI"),
                   (gint)length, start);
      return FALSE;
    }
  else if (parsed_port > 65535)
    {
      g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_PORT,
                   _("Port ‘%.*s’ in URI is out of range"),
                   (gint)length, start);
      return FALSE;
    }

  if (out)
    *out = parsed_port;
  return TRUE;
}

static gboolean
parse_userinfo (const gchar  *start,
                gsize         length,
                GUriFlags     flags,
                gchar       **user,
                gchar       **password,
                gchar       **auth_params,
                GError      **error)
{
  const gchar *user_end = NULL, *password_end = NULL, *auth_params_end;

  auth_params_end = start + length;
  if (flags & G_URI_FLAGS_HAS_AUTH_PARAMS)
    password_end = memchr (start, ';', auth_params_end - start);
  if (!password_end)
    password_end = auth_params_end;
  if (flags & G_URI_FLAGS_HAS_PASSWORD)
    user_end = memchr (start, ':', password_end - start);
  if (!user_end)
    user_end = password_end;

  if (!uri_normalize (user, start, user_end - start, flags,
                      G_URI_ERROR_BAD_USER, error))
    return FALSE;

  if (*user_end == ':')
    {
      start = user_end + 1;
      if (!uri_normalize (password, start, password_end - start, flags,
                          G_URI_ERROR_BAD_PASSWORD, error))
        {
          if (user)
            g_clear_pointer (user, g_free);
          return FALSE;
        }
    }
  else if (password)
    *password = NULL;

  if (*password_end == ';')
    {
      start = password_end + 1;
      if (!uri_normalize (auth_params, start, auth_params_end - start, flags,
                          G_URI_ERROR_BAD_AUTH_PARAMS, error))
        {
          if (user)
            g_clear_pointer (user, g_free);
          if (password)
            g_clear_pointer (password, g_free);
          return FALSE;
        }
    }
  else if (auth_params)
    *auth_params = NULL;

  return TRUE;
}

static gchar *
uri_cleanup (const gchar *uri_string)
{
  GString *copy;
  const gchar *end;

  /* Skip leading whitespace */
  while (g_ascii_isspace (*uri_string))
    uri_string++;

  /* Ignore trailing whitespace */
  end = uri_string + strlen (uri_string);
  while (end > uri_string && g_ascii_isspace (*(end - 1)))
    end--;

  /* Copy the rest, encoding unencoded spaces and stripping other whitespace */
  copy = g_string_sized_new (end - uri_string);
  while (uri_string < end)
    {
      if (*uri_string == ' ')
        g_string_append (copy, "%20");
      else if (g_ascii_isspace (*uri_string))
        ;
      else
        g_string_append_c (copy, *uri_string);
      uri_string++;
    }

  return g_string_free (copy, FALSE);
}

static gboolean
should_normalize_empty_path (const char *scheme)
{
  const char * const schemes[] = { "https", "http", "wss", "ws" };
  gsize i;
  for (i = 0; i < G_N_ELEMENTS (schemes); ++i)
    {
      if (!strcmp (schemes[i], scheme))
        return TRUE;
    }
  return FALSE;
}

static int
normalize_port (const char *scheme,
                int         port)
{
  const char *default_schemes[3] = { NULL };
  int i;

  switch (port)
    {
    case 21:
      default_schemes[0] = "ftp";
      break;
    case 80:
      default_schemes[0] = "http";
      default_schemes[1] = "ws";
      break;
    case 443:
      default_schemes[0] = "https";
      default_schemes[1] = "wss";
      break;
    default:
      break;
    }

  for (i = 0; default_schemes[i]; ++i)
    {
      if (!strcmp (scheme, default_schemes[i]))
        return -1;
    }

  return port;
}

int
g_uri_get_default_scheme_port (const char *scheme)
{
  if (strcmp (scheme, "http") == 0 || strcmp (scheme, "ws") == 0)
    return 80;

  if (strcmp (scheme, "https") == 0 || strcmp (scheme, "wss") == 0)
    return 443;

  if (strcmp (scheme, "ftp") == 0)
    return 21;

  if (strstr (scheme, "socks") == scheme)
    return 1080;

  return -1;
}

static gboolean
g_uri_split_internal (const gchar  *uri_string,
                      GUriFlags     flags,
                      gchar       **scheme,
                      gchar       **userinfo,
                      gchar       **user,
                      gchar       **password,
                      gchar       **auth_params,
                      gchar       **host,
                      gint         *port,
                      gchar       **path,
                      gchar       **query,
                      gchar       **fragment,
                      GError      **error)
{
  const gchar *end, *colon, *at, *path_start, *semi, *question;
  const gchar *p, *bracket, *hostend;
  gchar *cleaned_uri_string = NULL;
  gchar *normalized_scheme = NULL;

  if (scheme)
    *scheme = NULL;
  if (userinfo)
    *userinfo = NULL;
  if (user)
    *user = NULL;
  if (password)
    *password = NULL;
  if (auth_params)
    *auth_params = NULL;
  if (host)
    *host = NULL;
  if (port)
    *port = -1;
  if (path)
    *path = NULL;
  if (query)
    *query = NULL;
  if (fragment)
    *fragment = NULL;

  if ((flags & G_URI_FLAGS_PARSE_RELAXED) && strpbrk (uri_string, " \t\n\r"))
    {
      cleaned_uri_string = uri_cleanup (uri_string);
      uri_string = cleaned_uri_string;
    }

  /* Find scheme */
  p = uri_string;
  while (*p && (g_ascii_isalpha (*p) ||
               (p > uri_string && (g_ascii_isdigit (*p) ||
                                   *p == '.' || *p == '+' || *p == '-'))))
    p++;

  if (p > uri_string && *p == ':')
    {
      normalized_scheme = g_ascii_strdown (uri_string, p - uri_string);
      if (scheme)
        *scheme = g_steal_pointer (&normalized_scheme);
      p++;
    }
  else
    {
      if (scheme)
        *scheme = NULL;
      p = uri_string;
    }

  /* Check for authority */
  if (strncmp (p, "//", 2) == 0)
    {
      p += 2;

      path_start = p + strcspn (p, "/?#");
      at = memchr (p, '@', path_start - p);
      if (at)
        {
          if (flags & G_URI_FLAGS_PARSE_RELAXED)
            {
              gchar *next_at;

              /* Any "@"s in the userinfo must be %-encoded, but
               * people get this wrong sometimes. Since "@"s in the
               * hostname are unlikely (and also wrong anyway), assume
               * that if there are extra "@"s, they belong in the
               * userinfo.
               */
              do
                {
                  next_at = memchr (at + 1, '@', path_start - (at + 1));
                  if (next_at)
                    at = next_at;
                }
              while (next_at);
            }

          if (user || password || auth_params ||
              (flags & (G_URI_FLAGS_HAS_PASSWORD|G_URI_FLAGS_HAS_AUTH_PARAMS)))
            {
              if (!parse_userinfo (p, at - p, flags,
                                   user, password, auth_params,
                                   error))
                goto fail;
            }

          if (!uri_normalize (userinfo, p, at - p, flags,
                              G_URI_ERROR_BAD_USER, error))
            goto fail;

          p = at + 1;
        }

      if (flags & G_URI_FLAGS_PARSE_RELAXED)
        {
          semi = strchr (p, ';');
          if (semi && semi < path_start)
            {
              /* Technically, semicolons are allowed in the "host"
               * production, but no one ever does this, and some
               * schemes mistakenly use semicolon as a delimiter
               * marking the start of the path. We have to check this
               * after checking for userinfo though, because a
               * semicolon before the "@" must be part of the
               * userinfo.
               */
              path_start = semi;
            }
        }

      /* Find host and port. The host may be a bracket-delimited IPv6
       * address, in which case the colon delimiting the port must come
       * (immediately) after the close bracket.
       */
      if (*p == '[')
        {
          bracket = memchr (p, ']', path_start - p);
          if (bracket && *(bracket + 1) == ':')
            colon = bracket + 1;
          else
            colon = NULL;
        }
      else
        colon = memchr (p, ':', path_start - p);

      hostend = colon ? colon : path_start;
      if (!parse_host (p, hostend - p, flags, host, error))
        goto fail;

      if (colon && colon != path_start - 1)
        {
          p = colon + 1;
          if (!parse_port (p, path_start - p, port, error))
            goto fail;
        }

      p = path_start;
    }

  /* Find fragment. */
  end = p + strcspn (p, "#");
  if (*end == '#')
    {
      if (!uri_normalize (fragment, end + 1, strlen (end + 1),
                          flags | (flags & G_URI_FLAGS_ENCODED_FRAGMENT ? G_URI_FLAGS_ENCODED : 0),
                          G_URI_ERROR_BAD_FRAGMENT, error))
        goto fail;
    }

  /* Find query */
  question = memchr (p, '?', end - p);
  if (question)
    {
      if (!uri_normalize (query, question + 1, end - (question + 1),
                          flags | (flags & G_URI_FLAGS_ENCODED_QUERY ? G_URI_FLAGS_ENCODED : 0),
                          G_URI_ERROR_BAD_QUERY, error))
        goto fail;
      end = question;
    }

  if (!uri_normalize (path, p, end - p,
                      flags | (flags & G_URI_FLAGS_ENCODED_PATH ? G_URI_FLAGS_ENCODED : 0),
                      G_URI_ERROR_BAD_PATH, error))
    goto fail;

  /* Scheme-based normalization */
  if (flags & G_URI_FLAGS_SCHEME_NORMALIZE && ((scheme && *scheme) || normalized_scheme))
    {
      const char *scheme_str = scheme && *scheme ? *scheme : normalized_scheme;

      if (should_normalize_empty_path (scheme_str) && path && !**path)
        {
          g_free (*path);
          *path = g_strdup ("/");
        }

      if (port && *port == -1)
        *port = g_uri_get_default_scheme_port (scheme_str);
    }

  g_free (normalized_scheme);
  g_free (cleaned_uri_string);
  return TRUE;

 fail:
  if (scheme)
    g_clear_pointer (scheme, g_free);
  if (userinfo)
    g_clear_pointer (userinfo, g_free);
  if (host)
    g_clear_pointer (host, g_free);
  if (port)
    *port = -1;
  if (path)
    g_clear_pointer (path, g_free);
  if (query)
    g_clear_pointer (query, g_free);
  if (fragment)
    g_clear_pointer (fragment, g_free);

  g_free (normalized_scheme);
  g_free (cleaned_uri_string);
  return FALSE;
}

/**
 * g_uri_split:
 * @uri_ref: a string containing a relative or absolute URI
 * @flags: flags for parsing @uri_ref
 * @scheme: (out) (nullable) (optional) (transfer full): on return, contains
 *    the scheme (converted to lowercase), or %NULL
 * @userinfo: (out) (nullable) (optional) (transfer full): on return, contains
 *    the userinfo, or %NULL
 * @host: (out) (nullable) (optional) (transfer full): on return, contains the
 *    host, or %NULL
 * @port: (out) (optional) (transfer full): on return, contains the
 *    port, or `-1`
 * @path: (out) (not nullable) (optional) (transfer full): on return, contains the
 *    path
 * @query: (out) (nullable) (optional) (transfer full): on return, contains the
 *    query, or %NULL
 * @fragment: (out) (nullable) (optional) (transfer full): on return, contains
 *    the fragment, or %NULL
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Parses @uri_ref (which can be an
 * [absolute or relative URI](#relative-and-absolute-uris)) according to @flags, and
 * returns the pieces. Any component that doesn't appear in @uri_ref will be
 * returned as %NULL (but note that all URIs always have a path component,
 * though it may be the empty string).
 *
 * If @flags contains %G_URI_FLAGS_ENCODED, then `%`-encoded characters in
 * @uri_ref will remain encoded in the output strings. (If not,
 * then all such characters will be decoded.) Note that decoding will
 * only work if the URI components are ASCII or UTF-8, so you will
 * need to use %G_URI_FLAGS_ENCODED if they are not.
 *
 * Note that the %G_URI_FLAGS_HAS_PASSWORD and
 * %G_URI_FLAGS_HAS_AUTH_PARAMS @flags are ignored by g_uri_split(),
 * since it always returns only the full userinfo; use
 * g_uri_split_with_user() if you want it split up.
 *
 * Returns: (skip): %TRUE if @uri_ref parsed successfully, %FALSE
 *   on error.
 *
 * Since: 2.66
 */
gboolean
g_uri_split (const gchar  *uri_ref,
             GUriFlags     flags,
             gchar       **scheme,
             gchar       **userinfo,
             gchar       **host,
             gint         *port,
             gchar       **path,
             gchar       **query,
             gchar       **fragment,
             GError      **error)
{
  g_return_val_if_fail (uri_ref != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  return g_uri_split_internal (uri_ref, flags,
                               scheme, userinfo, NULL, NULL, NULL,
                               host, port, path, query, fragment,
                               error);
}

/**
 * g_uri_split_with_user:
 * @uri_ref: a string containing a relative or absolute URI
 * @flags: flags for parsing @uri_ref
 * @scheme: (out) (nullable) (optional) (transfer full): on return, contains
 *    the scheme (converted to lowercase), or %NULL
 * @user: (out) (nullable) (optional) (transfer full): on return, contains
 *    the user, or %NULL
 * @password: (out) (nullable) (optional) (transfer full): on return, contains
 *    the password, or %NULL
 * @auth_params: (out) (nullable) (optional) (transfer full): on return, contains
 *    the auth_params, or %NULL
 * @host: (out) (nullable) (optional) (transfer full): on return, contains the
 *    host, or %NULL
 * @port: (out) (optional) (transfer full): on return, contains the
 *    port, or `-1`
 * @path: (out) (not nullable) (optional) (transfer full): on return, contains the
 *    path
 * @query: (out) (nullable) (optional) (transfer full): on return, contains the
 *    query, or %NULL
 * @fragment: (out) (nullable) (optional) (transfer full): on return, contains
 *    the fragment, or %NULL
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Parses @uri_ref (which can be an
 * [absolute or relative URI](#relative-and-absolute-uris)) according to @flags, and
 * returns the pieces. Any component that doesn't appear in @uri_ref will be
 * returned as %NULL (but note that all URIs always have a path component,
 * though it may be the empty string).
 *
 * See g_uri_split(), and the definition of #GUriFlags, for more
 * information on the effect of @flags. Note that @password will only
 * be parsed out if @flags contains %G_URI_FLAGS_HAS_PASSWORD, and
 * @auth_params will only be parsed out if @flags contains
 * %G_URI_FLAGS_HAS_AUTH_PARAMS.
 *
 * Returns: (skip): %TRUE if @uri_ref parsed successfully, %FALSE
 *   on error.
 *
 * Since: 2.66
 */
gboolean
g_uri_split_with_user (const gchar  *uri_ref,
                       GUriFlags     flags,
                       gchar       **scheme,
                       gchar       **user,
                       gchar       **password,
                       gchar       **auth_params,
                       gchar       **host,
                       gint         *port,
                       gchar       **path,
                       gchar       **query,
                       gchar       **fragment,
                       GError      **error)
{
  g_return_val_if_fail (uri_ref != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  return g_uri_split_internal (uri_ref, flags,
                               scheme, NULL, user, password, auth_params,
                               host, port, path, query, fragment,
                               error);
}


/**
 * g_uri_split_network:
 * @uri_string: a string containing an absolute URI
 * @flags: flags for parsing @uri_string
 * @scheme: (out) (nullable) (optional) (transfer full): on return, contains
 *    the scheme (converted to lowercase), or %NULL
 * @host: (out) (nullable) (optional) (transfer full): on return, contains the
 *    host, or %NULL
 * @port: (out) (optional) (transfer full): on return, contains the
 *    port, or `-1`
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Parses @uri_string (which must be an [absolute URI](#relative-and-absolute-uris))
 * according to @flags, and returns the pieces relevant to connecting to a host.
 * See the documentation for g_uri_split() for more details; this is
 * mostly a wrapper around that function with simpler arguments.
 * However, it will return an error if @uri_string is a relative URI,
 * or does not contain a hostname component.
 *
 * Returns: (skip): %TRUE if @uri_string parsed successfully,
 *   %FALSE on error.
 *
 * Since: 2.66
 */
gboolean
g_uri_split_network (const gchar  *uri_string,
                     GUriFlags     flags,
                     gchar       **scheme,
                     gchar       **host,
                     gint         *port,
                     GError      **error)
{
  gchar *my_scheme = NULL, *my_host = NULL;

  g_return_val_if_fail (uri_string != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (!g_uri_split_internal (uri_string, flags,
                             &my_scheme, NULL, NULL, NULL, NULL,
                             &my_host, port, NULL, NULL, NULL,
                             error))
    return FALSE;

  if (!my_scheme || !my_host)
    {
      if (!my_scheme)
        {
          g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_SCHEME,
                       _("URI ‘%s’ is not an absolute URI"),
                       uri_string);
        }
      else
        {
          g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_HOST,
                       _("URI ‘%s’ has no host component"),
                       uri_string);
        }
      g_free (my_scheme);
      g_free (my_host);

      return FALSE;
    }

  if (scheme)
    *scheme = g_steal_pointer (&my_scheme);
  if (host)
    *host = g_steal_pointer (&my_host);

  g_free (my_scheme);
  g_free (my_host);

  return TRUE;
}

/**
 * g_uri_is_valid:
 * @uri_string: a string containing an absolute URI
 * @flags: flags for parsing @uri_string
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Parses @uri_string according to @flags, to determine whether it is a valid
 * [absolute URI](#relative-and-absolute-uris), i.e. it does not need to be resolved
 * relative to another URI using g_uri_parse_relative().
 *
 * If it’s not a valid URI, an error is returned explaining how it’s invalid.
 *
 * See g_uri_split(), and the definition of #GUriFlags, for more
 * information on the effect of @flags.
 *
 * Returns: %TRUE if @uri_string is a valid absolute URI, %FALSE on error.
 *
 * Since: 2.66
 */
gboolean
g_uri_is_valid (const gchar  *uri_string,
                GUriFlags     flags,
                GError      **error)
{
  gchar *my_scheme = NULL;

  g_return_val_if_fail (uri_string != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (!g_uri_split_internal (uri_string, flags,
                             &my_scheme, NULL, NULL, NULL, NULL,
                             NULL, NULL, NULL, NULL, NULL,
                             error))
    return FALSE;

  if (!my_scheme)
    {
      g_set_error (error, G_URI_ERROR, G_URI_ERROR_BAD_SCHEME,
                   _("URI ‘%s’ is not an absolute URI"),
                   uri_string);
      return FALSE;
    }

  g_free (my_scheme);

  return TRUE;
}


/* Implements the "Remove Dot Segments" algorithm from section 5.2.4 of
 * RFC 3986.
 *
 * See https://tools.ietf.org/html/rfc3986#section-5.2.4
 */
static void
remove_dot_segments (gchar *path)
{
  /* The output can be written to the same buffer that the input
   * is read from, as the output pointer is only ever increased
   * when the input pointer is increased as well, and the input
   * pointer is never decreased. */
  gchar *input = path;
  gchar *output = path;

  if (!*path)
    return;

  while (*input)
    {
      /*  A.  If the input buffer begins with a prefix of "../" or "./",
       *      then remove that prefix from the input buffer; otherwise,
       */
      if (strncmp (input, "../", 3) == 0)
        input += 3;
      else if (strncmp (input, "./", 2) == 0)
        input += 2;

      /*  B.  if the input buffer begins with a prefix of "/./" or "/.",
       *      where "." is a complete path segment, then replace that
       *      prefix with "/" in the input buffer; otherwise,
       */
      else if (strncmp (input, "/./", 3) == 0)
        input += 2;
      else if (strcmp (input, "/.") == 0)
        input[1] = '\0';

      /*  C.  if the input buffer begins with a prefix of "/../" or "/..",
       *      where ".." is a complete path segment, then replace that
       *      prefix with "/" in the input buffer and remove the last
       *      segment and its preceding "/" (if any) from the output
       *      buffer; otherwise,
       */
      else if (strncmp (input, "/../", 4) == 0)
        {
          input += 3;
          if (output > path)
            {
              do
                {
                  output--;
                }
              while (*output != '/' && output > path);
            }
        }
      else if (strcmp (input, "/..") == 0)
        {
          input[1] = '\0';
          if (output > path)
            {
              do
                 {
                   output--;
                 }
              while (*output != '/' && output > path);
            }
        }

      /*  D.  if the input buffer consists only of "." or "..", then remove
       *      that from the input buffer; otherwise,
       */
      else if (strcmp (input, "..") == 0 || strcmp (input, ".") == 0)
        input[0] = '\0';

      /*  E.  move the first path segment in the input buffer to the end of
       *      the output buffer, including the initial "/" character (if
       *      any) and any subsequent characters up to, but not including,
       *      the next "/" character or the end of the input buffer.
       */
      else
        {
          *output++ = *input++;
          while (*input && *input != '/')
            *output++ = *input++;
        }
    }
  *output = '\0';
}

/**
 * g_uri_parse:
 * @uri_string: a string representing an absolute URI
 * @flags: flags describing how to parse @uri_string
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Parses @uri_string according to @flags. If the result is not a
 * valid [absolute URI](#relative-and-absolute-uris), it will be discarded, and an
 * error returned.
 *
 * Return value: (transfer full): a new #GUri, or NULL on error.
 *
 * Since: 2.66
 */
GUri *
g_uri_parse (const gchar  *uri_string,
             GUriFlags     flags,
             GError      **error)
{
  g_return_val_if_fail (uri_string != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  return g_uri_parse_relative (NULL, uri_string, flags, error);
}

/**
 * g_uri_parse_relative:
 * @base_uri: (nullable) (transfer none): a base absolute URI
 * @uri_ref: a string representing a relative or absolute URI
 * @flags: flags describing how to parse @uri_ref
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Parses @uri_ref according to @flags and, if it is a
 * [relative URI](#relative-and-absolute-uris), resolves it relative to @base_uri.
 * If the result is not a valid absolute URI, it will be discarded, and an error
 * returned.
 *
 * Return value: (transfer full): a new #GUri, or NULL on error.
 *
 * Since: 2.66
 */
GUri *
g_uri_parse_relative (GUri         *base_uri,
                      const gchar  *uri_ref,
                      GUriFlags     flags,
                      GError      **error)
{
  GUri *uri = NULL;

  g_return_val_if_fail (uri_ref != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
  g_return_val_if_fail (base_uri == NULL || base_uri->scheme != NULL, NULL);

  /* Use GUri struct to construct the return value: there is no guarantee it is
   * actually correct within the function body. */
  uri = g_atomic_rc_box_new0 (GUri);
  uri->flags = flags;

  if (!g_uri_split_internal (uri_ref, flags,
                             &uri->scheme, &uri->userinfo,
                             &uri->user, &uri->password, &uri->auth_params,
                             &uri->host, &uri->port,
                             &uri->path, &uri->query, &uri->fragment,
                             error))
    {
      g_uri_unref (uri);
      return NULL;
    }

  if (!uri->scheme && !base_uri)
    {
      g_set_error_literal (error, G_URI_ERROR, G_URI_ERROR_FAILED,
                           _("URI is not absolute, and no base URI was provided"));
      g_uri_unref (uri);
      return NULL;
    }

  if (base_uri)
    {
      /* This is section 5.2.2 of RFC 3986, except that we're doing
       * it in place in @uri rather than copying from R to T.
       *
       * See https://tools.ietf.org/html/rfc3986#section-5.2.2
       */
      if (uri->scheme)
        remove_dot_segments (uri->path);
      else
        {
          uri->scheme = g_strdup (base_uri->scheme);
          if (uri->host)
            remove_dot_segments (uri->path);
          else
            {
              if (!*uri->path)
                {
                  g_free (uri->path);
                  uri->path = g_strdup (base_uri->path);
                  if (!uri->query)
                    uri->query = g_strdup (base_uri->query);
                }
              else
                {
                  if (*uri->path == '/')
                    remove_dot_segments (uri->path);
                  else
                    {
                      gchar *newpath, *last;

                      last = strrchr (base_uri->path, '/');
                      if (last)
                        {
                          newpath = g_strdup_printf ("%.*s/%s",
                                                     (gint)(last - base_uri->path),
                                                     base_uri->path,
                                                     uri->path);
                        }
                      else
                        newpath = g_strdup_printf ("/%s", uri->path);

                      g_free (uri->path);
                      uri->path = g_steal_pointer (&newpath);

                      remove_dot_segments (uri->path);
                    }
                }

              uri->userinfo = g_strdup (base_uri->userinfo);
              uri->user = g_strdup (base_uri->user);
              uri->password = g_strdup (base_uri->password);
              uri->auth_params = g_strdup (base_uri->auth_params);
              uri->host = g_strdup (base_uri->host);
              uri->port = base_uri->port;
            }
        }

      /* Scheme normalization couldn't have been done earlier
       * as the relative URI may not have had a scheme */
      if (flags & G_URI_FLAGS_SCHEME_NORMALIZE)
        {
          if (should_normalize_empty_path (uri->scheme) && !*uri->path)
            {
              g_free (uri->path);
              uri->path = g_strdup ("/");
            }

          uri->port = normalize_port (uri->scheme, uri->port);
        }
    }
  else
    {
      remove_dot_segments (uri->path);
    }

  return g_steal_pointer (&uri);
}

/**
 * g_uri_resolve_relative:
 * @base_uri_string: (nullable): a string representing a base URI
 * @uri_ref: a string representing a relative or absolute URI
 * @flags: flags describing how to parse @uri_ref
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Parses @uri_ref according to @flags and, if it is a
 * [relative URI](#relative-and-absolute-uris), resolves it relative to
 * @base_uri_string. If the result is not a valid absolute URI, it will be
 * discarded, and an error returned.
 *
 * (If @base_uri_string is %NULL, this just returns @uri_ref, or
 * %NULL if @uri_ref is invalid or not absolute.)
 *
 * Return value: (transfer full): the resolved URI string,
 * or NULL on error.
 *
 * Since: 2.66
 */
gchar *
g_uri_resolve_relative (const gchar  *base_uri_string,
                        const gchar  *uri_ref,
                        GUriFlags     flags,
                        GError      **error)
{
  GUri *base_uri, *resolved_uri;
  gchar *resolved_uri_string;

  g_return_val_if_fail (uri_ref != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  flags |= G_URI_FLAGS_ENCODED;

  if (base_uri_string)
    {
      base_uri = g_uri_parse (base_uri_string, flags, error);
      if (!base_uri)
        return NULL;
    }
  else
    base_uri = NULL;

  resolved_uri = g_uri_parse_relative (base_uri, uri_ref, flags, error);
  if (base_uri)
    g_uri_unref (base_uri);
  if (!resolved_uri)
    return NULL;

  resolved_uri_string = g_uri_to_string (resolved_uri);
  g_uri_unref (resolved_uri);
  return g_steal_pointer (&resolved_uri_string);
}

/* userinfo as a whole can contain sub-delims + ":", but split-out
 * user can't contain ":" or ";", and split-out password can't contain
 * ";".
 */
#define USERINFO_ALLOWED_CHARS G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO
#define USER_ALLOWED_CHARS "!$&'()*+,="
#define PASSWORD_ALLOWED_CHARS "!$&'()*+,=:"
#define AUTH_PARAMS_ALLOWED_CHARS USERINFO_ALLOWED_CHARS
#define IP_ADDR_ALLOWED_CHARS ":"
#define HOST_ALLOWED_CHARS G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS
#define PATH_ALLOWED_CHARS G_URI_RESERVED_CHARS_ALLOWED_IN_PATH
#define QUERY_ALLOWED_CHARS G_URI_RESERVED_CHARS_ALLOWED_IN_PATH "?"
#define FRAGMENT_ALLOWED_CHARS G_URI_RESERVED_CHARS_ALLOWED_IN_PATH "?"

static gchar *
g_uri_join_internal (GUriFlags    flags,
                     const gchar *scheme,
                     gboolean     userinfo,
                     const gchar *user,
                     const gchar *password,
                     const gchar *auth_params,
                     const gchar *host,
                     gint         port,
                     const gchar *path,
                     const gchar *query,
                     const gchar *fragment)
{
  gboolean encoded = (flags & G_URI_FLAGS_ENCODED);
  GString *str;
  char *normalized_scheme = NULL;

  /* Restrictions on path prefixes. See:
   * https://tools.ietf.org/html/rfc3986#section-3
   */
  g_return_val_if_fail (path != NULL, NULL);
  g_return_val_if_fail (host == NULL || (path[0] == '\0' || path[0] == '/'), NULL);
  g_return_val_if_fail (host != NULL || (path[0] != '/' || path[1] != '/'), NULL);

  /* Arbitrarily chosen default size which should handle most average length
   * URIs. This should avoid a few reallocations of the buffer in most cases.
   * It’s 1B shorter than a power of two, since GString will add a
   * nul-terminator byte. */
  str = g_string_sized_new (127);

  if (scheme)
    {
      g_string_append (str, scheme);
      g_string_append_c (str, ':');
    }

  if (flags & G_URI_FLAGS_SCHEME_NORMALIZE && scheme && ((host && port != -1) || path[0] == '\0'))
    normalized_scheme = g_ascii_strdown (scheme, -1);

  if (host)
    {
      g_string_append (str, "//");

      if (user)
        {
          if (encoded)
            g_string_append (str, user);
          else
            {
              if (userinfo)
                g_string_append_uri_escaped (str, user, USERINFO_ALLOWED_CHARS, TRUE);
              else
                /* Encode ':' and ';' regardless of whether we have a
                 * password or auth params, since it may be parsed later
                 * under the assumption that it does.
                 */
                g_string_append_uri_escaped (str, user, USER_ALLOWED_CHARS, TRUE);
            }

          if (password)
            {
              g_string_append_c (str, ':');
              if (encoded)
                g_string_append (str, password);
              else
                g_string_append_uri_escaped (str, password,
                                             PASSWORD_ALLOWED_CHARS, TRUE);
            }

          if (auth_params)
            {
              g_string_append_c (str, ';');
              if (encoded)
                g_string_append (str, auth_params);
              else
                g_string_append_uri_escaped (str, auth_params,
                                             AUTH_PARAMS_ALLOWED_CHARS, TRUE);
            }

          g_string_append_c (str, '@');
        }

      if (strchr (host, ':') && g_hostname_is_ip_address (host))
        {
          g_string_append_c (str, '[');
          if (encoded)
            g_string_append (str, host);
          else
            g_string_append_uri_escaped (str, host, IP_ADDR_ALLOWED_CHARS, TRUE);
          g_string_append_c (str, ']');
        }
      else
        {
          if (encoded)
            g_string_append (str, host);
          else
            g_string_append_uri_escaped (str, host, HOST_ALLOWED_CHARS, TRUE);
        }

      if (port != -1 && (!normalized_scheme || normalize_port (normalized_scheme, port) != -1))
        g_string_append_printf (str, ":%d", port);
    }

  if (path[0] == '\0' && normalized_scheme && should_normalize_empty_path (normalized_scheme))
    g_string_append (str, "/");
  else if (encoded || flags & G_URI_FLAGS_ENCODED_PATH)
    g_string_append (str, path);
  else
    g_string_append_uri_escaped (str, path, PATH_ALLOWED_CHARS, TRUE);

  g_free (normalized_scheme);

  if (query)
    {
      g_string_append_c (str, '?');
      if (encoded || flags & G_URI_FLAGS_ENCODED_QUERY)
        g_string_append (str, query);
      else
        g_string_append_uri_escaped (str, query, QUERY_ALLOWED_CHARS, TRUE);
    }
  if (fragment)
    {
      g_string_append_c (str, '#');
      if (encoded || flags & G_URI_FLAGS_ENCODED_FRAGMENT)
        g_string_append (str, fragment);
      else
        g_string_append_uri_escaped (str, fragment, FRAGMENT_ALLOWED_CHARS, TRUE);
    }

  return g_string_free (str, FALSE);
}

/**
 * g_uri_join:
 * @flags: flags describing how to build the URI string
 * @scheme: (nullable): the URI scheme, or %NULL
 * @userinfo: (nullable): the userinfo component, or %NULL
 * @host: (nullable): the host component, or %NULL
 * @port: the port, or `-1`
 * @path: (not nullable): the path component
 * @query: (nullable): the query component, or %NULL
 * @fragment: (nullable): the fragment, or %NULL
 *
 * Joins the given components together according to @flags to create
 * an absolute URI string. @path may not be %NULL (though it may be the empty
 * string).
 *
 * When @host is present, @path must either be empty or begin with a slash (`/`)
 * character. When @host is not present, @path cannot begin with two slash
 * characters (`//`). See
 * [RFC 3986, section 3](https://tools.ietf.org/html/rfc3986#section-3).
 *
 * See also g_uri_join_with_user(), which allows specifying the
 * components of the ‘userinfo’ separately.
 *
 * %G_URI_FLAGS_HAS_PASSWORD and %G_URI_FLAGS_HAS_AUTH_PARAMS are ignored if set
 * in @flags.
 *
 * Return value: (not nullable) (transfer full): an absolute URI string
 *
 * Since: 2.66
 */
gchar *
g_uri_join (GUriFlags    flags,
            const gchar *scheme,
            const gchar *userinfo,
            const gchar *host,
            gint         port,
            const gchar *path,
            const gchar *query,
            const gchar *fragment)
{
  g_return_val_if_fail (port >= -1 && port <= 65535, NULL);
  g_return_val_if_fail (path != NULL, NULL);

  return g_uri_join_internal (flags,
                              scheme,
                              TRUE, userinfo, NULL, NULL,
                              host,
                              port,
                              path,
                              query,
                              fragment);
}

/**
 * g_uri_join_with_user:
 * @flags: flags describing how to build the URI string
 * @scheme: (nullable): the URI scheme, or %NULL
 * @user: (nullable): the user component of the userinfo, or %NULL
 * @password: (nullable): the password component of the userinfo, or
 *   %NULL
 * @auth_params: (nullable): the auth params of the userinfo, or
 *   %NULL
 * @host: (nullable): the host component, or %NULL
 * @port: the port, or `-1`
 * @path: (not nullable): the path component
 * @query: (nullable): the query component, or %NULL
 * @fragment: (nullable): the fragment, or %NULL
 *
 * Joins the given components together according to @flags to create
 * an absolute URI string. @path may not be %NULL (though it may be the empty
 * string).
 *
 * In contrast to g_uri_join(), this allows specifying the components
 * of the ‘userinfo’ separately. It otherwise behaves the same.
 *
 * %G_URI_FLAGS_HAS_PASSWORD and %G_URI_FLAGS_HAS_AUTH_PARAMS are ignored if set
 * in @flags.
 *
 * Return value: (not nullable) (transfer full): an absolute URI string
 *
 * Since: 2.66
 */
gchar *
g_uri_join_with_user (GUriFlags    flags,
                      const gchar *scheme,
                      const gchar *user,
                      const gchar *password,
                      const gchar *auth_params,
                      const gchar *host,
                      gint         port,
                      const gchar *path,
                      const gchar *query,
                      const gchar *fragment)
{
  g_return_val_if_fail (port >= -1 && port <= 65535, NULL);
  g_return_val_if_fail (path != NULL, NULL);

  return g_uri_join_internal (flags,
                              scheme,
                              FALSE, user, password, auth_params,
                              host,
                              port,
                              path,
                              query,
                              fragment);
}

/**
 * g_uri_build:
 * @flags: flags describing how to build the #GUri
 * @scheme: (not nullable): the URI scheme
 * @userinfo: (nullable): the userinfo component, or %NULL
 * @host: (nullable): the host component, or %NULL
 * @port: the port, or `-1`
 * @path: (not nullable): the path component
 * @query: (nullable): the query component, or %NULL
 * @fragment: (nullable): the fragment, or %NULL
 *
 * Creates a new #GUri from the given components according to @flags.
 *
 * See also g_uri_build_with_user(), which allows specifying the
 * components of the "userinfo" separately.
 *
 * Return value: (not nullable) (transfer full): a new #GUri
 *
 * Since: 2.66
 */
GUri *
g_uri_build (GUriFlags    flags,
             const gchar *scheme,
             const gchar *userinfo,
             const gchar *host,
             gint         port,
             const gchar *path,
             const gchar *query,
             const gchar *fragment)
{
  GUri *uri;

  g_return_val_if_fail (scheme != NULL, NULL);
  g_return_val_if_fail (port >= -1 && port <= 65535, NULL);
  g_return_val_if_fail (path != NULL, NULL);

  uri = g_atomic_rc_box_new0 (GUri);
  uri->flags = flags;
  uri->scheme = g_ascii_strdown (scheme, -1);
  uri->userinfo = g_strdup (userinfo);
  uri->host = g_strdup (host);
  uri->port = port;
  uri->path = g_strdup (path);
  uri->query = g_strdup (query);
  uri->fragment = g_strdup (fragment);

  return g_steal_pointer (&uri);
}

/**
 * g_uri_build_with_user:
 * @flags: flags describing how to build the #GUri
 * @scheme: (not nullable): the URI scheme
 * @user: (nullable): the user component of the userinfo, or %NULL
 * @password: (nullable): the password component of the userinfo, or %NULL
 * @auth_params: (nullable): the auth params of the userinfo, or %NULL
 * @host: (nullable): the host component, or %NULL
 * @port: the port, or `-1`
 * @path: (not nullable): the path component
 * @query: (nullable): the query component, or %NULL
 * @fragment: (nullable): the fragment, or %NULL
 *
 * Creates a new #GUri from the given components according to @flags
 * (%G_URI_FLAGS_HAS_PASSWORD is added unconditionally). The @flags must be
 * coherent with the passed values, in particular use `%`-encoded values with
 * %G_URI_FLAGS_ENCODED.
 *
 * In contrast to g_uri_build(), this allows specifying the components
 * of the ‘userinfo’ field separately. Note that @user must be non-%NULL
 * if either @password or @auth_params is non-%NULL.
 *
 * Return value: (not nullable) (transfer full): a new #GUri
 *
 * Since: 2.66
 */
GUri *
g_uri_build_with_user (GUriFlags    flags,
                       const gchar *scheme,
                       const gchar *user,
                       const gchar *password,
                       const gchar *auth_params,
                       const gchar *host,
                       gint         port,
                       const gchar *path,
                       const gchar *query,
                       const gchar *fragment)
{
  GUri *uri;
  GString *userinfo;

  g_return_val_if_fail (scheme != NULL, NULL);
  g_return_val_if_fail (password == NULL || user != NULL, NULL);
  g_return_val_if_fail (auth_params == NULL || user != NULL, NULL);
  g_return_val_if_fail (port >= -1 && port <= 65535, NULL);
  g_return_val_if_fail (path != NULL, NULL);

  uri = g_atomic_rc_box_new0 (GUri);
  uri->flags = flags | G_URI_FLAGS_HAS_PASSWORD;
  uri->scheme = g_ascii_strdown (scheme, -1);
  uri->user = g_strdup (user);
  uri->password = g_strdup (password);
  uri->auth_params = g_strdup (auth_params);
  uri->host = g_strdup (host);
  uri->port = port;
  uri->path = g_strdup (path);
  uri->query = g_strdup (query);
  uri->fragment = g_strdup (fragment);

  if (user)
    {
      userinfo = g_string_new (user);
      if (password)
        {
          g_string_append_c (userinfo, ':');
          g_string_append (userinfo, uri->password);
        }
      if (auth_params)
        {
          g_string_append_c (userinfo, ';');
          g_string_append (userinfo, uri->auth_params);
        }
      uri->userinfo = g_string_free (userinfo, FALSE);
    }

  return g_steal_pointer (&uri);
}

/**
 * g_uri_to_string:
 * @uri: a #GUri
 *
 * Returns a string representing @uri.
 *
 * This is not guaranteed to return a string which is identical to the
 * string that @uri was parsed from. However, if the source URI was
 * syntactically correct (according to RFC 3986), and it was parsed
 * with %G_URI_FLAGS_ENCODED, then g_uri_to_string() is guaranteed to return
 * a string which is at least semantically equivalent to the source
 * URI (according to RFC 3986).
 *
 * If @uri might contain sensitive details, such as authentication parameters,
 * or private data in its query string, and the returned string is going to be
 * logged, then consider using g_uri_to_string_partial() to redact parts.
 *
 * Return value: (not nullable) (transfer full): a string representing @uri,
 *     which the caller must free.
 *
 * Since: 2.66
 */
gchar *
g_uri_to_string (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return g_uri_to_string_partial (uri, G_URI_HIDE_NONE);
}

/**
 * g_uri_to_string_partial:
 * @uri: a #GUri
 * @flags: flags describing what parts of @uri to hide
 *
 * Returns a string representing @uri, subject to the options in
 * @flags. See g_uri_to_string() and #GUriHideFlags for more details.
 *
 * Return value: (not nullable) (transfer full): a string representing
 *     @uri, which the caller must free.
 *
 * Since: 2.66
 */
gchar *
g_uri_to_string_partial (GUri          *uri,
                         GUriHideFlags  flags)
{
  gboolean hide_user = (flags & G_URI_HIDE_USERINFO);
  gboolean hide_password = (flags & (G_URI_HIDE_USERINFO | G_URI_HIDE_PASSWORD));
  gboolean hide_auth_params = (flags & (G_URI_HIDE_USERINFO | G_URI_HIDE_AUTH_PARAMS));
  gboolean hide_query = (flags & G_URI_HIDE_QUERY);
  gboolean hide_fragment = (flags & G_URI_HIDE_FRAGMENT);

  g_return_val_if_fail (uri != NULL, NULL);

  if (uri->flags & (G_URI_FLAGS_HAS_PASSWORD | G_URI_FLAGS_HAS_AUTH_PARAMS))
    {
      return g_uri_join_with_user (uri->flags,
                                   uri->scheme,
                                   hide_user ? NULL : uri->user,
                                   hide_password ? NULL : uri->password,
                                   hide_auth_params ? NULL : uri->auth_params,
                                   uri->host,
                                   uri->port,
                                   uri->path,
                                   hide_query ? NULL : uri->query,
                                   hide_fragment ? NULL : uri->fragment);
    }

  return g_uri_join (uri->flags,
                     uri->scheme,
                     hide_user ? NULL : uri->userinfo,
                     uri->host,
                     uri->port,
                     uri->path,
                     hide_query ? NULL : uri->query,
                     hide_fragment ? NULL : uri->fragment);
}

/* This is just a copy of g_str_hash() with g_ascii_toupper() added */
static guint
str_ascii_case_hash (gconstpointer v)
{
  const signed char *p;
  guint32 h = 5381;

  for (p = v; *p != '\0'; p++)
    h = (h << 5) + h + g_ascii_toupper (*p);

  return h;
}

static gboolean
str_ascii_case_equal (gconstpointer v1,
                      gconstpointer v2)
{
  const gchar *string1 = v1;
  const gchar *string2 = v2;

  return g_ascii_strcasecmp (string1, string2) == 0;
}

/**
 * GUriParamsIter:
 *
 * Many URI schemes include one or more attribute/value pairs as part of the URI
 * value. For example `scheme://server/path?query=string&is=there` has two
 * attributes – `query=string` and `is=there` – in its query part.
 *
 * A #GUriParamsIter structure represents an iterator that can be used to
 * iterate over the attribute/value pairs of a URI query string. #GUriParamsIter
 * structures are typically allocated on the stack and then initialized with
 * g_uri_params_iter_init(). See the documentation for g_uri_params_iter_init()
 * for a usage example.
 *
 * Since: 2.66
 */
typedef struct
{
  GUriParamsFlags flags;
  const gchar    *attr;
  const gchar    *end;
  guint8          sep_table[256]; /* 1 = index is a separator; 0 otherwise */
} RealIter;

G_STATIC_ASSERT (sizeof (GUriParamsIter) == sizeof (RealIter));
G_STATIC_ASSERT (G_ALIGNOF (GUriParamsIter) >= G_ALIGNOF (RealIter));

/**
 * g_uri_params_iter_init:
 * @iter: an uninitialized #GUriParamsIter
 * @params: a `%`-encoded string containing `attribute=value`
 *   parameters
 * @length: the length of @params, or `-1` if it is nul-terminated
 * @separators: the separator byte character set between parameters. (usually
 *   `&`, but sometimes `;` or both `&;`). Note that this function works on
 *   bytes not characters, so it can't be used to delimit UTF-8 strings for
 *   anything but ASCII characters. You may pass an empty set, in which case
 *   no splitting will occur.
 * @flags: flags to modify the way the parameters are handled.
 *
 * Initializes an attribute/value pair iterator.
 *
 * The iterator keeps pointers to the @params and @separators arguments, those
 * variables must thus outlive the iterator and not be modified during the
 * iteration.
 *
 * If %G_URI_PARAMS_WWW_FORM is passed in @flags, `+` characters in the param
 * string will be replaced with spaces in the output. For example, `foo=bar+baz`
 * will give attribute `foo` with value `bar baz`. This is commonly used on the
 * web (the `https` and `http` schemes only), but is deprecated in favour of
 * the equivalent of encoding spaces as `%20`.
 *
 * Unlike with g_uri_parse_params(), %G_URI_PARAMS_CASE_INSENSITIVE has no
 * effect if passed to @flags for g_uri_params_iter_init(). The caller is
 * responsible for doing their own case-insensitive comparisons.
 *
 * |[<!-- language="C" -->
 * GUriParamsIter iter;
 * GError *error = NULL;
 * gchar *unowned_attr, *unowned_value;
 *
 * g_uri_params_iter_init (&iter, "foo=bar&baz=bar&Foo=frob&baz=bar2", -1, "&", G_URI_PARAMS_NONE);
 * while (g_uri_params_iter_next (&iter, &unowned_attr, &unowned_value, &error))
 *   {
 *     g_autofree gchar *attr = g_steal_pointer (&unowned_attr);
 *     g_autofree gchar *value = g_steal_pointer (&unowned_value);
 *     // do something with attr and value; this code will be called 4 times
 *     // for the params string in this example: once with attr=foo and value=bar,
 *     // then with baz/bar, then Foo/frob, then baz/bar2.
 *   }
 * if (error)
 *   // handle parsing error
 * ]|
 *
 * Since: 2.66
 */
void
g_uri_params_iter_init (GUriParamsIter *iter,
                        const gchar    *params,
                        gssize          length,
                        const gchar    *separators,
                        GUriParamsFlags flags)
{
  RealIter *ri = (RealIter *)iter;
  const gchar *s;

  g_return_if_fail (iter != NULL);
  g_return_if_fail (length == 0 || params != NULL);
  g_return_if_fail (length >= -1);
  g_return_if_fail (separators != NULL);

  ri->flags = flags;

  if (length == -1)
    ri->end = params + strlen (params);
  else
    ri->end = params + length;

  memset (ri->sep_table, FALSE, sizeof (ri->sep_table));
  for (s = separators; *s != '\0'; ++s)
    ri->sep_table[*(guchar *)s] = TRUE;

  ri->attr = params;
}

/**
 * g_uri_params_iter_next:
 * @iter: an initialized #GUriParamsIter
 * @attribute: (out) (nullable) (optional) (transfer full): on return, contains
 *     the attribute, or %NULL.
 * @value: (out) (nullable) (optional) (transfer full): on return, contains
 *     the value, or %NULL.
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Advances @iter and retrieves the next attribute/value. %FALSE is returned if
 * an error has occurred (in which case @error is set), or if the end of the
 * iteration is reached (in which case @attribute and @value are set to %NULL
 * and the iterator becomes invalid). If %TRUE is returned,
 * g_uri_params_iter_next() may be called again to receive another
 * attribute/value pair.
 *
 * Note that the same @attribute may be returned multiple times, since URIs
 * allow repeated attributes.
 *
 * Returns: %FALSE if the end of the parameters has been reached or an error was
 *     encountered. %TRUE otherwise.
 *
 * Since: 2.66
 */
gboolean
g_uri_params_iter_next (GUriParamsIter *iter,
                        gchar         **attribute,
                        gchar         **value,
                        GError        **error)
{
  RealIter *ri = (RealIter *)iter;
  const gchar *attr_end, *val, *val_end;
  gchar *decoded_attr, *decoded_value;
  gboolean www_form = ri->flags & G_URI_PARAMS_WWW_FORM;
  GUriFlags decode_flags = G_URI_FLAGS_NONE;

  g_return_val_if_fail (iter != NULL, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  /* Pre-clear these in case of failure or finishing. */
  if (attribute)
    *attribute = NULL;
  if (value)
    *value = NULL;

  if (ri->attr >= ri->end)
    return FALSE;

  if (ri->flags & G_URI_PARAMS_PARSE_RELAXED)
    decode_flags |= G_URI_FLAGS_PARSE_RELAXED;

  /* Check if each character in @attr is a separator, by indexing by the
   * character value into the @sep_table, which has value 1 stored at an
   * index if that index is a separator. */
  for (val_end = ri->attr; val_end < ri->end; val_end++)
    if (ri->sep_table[*(guchar *)val_end])
      break;

  attr_end = memchr (ri->attr, '=', val_end - ri->attr);
  if (!attr_end)
    {
      g_set_error_literal (error, G_URI_ERROR, G_URI_ERROR_FAILED,
                           _("Missing ‘=’ and parameter value"));
      return FALSE;
    }
  if (!uri_decode (&decoded_attr, NULL, ri->attr, attr_end - ri->attr,
                   www_form, decode_flags, G_URI_ERROR_FAILED, error))
    {
      return FALSE;
    }

  val = attr_end + 1;
  if (!uri_decode (&decoded_value, NULL, val, val_end - val,
                   www_form, decode_flags, G_URI_ERROR_FAILED, error))
    {
      g_free (decoded_attr);
      return FALSE;
    }

  if (attribute)
    *attribute = g_steal_pointer (&decoded_attr);
  if (value)
    *value = g_steal_pointer (&decoded_value);

  g_free (decoded_attr);
  g_free (decoded_value);

  ri->attr = val_end + 1;
  return TRUE;
}

/**
 * g_uri_parse_params:
 * @params: a `%`-encoded string containing `attribute=value`
 *   parameters
 * @length: the length of @params, or `-1` if it is nul-terminated
 * @separators: the separator byte character set between parameters. (usually
 *   `&`, but sometimes `;` or both `&;`). Note that this function works on
 *   bytes not characters, so it can't be used to delimit UTF-8 strings for
 *   anything but ASCII characters. You may pass an empty set, in which case
 *   no splitting will occur.
 * @flags: flags to modify the way the parameters are handled.
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Many URI schemes include one or more attribute/value pairs as part of the URI
 * value. This method can be used to parse them into a hash table. When an
 * attribute has multiple occurrences, the last value is the final returned
 * value. If you need to handle repeated attributes differently, use
 * #GUriParamsIter.
 *
 * The @params string is assumed to still be `%`-encoded, but the returned
 * values will be fully decoded. (Thus it is possible that the returned values
 * may contain `=` or @separators, if the value was encoded in the input.)
 * Invalid `%`-encoding is treated as with the %G_URI_FLAGS_PARSE_RELAXED
 * rules for g_uri_parse(). (However, if @params is the path or query string
 * from a #GUri that was parsed without %G_URI_FLAGS_PARSE_RELAXED and
 * %G_URI_FLAGS_ENCODED, then you already know that it does not contain any
 * invalid encoding.)
 *
 * %G_URI_PARAMS_WWW_FORM is handled as documented for g_uri_params_iter_init().
 *
 * If %G_URI_PARAMS_CASE_INSENSITIVE is passed to @flags, attributes will be
 * compared case-insensitively, so a params string `attr=123&Attr=456` will only
 * return a single attribute–value pair, `Attr=456`. Case will be preserved in
 * the returned attributes.
 *
 * If @params cannot be parsed (for example, it contains two @separators
 * characters in a row), then @error is set and %NULL is returned.
 *
 * Return value: (transfer full) (element-type utf8 utf8):
 *     A hash table of attribute/value pairs, with both names and values
 *     fully-decoded; or %NULL on error.
 *
 * Since: 2.66
 */
GHashTable *
g_uri_parse_params (const gchar     *params,
                    gssize           length,
                    const gchar     *separators,
                    GUriParamsFlags  flags,
                    GError         **error)
{
  GHashTable *hash;
  GUriParamsIter iter;
  gchar *attribute, *value;
  GError *err = NULL;

  g_return_val_if_fail (length == 0 || params != NULL, NULL);
  g_return_val_if_fail (length >= -1, NULL);
  g_return_val_if_fail (separators != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (flags & G_URI_PARAMS_CASE_INSENSITIVE)
    {
      hash = g_hash_table_new_full (str_ascii_case_hash,
                                    str_ascii_case_equal,
                                    g_free, g_free);
    }
  else
    {
      hash = g_hash_table_new_full (g_str_hash, g_str_equal,
                                    g_free, g_free);
    }

  g_uri_params_iter_init (&iter, params, length, separators, flags);

  while (g_uri_params_iter_next (&iter, &attribute, &value, &err))
    g_hash_table_insert (hash, attribute, value);

  if (err)
    {
      g_propagate_error (error, g_steal_pointer (&err));
      g_hash_table_destroy (hash);
      return NULL;
    }

  return g_steal_pointer (&hash);
}

/**
 * g_uri_get_scheme:
 * @uri: a #GUri
 *
 * Gets @uri's scheme. Note that this will always be all-lowercase,
 * regardless of the string or strings that @uri was created from.
 *
 * Return value: (not nullable): @uri's scheme.
 *
 * Since: 2.66
 */
const gchar *
g_uri_get_scheme (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->scheme;
}

/**
 * g_uri_get_userinfo:
 * @uri: a #GUri
 *
 * Gets @uri's userinfo, which may contain `%`-encoding, depending on
 * the flags with which @uri was created.
 *
 * Return value: (nullable): @uri's userinfo.
 *
 * Since: 2.66
 */
const gchar *
g_uri_get_userinfo (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->userinfo;
}

/**
 * g_uri_get_user:
 * @uri: a #GUri
 *
 * Gets the ‘username’ component of @uri's userinfo, which may contain
 * `%`-encoding, depending on the flags with which @uri was created.
 * If @uri was not created with %G_URI_FLAGS_HAS_PASSWORD or
 * %G_URI_FLAGS_HAS_AUTH_PARAMS, this is the same as g_uri_get_userinfo().
 *
 * Return value: (nullable): @uri's user.
 *
 * Since: 2.66
 */
const gchar *
g_uri_get_user (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->user;
}

/**
 * g_uri_get_password:
 * @uri: a #GUri
 *
 * Gets @uri's password, which may contain `%`-encoding, depending on
 * the flags with which @uri was created. (If @uri was not created
 * with %G_URI_FLAGS_HAS_PASSWORD then this will be %NULL.)
 *
 * Return value: (nullable): @uri's password.
 *
 * Since: 2.66
 */
const gchar *
g_uri_get_password (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->password;
}

/**
 * g_uri_get_auth_params:
 * @uri: a #GUri
 *
 * Gets @uri's authentication parameters, which may contain
 * `%`-encoding, depending on the flags with which @uri was created.
 * (If @uri was not created with %G_URI_FLAGS_HAS_AUTH_PARAMS then this will
 * be %NULL.)
 *
 * Depending on the URI scheme, g_uri_parse_params() may be useful for
 * further parsing this information.
 *
 * Return value: (nullable): @uri's authentication parameters.
 *
 * Since: 2.66
 */
const gchar *
g_uri_get_auth_params (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->auth_params;
}

/**
 * g_uri_get_host:
 * @uri: a #GUri
 *
 * Gets @uri's host. This will never have `%`-encoded characters,
 * unless it is non-UTF-8 (which can only be the case if @uri was
 * created with %G_URI_FLAGS_NON_DNS).
 *
 * If @uri contained an IPv6 address literal, this value will be just
 * that address, without the brackets around it that are necessary in
 * the string form of the URI. Note that in this case there may also
 * be a scope ID attached to the address. Eg, `fe80::1234%``em1` (or
 * `fe80::1234%``25em1` if the string is still encoded).
 *
 * Return value: (nullable): @uri's host.
 *
 * Since: 2.66
 */
const gchar *
g_uri_get_host (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->host;
}

/**
 * g_uri_get_port:
 * @uri: a #GUri
 *
 * Gets @uri's port.
 *
 * Return value: @uri's port, or `-1` if no port was specified.
 *
 * Since: 2.66
 */
gint
g_uri_get_port (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, -1);

  if (uri->port == -1 && uri->flags & G_URI_FLAGS_SCHEME_NORMALIZE)
    return g_uri_get_default_scheme_port (uri->scheme);

  return uri->port;
}

/**
 * g_uri_get_path:
 * @uri: a #GUri
 *
 * Gets @uri's path, which may contain `%`-encoding, depending on the
 * flags with which @uri was created.
 *
 * Return value: (not nullable): @uri's path.
 *
 * Since: 2.66
 */
const gchar *
g_uri_get_path (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->path;
}

/**
 * g_uri_get_query:
 * @uri: a #GUri
 *
 * Gets @uri's query, which may contain `%`-encoding, depending on the
 * flags with which @uri was created.
 *
 * For queries consisting of a series of `name=value` parameters,
 * #GUriParamsIter or g_uri_parse_params() may be useful.
 *
 * Return value: (nullable): @uri's query.
 *
 * Since: 2.66
 */
const gchar *
g_uri_get_query (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->query;
}

/**
 * g_uri_get_fragment:
 * @uri: a #GUri
 *
 * Gets @uri's fragment, which may contain `%`-encoding, depending on
 * the flags with which @uri was created.
 *
 * Return value: (nullable): @uri's fragment.
 *
 * Since: 2.66
 */
const gchar *
g_uri_get_fragment (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, NULL);

  return uri->fragment;
}


/**
 * g_uri_get_flags:
 * @uri: a #GUri
 *
 * Gets @uri's flags set upon construction.
 *
 * Return value: @uri's flags.
 *
 * Since: 2.66
 **/
GUriFlags
g_uri_get_flags (GUri *uri)
{
  g_return_val_if_fail (uri != NULL, G_URI_FLAGS_NONE);

  return uri->flags;
}

/**
 * g_uri_unescape_segment:
 * @escaped_string: (nullable): A string, may be %NULL
 * @escaped_string_end: (nullable): Pointer to end of @escaped_string,
 *   may be %NULL
 * @illegal_characters: (nullable): An optional string of illegal
 *   characters not to be allowed, may be %NULL
 *
 * Unescapes a segment of an escaped string.
 *
 * If any of the characters in @illegal_characters or the NUL
 * character appears as an escaped character in @escaped_string, then
 * that is an error and %NULL will be returned. This is useful if you
 * want to avoid for instance having a slash being expanded in an
 * escaped path element, which might confuse pathname handling.
 *
 * Note: `NUL` byte is not accepted in the output, in contrast to
 * g_uri_unescape_bytes().
 *
 * Returns: (nullable): an unescaped version of @escaped_string,
 * or %NULL on error. The returned string should be freed when no longer
 * needed.  As a special case if %NULL is given for @escaped_string, this
 * function will return %NULL.
 *
 * Since: 2.16
 **/
gchar *
g_uri_unescape_segment (const gchar *escaped_string,
                        const gchar *escaped_string_end,
                        const gchar *illegal_characters)
{
  gchar *unescaped;
  gsize length;
  gssize decoded_len;

  if (!escaped_string)
    return NULL;

  if (escaped_string_end)
    length = escaped_string_end - escaped_string;
  else
    length = strlen (escaped_string);

  decoded_len = uri_decoder (&unescaped,
                             illegal_characters,
                             escaped_string, length,
                             FALSE, FALSE,
                             G_URI_FLAGS_ENCODED,
                             0, NULL);
  if (decoded_len < 0)
    return NULL;

  if (memchr (unescaped, '\0', decoded_len))
    {
      g_free (unescaped);
      return NULL;
    }

  return unescaped;
}

/**
 * g_uri_unescape_string:
 * @escaped_string: an escaped string to be unescaped.
 * @illegal_characters: (nullable): a string of illegal characters
 *   not to be allowed, or %NULL.
 *
 * Unescapes a whole escaped string.
 *
 * If any of the characters in @illegal_characters or the NUL
 * character appears as an escaped character in @escaped_string, then
 * that is an error and %NULL will be returned. This is useful if you
 * want to avoid for instance having a slash being expanded in an
 * escaped path element, which might confuse pathname handling.
 *
 * Returns: (nullable): an unescaped version of @escaped_string.
 * The returned string should be freed when no longer needed.
 *
 * Since: 2.16
 **/
gchar *
g_uri_unescape_string (const gchar *escaped_string,
                       const gchar *illegal_characters)
{
  return g_uri_unescape_segment (escaped_string, NULL, illegal_characters);
}

/**
 * g_uri_escape_string:
 * @unescaped: the unescaped input string.
 * @reserved_chars_allowed: (nullable): a string of reserved
 *   characters that are allowed to be used, or %NULL.
 * @allow_utf8: %TRUE if the result can include UTF-8 characters.
 *
 * Escapes a string for use in a URI.
 *
 * Normally all characters that are not "unreserved" (i.e. ASCII
 * alphanumerical characters plus dash, dot, underscore and tilde) are
 * escaped. But if you specify characters in @reserved_chars_allowed
 * they are not escaped. This is useful for the "reserved" characters
 * in the URI specification, since those are allowed unescaped in some
 * portions of a URI.
 *
 * Returns: (not nullable): an escaped version of @unescaped. The
 * returned string should be freed when no longer needed.
 *
 * Since: 2.16
 **/
gchar *
g_uri_escape_string (const gchar *unescaped,
                     const gchar *reserved_chars_allowed,
                     gboolean     allow_utf8)
{
  GString *s;

  g_return_val_if_fail (unescaped != NULL, NULL);

  s = g_string_sized_new (strlen (unescaped) * 1.25);

  g_string_append_uri_escaped (s, unescaped, reserved_chars_allowed, allow_utf8);

  return g_string_free (s, FALSE);
}

/**
 * g_uri_unescape_bytes:
 * @escaped_string: A URI-escaped string
 * @length: the length (in bytes) of @escaped_string to escape, or `-1` if it
 *   is nul-terminated.
 * @illegal_characters: (nullable): a string of illegal characters
 *   not to be allowed, or %NULL.
 * @error: #GError for error reporting, or %NULL to ignore.
 *
 * Unescapes a segment of an escaped string as binary data.
 *
 * Note that in contrast to g_uri_unescape_string(), this does allow
 * nul bytes to appear in the output.
 *
 * If any of the characters in @illegal_characters appears as an escaped
 * character in @escaped_string, then that is an error and %NULL will be
 * returned. This is useful if you want to avoid for instance having a slash
 * being expanded in an escaped path element, which might confuse pathname
 * handling.
 *
 * Returns: (transfer full): an unescaped version of @escaped_string
 *     or %NULL on error (if decoding failed, using %G_URI_ERROR_FAILED error
 *     code). The returned #GBytes should be unreffed when no longer needed.
 *
 * Since: 2.66
 **/
GBytes *
g_uri_unescape_bytes (const gchar *escaped_string,
                      gssize       length,
                      const char *illegal_characters,
                      GError     **error)
{
  gchar *buf;
  gssize unescaped_length;

  g_return_val_if_fail (escaped_string != NULL, NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  if (length == -1)
    length = strlen (escaped_string);

  unescaped_length = uri_decoder (&buf,
                                  illegal_characters,
                                  escaped_string, length,
                                  FALSE,
                                  FALSE,
                                  G_URI_FLAGS_ENCODED,
                                  G_URI_ERROR_FAILED, error);
  if (unescaped_length == -1)
    return NULL;

  return g_bytes_new_take (buf, unescaped_length);
}

/**
 * g_uri_escape_bytes:
 * @unescaped: (array length=length): the unescaped input data.
 * @length: the length of @unescaped
 * @reserved_chars_allowed: (nullable): a string of reserved
 *   characters that are allowed to be used, or %NULL.
 *
 * Escapes arbitrary data for use in a URI.
 *
 * Normally all characters that are not ‘unreserved’ (i.e. ASCII
 * alphanumerical characters plus dash, dot, underscore and tilde) are
 * escaped. But if you specify characters in @reserved_chars_allowed
 * they are not escaped. This is useful for the ‘reserved’ characters
 * in the URI specification, since those are allowed unescaped in some
 * portions of a URI.
 *
 * Though technically incorrect, this will also allow escaping nul
 * bytes as `%``00`.
 *
 * Returns: (not nullable) (transfer full): an escaped version of @unescaped.
 *     The returned string should be freed when no longer needed.
 *
 * Since: 2.66
 */
gchar *
g_uri_escape_bytes (const guint8 *unescaped,
                    gsize         length,
                    const gchar  *reserved_chars_allowed)
{
  GString *string;

  g_return_val_if_fail (unescaped != NULL, NULL);

  string = g_string_sized_new (length * 1.25);

  _uri_encoder (string, unescaped, length,
               reserved_chars_allowed, FALSE);

  return g_string_free (string, FALSE);
}

static gssize
g_uri_scheme_length (const gchar *uri)
{
  const gchar *p;

  p = uri;
  if (!g_ascii_isalpha (*p))
    return -1;
  p++;
  while (g_ascii_isalnum (*p) || *p == '.' || *p == '+' || *p == '-')
    p++;

  if (p > uri && *p == ':')
    return p - uri;

  return -1;
}

/**
 * g_uri_parse_scheme:
 * @uri: a valid URI.
 *
 * Gets the scheme portion of a URI string.
 * [RFC 3986](https://tools.ietf.org/html/rfc3986#section-3) decodes the scheme
 * as:
 * |[
 * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
 * ]|
 * Common schemes include `file`, `https`, `svn+ssh`, etc.
 *
 * Returns: (transfer full) (nullable): The ‘scheme’ component of the URI, or
 *     %NULL on error. The returned string should be freed when no longer needed.
 *
 * Since: 2.16
 **/
gchar *
g_uri_parse_scheme (const gchar *uri)
{
  gssize len;

  g_return_val_if_fail (uri != NULL, NULL);

  len = g_uri_scheme_length (uri);
  return len == -1 ? NULL : g_strndup (uri, len);
}

/**
 * g_uri_peek_scheme:
 * @uri: a valid URI.
 *
 * Gets the scheme portion of a URI string.
 * [RFC 3986](https://tools.ietf.org/html/rfc3986#section-3) decodes the scheme
 * as:
 * |[
 * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
 * ]|
 * Common schemes include `file`, `https`, `svn+ssh`, etc.
 *
 * Unlike g_uri_parse_scheme(), the returned scheme is normalized to
 * all-lowercase and does not need to be freed.
 *
 * Returns: (transfer none) (nullable): The ‘scheme’ component of the URI, or
 *     %NULL on error. The returned string is normalized to all-lowercase, and
 *     interned via g_intern_string(), so it does not need to be freed.
 *
 * Since: 2.66
 **/
const gchar *
g_uri_peek_scheme (const gchar *uri)
{
  gssize len;
  gchar *lower_scheme;
  const gchar *scheme;

  g_return_val_if_fail (uri != NULL, NULL);

  len = g_uri_scheme_length (uri);
  if (len == -1)
    return NULL;

  lower_scheme = g_ascii_strdown (uri, len);
  scheme = g_intern_string (lower_scheme);
  g_free (lower_scheme);

  return scheme;
}

G_DEFINE_QUARK (g-uri-quark, g_uri_error)
