mirror of
https://github.com/rkd77/elinks.git
synced 2025-01-03 14:57:44 -05:00
119 lines
2.6 KiB
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;
|
|
}
|