mirror of
https://github.com/moparisthebest/wget
synced 2024-07-03 16:38:41 -04:00
[svn] Better document the workings of construct_relative().
Reformat is_valid_ipv6_address() to GNU formatting style.
This commit is contained in:
parent
cf01276391
commit
27d5becdaf
@ -1,3 +1,11 @@
|
||||
2003-10-25 Hrvoje Niksic <hniksic@xemacs.org>
|
||||
|
||||
* url.c (is_valid_ipv6_address): Reformat to GNU coding style.
|
||||
Use enums for NS_IN* constants. Use ISXDIGIT.
|
||||
|
||||
* convert.c (construct_relative): Document better how the function
|
||||
works.
|
||||
|
||||
2003-10-23 Hrvoje Niksic <hniksic@xemacs.org>
|
||||
|
||||
* config.h.in: Deploy preprocessor magic to avoid Ultrix's
|
||||
|
@ -327,52 +327,67 @@ convert_links (const char *file, struct urlpos *links)
|
||||
logprintf (LOG_VERBOSE, "%d-%d\n", to_file_count, to_url_count);
|
||||
}
|
||||
|
||||
/* Construct and return a link that points from S1's position to S2.
|
||||
Both files should be local file names, S1 of the referrering file,
|
||||
and S2 of the referred file.
|
||||
/* Construct and return a link that points from BASEFILE to LINKFILE.
|
||||
Both files should be local file names, BASEFILE of the referrering
|
||||
file, and LINKFILE of the referred file.
|
||||
|
||||
So, if S1 is "H/index.html" and S2 is "H/images/news.gif", this
|
||||
function will return "images/news.gif". On the other hand, if S1
|
||||
is "H/ioccc/index.html", and S2 is "H/images/fly.gif", it will
|
||||
return "../images/fly.gif".
|
||||
Examples:
|
||||
|
||||
Caveats: S1 should not begin with `/', unless S2 also begins with
|
||||
'/'. S1 should not contain things like ".." and such --
|
||||
construct_relative ("fly/ioccc/../index.html",
|
||||
"fly/images/fly.gif") will fail. (A workaround is to call
|
||||
something like path_simplify() on S1). */
|
||||
cr("foo", "bar") -> "bar"
|
||||
cr("A/foo", "A/bar") -> "bar"
|
||||
cr("A/foo", "A/B/bar") -> "B/bar"
|
||||
cr("A/X/foo", "A/Y/bar") -> "../Y/bar"
|
||||
cr("X/", "Y/bar") -> "../Y/bar" (trailing slash does matter in BASE)
|
||||
|
||||
Both files should be absolute or relative, otherwise strange
|
||||
results might ensue. The function makes no special efforts to
|
||||
handle "." and ".." in links, so make sure they're not there
|
||||
(e.g. using path_simplify). */
|
||||
|
||||
static char *
|
||||
construct_relative (const char *s1, const char *s2)
|
||||
construct_relative (const char *basefile, const char *linkfile)
|
||||
{
|
||||
int i, cnt, sepdirs1;
|
||||
char *res;
|
||||
char *link;
|
||||
int basedirs;
|
||||
const char *b, *l;
|
||||
int i, start;
|
||||
|
||||
i = cnt = 0;
|
||||
/* Skip the directories common to both strings. */
|
||||
while (1)
|
||||
/* First, skip the initial directory components common to both
|
||||
files. */
|
||||
start = 0;
|
||||
for (b = basefile, l = linkfile; *b == *l && *b != '\0'; ++b, ++l)
|
||||
{
|
||||
while (s1[i] && s2[i]
|
||||
&& (s1[i] == s2[i])
|
||||
&& (s1[i] != '/')
|
||||
&& (s2[i] != '/'))
|
||||
++i;
|
||||
if (s1[i] == '/' && s2[i] == '/')
|
||||
cnt = ++i;
|
||||
else
|
||||
break;
|
||||
if (*b == '/')
|
||||
start = (b - basefile) + 1;
|
||||
}
|
||||
for (sepdirs1 = 0; s1[i]; i++)
|
||||
if (s1[i] == '/')
|
||||
++sepdirs1;
|
||||
/* Now, construct the file as of:
|
||||
- ../ repeated sepdirs1 time
|
||||
- all the non-mutual directories of S2. */
|
||||
res = (char *)xmalloc (3 * sepdirs1 + strlen (s2 + cnt) + 1);
|
||||
for (i = 0; i < sepdirs1; i++)
|
||||
memcpy (res + 3 * i, "../", 3);
|
||||
strcpy (res + 3 * i, s2 + cnt);
|
||||
return res;
|
||||
basefile += start;
|
||||
linkfile += start;
|
||||
|
||||
/* With common directories out of the way, the situation we have is
|
||||
as follows:
|
||||
b - b1/b2/[...]/bfile
|
||||
l - l1/l2/[...]/lfile
|
||||
|
||||
The link we're constructing needs to be:
|
||||
lnk - ../../l1/l2/[...]/lfile
|
||||
|
||||
Where the number of ".."'s equals the number of bN directory
|
||||
components in B. */
|
||||
|
||||
/* Count the directory components in B. */
|
||||
basedirs = 0;
|
||||
for (b = basefile; *b; b++)
|
||||
{
|
||||
if (*b == '/')
|
||||
++basedirs;
|
||||
}
|
||||
|
||||
/* Construct LINK as explained above. */
|
||||
link = (char *)xmalloc (3 * basedirs + strlen (linkfile) + 1);
|
||||
for (i = 0; i < basedirs; i++)
|
||||
memcpy (link + 3 * i, "../", 3);
|
||||
strcpy (link + 3 * i, linkfile);
|
||||
return link;
|
||||
}
|
||||
|
||||
static void
|
||||
|
165
src/url.c
165
src/url.c
@ -641,48 +641,52 @@ static char *parse_errors[] = {
|
||||
static int
|
||||
is_valid_ipv4_address (const char *str, const char *end)
|
||||
{
|
||||
int saw_digit, octets;
|
||||
int val;
|
||||
int saw_digit = 0;
|
||||
int octets = 0;
|
||||
int val = 0;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
val = 0;
|
||||
while (str < end)
|
||||
{
|
||||
int ch = *str++;
|
||||
|
||||
while (str < end) {
|
||||
int ch = *str++;
|
||||
if (ch >= '0' && ch <= '9')
|
||||
{
|
||||
val = val * 10 + (ch - '0');
|
||||
|
||||
if (ch >= '0' && ch <= '9') {
|
||||
val = val * 10 + (ch - '0');
|
||||
|
||||
if (val > 255)
|
||||
return 0;
|
||||
if (saw_digit == 0) {
|
||||
if (++octets > 4)
|
||||
return 0;
|
||||
saw_digit = 1;
|
||||
}
|
||||
} else if (ch == '.' && saw_digit == 1) {
|
||||
if (octets == 4)
|
||||
return 0;
|
||||
val = 0;
|
||||
saw_digit = 0;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
if (val > 255)
|
||||
return 0;
|
||||
if (saw_digit == 0)
|
||||
{
|
||||
if (++octets > 4)
|
||||
return 0;
|
||||
saw_digit = 1;
|
||||
}
|
||||
}
|
||||
else if (ch == '.' && saw_digit == 1)
|
||||
{
|
||||
if (octets == 4)
|
||||
return 0;
|
||||
val = 0;
|
||||
saw_digit = 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
if (octets < 4)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const int NS_INADDRSZ = 4;
|
||||
static const int NS_IN6ADDRSZ = 16;
|
||||
static const int NS_INT16SZ = 2;
|
||||
|
||||
static int
|
||||
is_valid_ipv6_address (const char *str, const char *end)
|
||||
{
|
||||
static const char xdigits[] = "0123456789abcdef";
|
||||
enum {
|
||||
NS_INADDRSZ = 4,
|
||||
NS_IN6ADDRSZ = 16,
|
||||
NS_INT16SZ = 2
|
||||
};
|
||||
|
||||
const char *curtok;
|
||||
int tp;
|
||||
const char *colonp;
|
||||
@ -707,62 +711,67 @@ is_valid_ipv6_address (const char *str, const char *end)
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
|
||||
while (str < end) {
|
||||
int ch = *str++;
|
||||
const char *pch;
|
||||
while (str < end)
|
||||
{
|
||||
int ch = *str++;
|
||||
|
||||
/* if ch is a number, add it to val. */
|
||||
pch = strchr(xdigits, ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (val > 0xffff)
|
||||
return 0;
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
/* if ch is a number, add it to val. */
|
||||
if (ISXDIGIT (ch))
|
||||
{
|
||||
val <<= 4;
|
||||
val |= XDIGIT_TO_NUM (ch);
|
||||
if (val > 0xffff)
|
||||
return 0;
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if ch is a colon ... */
|
||||
if (ch == ':')
|
||||
{
|
||||
curtok = str;
|
||||
if (saw_xdigit == 0)
|
||||
{
|
||||
if (colonp != NULL)
|
||||
return 0;
|
||||
colonp = str + tp;
|
||||
continue;
|
||||
}
|
||||
else if (str == end)
|
||||
return 0;
|
||||
if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
|
||||
return 0;
|
||||
tp += NS_INT16SZ;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if ch is a dot ... */
|
||||
if (ch == '.' && (tp <= NS_IN6ADDRSZ - NS_INADDRSZ)
|
||||
&& is_valid_ipv4_address (curtok, end) == 1)
|
||||
{
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* if ch is a colon ... */
|
||||
if (ch == ':') {
|
||||
curtok = str;
|
||||
if (saw_xdigit == 0) {
|
||||
if (colonp != NULL)
|
||||
return 0;
|
||||
colonp = str + tp;
|
||||
continue;
|
||||
} else if (str == end) {
|
||||
return 0;
|
||||
}
|
||||
if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
|
||||
if (saw_xdigit == 1)
|
||||
{
|
||||
if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
|
||||
return 0;
|
||||
tp += NS_INT16SZ;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if ch is a dot ... */
|
||||
if (ch == '.' && (tp <= NS_IN6ADDRSZ - NS_INADDRSZ) &&
|
||||
is_valid_ipv4_address(curtok, end) == 1) {
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break;
|
||||
if (colonp != NULL)
|
||||
{
|
||||
if (tp == NS_IN6ADDRSZ)
|
||||
return 0;
|
||||
tp = NS_IN6ADDRSZ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (saw_xdigit == 1) {
|
||||
if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
|
||||
return 0;
|
||||
tp += NS_INT16SZ;
|
||||
}
|
||||
|
||||
if (colonp != NULL) {
|
||||
if (tp == NS_IN6ADDRSZ)
|
||||
return 0;
|
||||
tp = NS_IN6ADDRSZ;
|
||||
}
|
||||
|
||||
if (tp != NS_IN6ADDRSZ)
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user