commit - 92e07b23c3cad37a92a7888b062064996891b1a3
commit + a165601e7e2641edcf7b36be8ce9c03ab281fd99
blob - f2687041ed034ffc3566a0168819e0ec26fc5c1c
blob + a95449659fd9a1b6d311f3ae106dd7544d79d1df
--- iri.c
+++ iri.c
if (cpstr(s, t, iri->iri_query, sizeof(iri->iri_query)) == -1)
return (NULL);
iri->iri_flags |= IH_QUERY;
+ return (t);
+}
+
+static const char *
+parse_fragment(const char *s, struct iri *iri)
+{
+ const char *n, *t = s;
+
+ for (;;) {
+ if ((n = advance_pchar(t)) != NULL)
+ t = n;
+ else if (*t == '/' || *t == '?')
+ t++;
+ else
+ break;
+ }
+
+ if (cpstr(s, t, iri->iri_fragment, sizeof(iri->iri_fragment)) == -1)
+ return (NULL);
+ iri->iri_flags |= IH_FRAGMENT;
return (t);
}
if (*s == '?' && (s = parse_query(s + 1, iri)) == NULL)
return (-1);
- /* skip fragments */
- if (*s == '#' || *s == '\0')
+ if (*s == '#' && (s = parse_fragment(s + 1, iri)) == NULL)
+ return (-1);
+
+ if (*s == '\0')
return (0);
return (-1);
if (*s == '?' && (s = parse_query(s + 1, iri)) == NULL)
return (-1);
- /* skip fragments */
- if (*s == '#' || *s == '\0')
+ if (*s == '#' && (s = parse_fragment(s + 1, iri)) == NULL)
+ return (-1);
+
+ if (*s == '\0')
return (0);
return (-1);
dest->iri_flags |= IH_QUERY;
memcpy(dest->iri_query, src->iri_query,
sizeof(dest->iri_query));
+ }
+ }
+ if (flags & IH_FRAGMENT) {
+ if (src->iri_flags & IH_FRAGMENT) {
+ dest->iri_flags |= IH_FRAGMENT;
+ memcpy(dest->iri_fragment, src->iri_fragment,
+ sizeof(dest->iri_fragment));
}
}
}
}
}
+ cpfields(iri, &iparsed, IH_FRAGMENT);
+
if (iparsed.iri_flags & IH_SCHEME) {
cpfields(iri, &iparsed, iparsed.iri_flags);
remove_dot_segments(iri);
return (0);
}
- /* if fragments are supported, copy iparsed fragment to iri */
-
cpfields(iri, &ibase, IH_SCHEME);
if (iparsed.iri_flags & IH_HOST) {
goto err;
}
+ if (i->iri_flags & IH_FRAGMENT) {
+ if (strlcat(buf, "#", buflen) >= buflen ||
+ strlcat(buf, i->iri_fragment, buflen) >= buflen)
+ goto err;
+ }
+
return (0);
err:
blob - 385c9423629d58a2d8807928a7bda8e6446c0418
blob + dcb6c2151e2bbfe69ffb5925c192635f8033696b
--- iri.h
+++ iri.h
uint16_t iri_port;
char iri_path[1024];
char iri_query[1024];
+ char iri_fragment[1024];
#define IH_SCHEME 0x01
#define IH_UINFO 0x02
#define IH_AUTHORITY (IH_UINFO|IH_HOST|IH_PORT)
#define IH_PATH 0x10
#define IH_QUERY 0x20
+#define IH_FRAGMENT 0x40
int iri_flags;
};
blob - 9904d91b3d90115ac086109bb8a049244509e0c5
blob + 85308278a62e6b91bb85a43a889150d3034ffc35
--- test/iritest.c
+++ test/iritest.c
ret |= check(base, "?y", "http://a/b/c/d;p?y");
ret |= check(base, "g?y", "http://a/b/c/g?y");
-// ret |= check(base, "#s", "http://a/b/c/d;p?q#s");
-// ret |= check(base, "g#s", "http://a/b/c/g#s");
-// ret |= check(base, "g?y#s", "http://a/b/c/g?y#s");
+ ret |= check(base, "#s", "http://a/b/c/d;p?q#s");
+ ret |= check(base, "g#s", "http://a/b/c/g#s");
+ ret |= check(base, "g?y#s", "http://a/b/c/g?y#s");
ret |= check(base, ";x", "http://a/b/c/;x");
ret |= check(base, "g;x", "http://a/b/c/g;x");
-// ret |= check(base, "g;x?y#s", "http://a/b/c/g;x?y#s");
+ ret |= check(base, "g;x?y#s", "http://a/b/c/g;x?y#s");
ret |= check(base, "", "http://a/b/c/d;p?q");
ret |= check(base, ".", "http://a/b/c/");
ret |= check(base, "./", "http://a/b/c/");
ret |= check(base, "g?y/./x", "http://a/b/c/g?y/./x");
ret |= check(base, "g?y/../x", "http://a/b/c/g?y/../x");
-// ret |= check(base, "g#s/./x", "http://a/b/c/g#s/./x");
-// ret |= check(base, "g#s/../x", "http://a/b/c/g#s/../x");
+ ret |= check(base, "g#s/./x", "http://a/b/c/g#s/./x");
+ ret |= check(base, "g#s/../x", "http://a/b/c/g#s/../x");
ret |= check(base, "http:g", "http:g");