1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-09-27 02:56:18 -04:00
elinks/src/document/html/parse-meta-refresh.c

119 lines
2.6 KiB
C

/* Parse <meta http-equiv="refresh" content="..."> */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <errno.h>
#include <stdlib.h>
#include "elinks.h"
#include "document/html/parse-meta-refresh.h"
#include "osdep/ascii.h"
#include "util/string.h"
#define LWS(c) ((c) == ' ' || (c) == ASCII_TAB)
int
html_parse_meta_refresh(const char *content,
unsigned long *delay_out,
char **url_out)
{
const char *scan = content;
char *delay_end;
int saw_delay = 0;
const char *url_begin;
const char *url_end;
*url_out = NULL;
*delay_out = 0;
while (LWS(*scan))
++scan;
/* TODO: Do we need to switch to the "C" locale and back? */
*delay_out = strtoul(scan, &delay_end, 10);
saw_delay = (scan != (const char *) delay_end);
scan = (const char *) delay_end;
if (saw_delay) {
/* Omit any fractional part. */
if (*scan == '.') {
++scan;
while (!(*scan == '\0' || LWS(*scan)
|| *scan == ';' || *scan == ','))
++scan;
}
if (!(*scan == '\0' || LWS(*scan)
|| *scan == ';' || *scan == ',')) {
/* The delay is followed by garbage. Give up. */
return -1;
}
/* Between the delay and the URL, there must be at
* least one LWS, semicolon, or comma; optionally with
* more LWS around it. */
while (LWS(*scan))
++scan;
if (*scan == ';' || *scan == ',')
++scan;
} else {
/* The delay was not specified. The delimiter must be
* a semicolon or a comma, optionally with LWS. LWS
* alone does not suffice. */
while (*scan != '\0' && *scan != ';' && *scan != ',')
++scan;
if (*scan == ';' || *scan == ',')
++scan;
}
while (LWS(*scan))
++scan;
/* Presume the URL begins here... */
url_begin = scan;
/* ..unless there is "URL=" with at least one equals sign,
* and optional spaces. */
if ((scan[0] == 'U' || scan[0] == 'u')
&& (scan[1] == 'R' || scan[1] == 'r')
&& (scan[2] == 'L' || scan[2] == 'l')) {
scan += 3;
while (LWS(*scan))
++scan;
if (*scan == '=') {
++scan;
while (LWS(*scan))
++scan;
url_begin = scan;
}
}
if (*url_begin == '"' || *url_begin == '\'') {
unsigned char quote = *url_begin++;
url_end = strchr(url_begin, quote);
if (url_end == NULL)
url_end = strchr(url_begin, '\0');
} else {
url_end = strchr(url_begin, '\0');
}
/* In any case, trim all spaces from the end of the URL. */
while (url_begin < url_end && LWS(url_end[-1]))
--url_end;
if (url_begin != url_end) {
*url_out = memacpy(url_begin, url_end - url_begin);
if (!*url_out)
return -1;
} else if (!saw_delay) {
/* There is no delay and no URL. */
return -1;
}
return 0;
}