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>
|
2003-10-23 Hrvoje Niksic <hniksic@xemacs.org>
|
||||||
|
|
||||||
* config.h.in: Deploy preprocessor magic to avoid Ultrix's
|
* 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);
|
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.
|
/* Construct and return a link that points from BASEFILE to LINKFILE.
|
||||||
Both files should be local file names, S1 of the referrering file,
|
Both files should be local file names, BASEFILE of the referrering
|
||||||
and S2 of the referred file.
|
file, and LINKFILE of the referred file.
|
||||||
|
|
||||||
So, if S1 is "H/index.html" and S2 is "H/images/news.gif", this
|
Examples:
|
||||||
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".
|
|
||||||
|
|
||||||
Caveats: S1 should not begin with `/', unless S2 also begins with
|
cr("foo", "bar") -> "bar"
|
||||||
'/'. S1 should not contain things like ".." and such --
|
cr("A/foo", "A/bar") -> "bar"
|
||||||
construct_relative ("fly/ioccc/../index.html",
|
cr("A/foo", "A/B/bar") -> "B/bar"
|
||||||
"fly/images/fly.gif") will fail. (A workaround is to call
|
cr("A/X/foo", "A/Y/bar") -> "../Y/bar"
|
||||||
something like path_simplify() on S1). */
|
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 *
|
static char *
|
||||||
construct_relative (const char *s1, const char *s2)
|
construct_relative (const char *basefile, const char *linkfile)
|
||||||
{
|
{
|
||||||
int i, cnt, sepdirs1;
|
char *link;
|
||||||
char *res;
|
int basedirs;
|
||||||
|
const char *b, *l;
|
||||||
|
int i, start;
|
||||||
|
|
||||||
i = cnt = 0;
|
/* First, skip the initial directory components common to both
|
||||||
/* Skip the directories common to both strings. */
|
files. */
|
||||||
while (1)
|
start = 0;
|
||||||
|
for (b = basefile, l = linkfile; *b == *l && *b != '\0'; ++b, ++l)
|
||||||
{
|
{
|
||||||
while (s1[i] && s2[i]
|
if (*b == '/')
|
||||||
&& (s1[i] == s2[i])
|
start = (b - basefile) + 1;
|
||||||
&& (s1[i] != '/')
|
|
||||||
&& (s2[i] != '/'))
|
|
||||||
++i;
|
|
||||||
if (s1[i] == '/' && s2[i] == '/')
|
|
||||||
cnt = ++i;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
for (sepdirs1 = 0; s1[i]; i++)
|
basefile += start;
|
||||||
if (s1[i] == '/')
|
linkfile += start;
|
||||||
++sepdirs1;
|
|
||||||
/* Now, construct the file as of:
|
/* With common directories out of the way, the situation we have is
|
||||||
- ../ repeated sepdirs1 time
|
as follows:
|
||||||
- all the non-mutual directories of S2. */
|
b - b1/b2/[...]/bfile
|
||||||
res = (char *)xmalloc (3 * sepdirs1 + strlen (s2 + cnt) + 1);
|
l - l1/l2/[...]/lfile
|
||||||
for (i = 0; i < sepdirs1; i++)
|
|
||||||
memcpy (res + 3 * i, "../", 3);
|
The link we're constructing needs to be:
|
||||||
strcpy (res + 3 * i, s2 + cnt);
|
lnk - ../../l1/l2/[...]/lfile
|
||||||
return res;
|
|
||||||
|
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
|
static void
|
||||||
|
165
src/url.c
165
src/url.c
@ -641,48 +641,52 @@ static char *parse_errors[] = {
|
|||||||
static int
|
static int
|
||||||
is_valid_ipv4_address (const char *str, const char *end)
|
is_valid_ipv4_address (const char *str, const char *end)
|
||||||
{
|
{
|
||||||
int saw_digit, octets;
|
int saw_digit = 0;
|
||||||
int val;
|
int octets = 0;
|
||||||
|
int val = 0;
|
||||||
|
|
||||||
saw_digit = 0;
|
while (str < end)
|
||||||
octets = 0;
|
{
|
||||||
val = 0;
|
int ch = *str++;
|
||||||
|
|
||||||
while (str < end) {
|
if (ch >= '0' && ch <= '9')
|
||||||
int ch = *str++;
|
{
|
||||||
|
val = val * 10 + (ch - '0');
|
||||||
|
|
||||||
if (ch >= '0' && ch <= '9') {
|
if (val > 255)
|
||||||
val = val * 10 + (ch - '0');
|
return 0;
|
||||||
|
if (saw_digit == 0)
|
||||||
if (val > 255)
|
{
|
||||||
return 0;
|
if (++octets > 4)
|
||||||
if (saw_digit == 0) {
|
return 0;
|
||||||
if (++octets > 4)
|
saw_digit = 1;
|
||||||
return 0;
|
}
|
||||||
saw_digit = 1;
|
}
|
||||||
}
|
else if (ch == '.' && saw_digit == 1)
|
||||||
} else if (ch == '.' && saw_digit == 1) {
|
{
|
||||||
if (octets == 4)
|
if (octets == 4)
|
||||||
return 0;
|
return 0;
|
||||||
val = 0;
|
val = 0;
|
||||||
saw_digit = 0;
|
saw_digit = 0;
|
||||||
} else
|
}
|
||||||
return 0;
|
else
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
if (octets < 4)
|
if (octets < 4)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int NS_INADDRSZ = 4;
|
|
||||||
static const int NS_IN6ADDRSZ = 16;
|
|
||||||
static const int NS_INT16SZ = 2;
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
is_valid_ipv6_address (const char *str, const char *end)
|
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;
|
const char *curtok;
|
||||||
int tp;
|
int tp;
|
||||||
const char *colonp;
|
const char *colonp;
|
||||||
@ -707,62 +711,67 @@ is_valid_ipv6_address (const char *str, const char *end)
|
|||||||
saw_xdigit = 0;
|
saw_xdigit = 0;
|
||||||
val = 0;
|
val = 0;
|
||||||
|
|
||||||
while (str < end) {
|
while (str < end)
|
||||||
int ch = *str++;
|
{
|
||||||
const char *pch;
|
int ch = *str++;
|
||||||
|
|
||||||
/* if ch is a number, add it to val. */
|
/* if ch is a number, add it to val. */
|
||||||
pch = strchr(xdigits, ch);
|
if (ISXDIGIT (ch))
|
||||||
if (pch != NULL) {
|
{
|
||||||
val <<= 4;
|
val <<= 4;
|
||||||
val |= (pch - xdigits);
|
val |= XDIGIT_TO_NUM (ch);
|
||||||
if (val > 0xffff)
|
if (val > 0xffff)
|
||||||
return 0;
|
return 0;
|
||||||
saw_xdigit = 1;
|
saw_xdigit = 1;
|
||||||
continue;
|
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 (saw_xdigit == 1)
|
||||||
if (ch == ':') {
|
{
|
||||||
curtok = str;
|
if (tp > NS_IN6ADDRSZ - NS_INT16SZ)
|
||||||
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;
|
return 0;
|
||||||
tp += NS_INT16SZ;
|
tp += NS_INT16SZ;
|
||||||
saw_xdigit = 0;
|
|
||||||
val = 0;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if ch is a dot ... */
|
if (colonp != NULL)
|
||||||
if (ch == '.' && (tp <= NS_IN6ADDRSZ - NS_INADDRSZ) &&
|
{
|
||||||
is_valid_ipv4_address(curtok, end) == 1) {
|
if (tp == NS_IN6ADDRSZ)
|
||||||
tp += NS_INADDRSZ;
|
return 0;
|
||||||
saw_xdigit = 0;
|
tp = NS_IN6ADDRSZ;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
if (tp != NS_IN6ADDRSZ)
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user