672 lines
16 KiB
C
672 lines
16 KiB
C
#if defined(ENABLE_WWW)
|
|
|
|
#include <stdlib.h>
|
|
#include "www_tree.h"
|
|
#include "bbs.h"
|
|
|
|
static char *www_tag_sanatize(char *data, int isdata) {
|
|
stralloc str = EMPTY_STRALLOC;
|
|
for (char *p = data; *p != '\0'; ++p) {
|
|
switch (*p) {
|
|
case '&':
|
|
stralloc_cats(&str, "&");
|
|
break;
|
|
case '<':
|
|
stralloc_cats(&str, "<");
|
|
break;
|
|
case '>':
|
|
stralloc_cats(&str, ">");
|
|
break;
|
|
case '\x01':
|
|
stralloc_cats(&str, "☺");
|
|
break;
|
|
case '\x02':
|
|
stralloc_cats(&str, "☻");
|
|
break;
|
|
case '\x03':
|
|
stralloc_cats(&str, "♥");
|
|
break;
|
|
case '\x04':
|
|
stralloc_cats(&str, "♦");
|
|
break;
|
|
case '\x05':
|
|
stralloc_cats(&str, "♣");
|
|
break;
|
|
case '\x06':
|
|
stralloc_cats(&str, "♠");
|
|
break;
|
|
case '\x07':
|
|
stralloc_cats(&str, "•");
|
|
break;
|
|
case '\x08':
|
|
stralloc_cats(&str, "◘");
|
|
break;
|
|
case '\x09':
|
|
stralloc_cats(&str, "○");
|
|
break;
|
|
case '\x0b':
|
|
stralloc_cats(&str, "♂");
|
|
break;
|
|
case '\x0c':
|
|
stralloc_cats(&str, "♀");
|
|
break;
|
|
case '\x0e':
|
|
stralloc_cats(&str, "♫");
|
|
break;
|
|
case '\x0f':
|
|
stralloc_cats(&str, "☼");
|
|
break;
|
|
case '\x10':
|
|
stralloc_cats(&str, "▸");
|
|
break;
|
|
case '\x11':
|
|
stralloc_cats(&str, "◂");
|
|
break;
|
|
case '\x12':
|
|
stralloc_cats(&str, "↕");
|
|
break;
|
|
case '\x13':
|
|
stralloc_cats(&str, "‼");
|
|
break;
|
|
case '\x14':
|
|
stralloc_cats(&str, "¶");
|
|
break;
|
|
case '\x15':
|
|
stralloc_cats(&str, "§");
|
|
break;
|
|
case '\x16':
|
|
stralloc_cats(&str, "▬");
|
|
break;
|
|
case '\x17':
|
|
stralloc_cats(&str, "↨");
|
|
break;
|
|
case '\x18':
|
|
stralloc_cats(&str, "↑");
|
|
break;
|
|
case '\x19':
|
|
stralloc_cats(&str, "↓");
|
|
break;
|
|
case '\x1a':
|
|
stralloc_cats(&str, "→");
|
|
break;
|
|
case '\x1b':
|
|
stralloc_cats(&str, "←");
|
|
break;
|
|
case '\x1c':
|
|
stralloc_cats(&str, "∟");
|
|
break;
|
|
case '\x1d':
|
|
stralloc_cats(&str, "↔");
|
|
break;
|
|
case '\x1e':
|
|
stralloc_cats(&str, "▴");
|
|
break;
|
|
case '\x1f':
|
|
stralloc_cats(&str, "▾");
|
|
break;
|
|
/*
|
|
case '\x21':
|
|
stralloc_cats(&str, "!");
|
|
break;
|
|
case '\x22':
|
|
stralloc_cats(&str, """);
|
|
break;
|
|
case '\x24':
|
|
stralloc_cats(&str, "$");
|
|
break;
|
|
case '\x25':
|
|
stralloc_cats(&str, "%");
|
|
break;
|
|
case '\x27':
|
|
stralloc_cats(&str, "'");
|
|
break;
|
|
case '\x28':
|
|
stralloc_cats(&str, "(");
|
|
break;
|
|
case '\x29':
|
|
stralloc_cats(&str, ")");
|
|
break;
|
|
case '\x2a':
|
|
stralloc_cats(&str, "*");
|
|
break;
|
|
case '\x2b':
|
|
stralloc_cats(&str, "+");
|
|
break;
|
|
case '\x2c':
|
|
stralloc_cats(&str, ",");
|
|
break;
|
|
*/
|
|
case '\x7f':
|
|
stralloc_cats(&str, "⌂");
|
|
break;
|
|
case '\x80':
|
|
stralloc_cats(&str, "Ç");
|
|
break;
|
|
case '\x81':
|
|
stralloc_cats(&str, "ü");
|
|
break;
|
|
case '\x82':
|
|
stralloc_cats(&str, "é");
|
|
break;
|
|
case '\x83':
|
|
stralloc_cats(&str, "â");
|
|
break;
|
|
case '\x84':
|
|
stralloc_cats(&str, "ä");
|
|
break;
|
|
case '\x85':
|
|
stralloc_cats(&str, "à");
|
|
break;
|
|
case '\x86':
|
|
stralloc_cats(&str, "å");
|
|
break;
|
|
case '\x87':
|
|
stralloc_cats(&str, "ç");
|
|
break;
|
|
case '\x88':
|
|
stralloc_cats(&str, "ê");
|
|
break;
|
|
case '\x89':
|
|
stralloc_cats(&str, "ë");
|
|
break;
|
|
case '\x8a':
|
|
stralloc_cats(&str, "è");
|
|
break;
|
|
case '\x8b':
|
|
stralloc_cats(&str, "ï");
|
|
break;
|
|
case '\x8c':
|
|
stralloc_cats(&str, "î");
|
|
break;
|
|
case '\x8d':
|
|
stralloc_cats(&str, "ì");
|
|
break;
|
|
case '\x8e':
|
|
stralloc_cats(&str, "Ä");
|
|
break;
|
|
case '\x8f':
|
|
stralloc_cats(&str, "Å");
|
|
break;
|
|
case '\x90':
|
|
stralloc_cats(&str, "É");
|
|
break;
|
|
case '\x91':
|
|
stralloc_cats(&str, "æ");
|
|
break;
|
|
case '\x92':
|
|
stralloc_cats(&str, "Æ");
|
|
break;
|
|
case '\x93':
|
|
stralloc_cats(&str, "ô");
|
|
break;
|
|
case '\x94':
|
|
stralloc_cats(&str, "ö");
|
|
break;
|
|
case '\x95':
|
|
stralloc_cats(&str, "ò");
|
|
break;
|
|
case '\x96':
|
|
stralloc_cats(&str, "û");
|
|
break;
|
|
case '\x97':
|
|
stralloc_cats(&str, "ù");
|
|
break;
|
|
case '\x98':
|
|
stralloc_cats(&str, "ÿ");
|
|
break;
|
|
case '\x99':
|
|
stralloc_cats(&str, "Ö");
|
|
break;
|
|
case '\x9a':
|
|
stralloc_cats(&str, "Ü");
|
|
break;
|
|
case '\x9b':
|
|
stralloc_cats(&str, "¢");
|
|
break;
|
|
case '\x9c':
|
|
stralloc_cats(&str, "£");
|
|
break;
|
|
case '\x9d':
|
|
stralloc_cats(&str, "¥");
|
|
break;
|
|
case '\x9e':
|
|
stralloc_cats(&str, "₧");
|
|
break;
|
|
case '\x9f':
|
|
stralloc_cats(&str, "ƒ");
|
|
break;
|
|
case '\xa0':
|
|
stralloc_cats(&str, "á");
|
|
break;
|
|
case '\xa1':
|
|
stralloc_cats(&str, "í");
|
|
break;
|
|
case '\xa2':
|
|
stralloc_cats(&str, "ó");
|
|
break;
|
|
case '\xa3':
|
|
stralloc_cats(&str, "ú");
|
|
break;
|
|
case '\xa4':
|
|
stralloc_cats(&str, "ñ");
|
|
break;
|
|
case '\xa5':
|
|
stralloc_cats(&str, "Ñ");
|
|
break;
|
|
case '\xa6':
|
|
stralloc_cats(&str, "ª");
|
|
break;
|
|
case '\xa7':
|
|
stralloc_cats(&str, "º");
|
|
break;
|
|
case '\xa8':
|
|
stralloc_cats(&str, "¿");
|
|
break;
|
|
case '\xa9':
|
|
stralloc_cats(&str, "⌐");
|
|
break;
|
|
case '\xaa':
|
|
stralloc_cats(&str, "¬");
|
|
break;
|
|
case '\xab':
|
|
stralloc_cats(&str, "½");
|
|
break;
|
|
case '\xac':
|
|
stralloc_cats(&str, "¼");
|
|
break;
|
|
case '\xad':
|
|
stralloc_cats(&str, "¡");
|
|
break;
|
|
case '\xae':
|
|
stralloc_cats(&str, "«");
|
|
break;
|
|
case '\xaf':
|
|
stralloc_cats(&str, "»");
|
|
break;
|
|
case '\xb0':
|
|
stralloc_cats(&str, "░");
|
|
break;
|
|
case '\xb1':
|
|
stralloc_cats(&str, "▒");
|
|
break;
|
|
case '\xb2':
|
|
stralloc_cats(&str, "▓");
|
|
break;
|
|
case '\xb3':
|
|
stralloc_cats(&str, "│");
|
|
break;
|
|
case '\xb4':
|
|
stralloc_cats(&str, "┤");
|
|
break;
|
|
case '\xb5':
|
|
stralloc_cats(&str, "╡");
|
|
break;
|
|
case '\xb6':
|
|
stralloc_cats(&str, "╢");
|
|
break;
|
|
case '\xb7':
|
|
stralloc_cats(&str, "╖");
|
|
break;
|
|
case '\xb8':
|
|
stralloc_cats(&str, "╕");
|
|
break;
|
|
case '\xb9':
|
|
stralloc_cats(&str, "╣");
|
|
break;
|
|
case '\xba':
|
|
stralloc_cats(&str, "║");
|
|
break;
|
|
case '\xbb':
|
|
stralloc_cats(&str, "╗");
|
|
break;
|
|
case '\xbc':
|
|
stralloc_cats(&str, "╝");
|
|
break;
|
|
case '\xbd':
|
|
stralloc_cats(&str, "╜");
|
|
break;
|
|
case '\xbe':
|
|
stralloc_cats(&str, "╛");
|
|
break;
|
|
case '\xbf':
|
|
stralloc_cats(&str, "┐");
|
|
break;
|
|
case '\xc0':
|
|
stralloc_cats(&str, "└");
|
|
break;
|
|
case '\xc1':
|
|
stralloc_cats(&str, "┴");
|
|
break;
|
|
case '\xc2':
|
|
stralloc_cats(&str, "┬");
|
|
break;
|
|
case '\xc3':
|
|
stralloc_cats(&str, "├");
|
|
break;
|
|
case '\xc4':
|
|
stralloc_cats(&str, "─");
|
|
break;
|
|
case '\xc5':
|
|
stralloc_cats(&str, "┼");
|
|
break;
|
|
case '\xc6':
|
|
stralloc_cats(&str, "╞");
|
|
break;
|
|
case '\xc7':
|
|
stralloc_cats(&str, "╟");
|
|
break;
|
|
case '\xc8':
|
|
stralloc_cats(&str, "╚");
|
|
break;
|
|
case '\xc9':
|
|
stralloc_cats(&str, "╔");
|
|
break;
|
|
case '\xca':
|
|
stralloc_cats(&str, "╩");
|
|
break;
|
|
case '\xcb':
|
|
stralloc_cats(&str, "╦");
|
|
break;
|
|
case '\xcc':
|
|
stralloc_cats(&str, "╠");
|
|
break;
|
|
case '\xcd':
|
|
stralloc_cats(&str, "═");
|
|
break;
|
|
case '\xce':
|
|
stralloc_cats(&str, "╬");
|
|
break;
|
|
case '\xcf':
|
|
stralloc_cats(&str, "╧");
|
|
break;
|
|
case '\xd0':
|
|
stralloc_cats(&str, "╨");
|
|
break;
|
|
case '\xd1':
|
|
stralloc_cats(&str, "╤");
|
|
break;
|
|
case '\xd2':
|
|
stralloc_cats(&str, "╥");
|
|
break;
|
|
case '\xd3':
|
|
stralloc_cats(&str, "╙");
|
|
break;
|
|
case '\xd4':
|
|
stralloc_cats(&str, "╛");
|
|
break;
|
|
case '\xd5':
|
|
stralloc_cats(&str, "╒");
|
|
break;
|
|
case '\xd6':
|
|
stralloc_cats(&str, "╓");
|
|
break;
|
|
case '\xd7':
|
|
stralloc_cats(&str, "╫");
|
|
break;
|
|
case '\xd8':
|
|
stralloc_cats(&str, "╪");
|
|
break;
|
|
case '\xd9':
|
|
stralloc_cats(&str, "┘");
|
|
break;
|
|
case '\xda':
|
|
stralloc_cats(&str, "┌");
|
|
break;
|
|
case '\xdb':
|
|
stralloc_cats(&str, "█");
|
|
break;
|
|
case '\xdc':
|
|
stralloc_cats(&str, "▄");
|
|
break;
|
|
case '\xdd':
|
|
stralloc_cats(&str, "▌");
|
|
break;
|
|
case '\xde':
|
|
stralloc_cats(&str, "▐");
|
|
break;
|
|
case '\xdf':
|
|
stralloc_cats(&str, "▀");
|
|
break;
|
|
case '\xe0':
|
|
stralloc_cats(&str, "α");
|
|
break;
|
|
case '\xe1':
|
|
stralloc_cats(&str, "β");
|
|
break;
|
|
case '\xe2':
|
|
stralloc_cats(&str, "Γ");
|
|
break;
|
|
case '\xe3':
|
|
stralloc_cats(&str, "π");
|
|
break;
|
|
case '\xe4':
|
|
stralloc_cats(&str, "Σ");
|
|
break;
|
|
case '\xe5':
|
|
stralloc_cats(&str, "σ");
|
|
break;
|
|
case '\xe6':
|
|
stralloc_cats(&str, "µ");
|
|
break;
|
|
case '\xe7':
|
|
stralloc_cats(&str, "τ");
|
|
break;
|
|
case '\xe8':
|
|
stralloc_cats(&str, "Φ");
|
|
break;
|
|
case '\xe9':
|
|
stralloc_cats(&str, "Θ");
|
|
break;
|
|
case '\xea':
|
|
stralloc_cats(&str, "Ω");
|
|
break;
|
|
case '\xeb':
|
|
stralloc_cats(&str, "δ");
|
|
break;
|
|
case '\xec':
|
|
stralloc_cats(&str, "∞");
|
|
break;
|
|
case '\xed':
|
|
stralloc_cats(&str, "∅");
|
|
break;
|
|
case '\xee':
|
|
stralloc_cats(&str, "∈");
|
|
break;
|
|
case '\xef':
|
|
stralloc_cats(&str, "∩");
|
|
break;
|
|
case '\xf0':
|
|
stralloc_cats(&str, "≡");
|
|
break;
|
|
case '\xf1':
|
|
stralloc_cats(&str, "±");
|
|
break;
|
|
case '\xf2':
|
|
stralloc_cats(&str, "≥");
|
|
break;
|
|
case '\xf3':
|
|
stralloc_cats(&str, "≤");
|
|
break;
|
|
case '\xf4':
|
|
stralloc_cats(&str, "⌠");
|
|
break;
|
|
case '\xf5':
|
|
stralloc_cats(&str, "⌡");
|
|
break;
|
|
case '\xf6':
|
|
stralloc_cats(&str, "÷");
|
|
break;
|
|
case '\xf7':
|
|
stralloc_cats(&str, "≈");
|
|
break;
|
|
case '\xf8':
|
|
stralloc_cats(&str, "°");
|
|
break;
|
|
case '\xf9':
|
|
stralloc_cats(&str, "∙");
|
|
break;
|
|
case '\xfa':
|
|
stralloc_cats(&str, "·");
|
|
break;
|
|
case '\xfb':
|
|
stralloc_cats(&str, "√");
|
|
break;
|
|
case '\xfc':
|
|
stralloc_cats(&str, "ⁿ");
|
|
break;
|
|
case '\xfd':
|
|
stralloc_cats(&str, "²");
|
|
break;
|
|
case '\xfe':
|
|
stralloc_cats(&str, "▪");
|
|
break;
|
|
case ' ':
|
|
if (isdata) {
|
|
if (*(p+1) == ' ') {
|
|
stralloc_cats(&str, " ");
|
|
} else {
|
|
if (p > data && (*(p-1) == ' ' || *(p-1) == '\n')) {
|
|
stralloc_cats(&str, " ");
|
|
} else if (data == p) {
|
|
stralloc_cats(&str, " ");
|
|
} else {
|
|
stralloc_append1(&str, ' ');
|
|
}
|
|
}
|
|
} else {
|
|
stralloc_append1(&str, ' ');
|
|
}
|
|
break;
|
|
|
|
default:
|
|
stralloc_append1(&str, *p);
|
|
break;
|
|
}
|
|
}
|
|
stralloc_0(&str);
|
|
return str.s;
|
|
}
|
|
|
|
struct www_tag *www_tag_new(char *tag, char *data) {
|
|
struct www_tag *new_tag = malloz(sizeof(struct www_tag));
|
|
|
|
|
|
new_tag->attribs = EMPTY_PTR_VECTOR;
|
|
new_tag->values = EMPTY_PTR_VECTOR;
|
|
new_tag->children = EMPTY_PTR_VECTOR;
|
|
|
|
if (tag == NULL) {
|
|
new_tag->tag = NULL;
|
|
|
|
/* SANATIZE DATA HERE */
|
|
new_tag->data = www_tag_sanatize(data, 1);
|
|
} else {
|
|
new_tag->tag = strdup(tag);
|
|
new_tag->data = NULL;
|
|
|
|
init_ptr_vector(&new_tag->attribs);
|
|
init_ptr_vector(&new_tag->values);
|
|
}
|
|
|
|
init_ptr_vector(&new_tag->children);
|
|
|
|
return new_tag;
|
|
}
|
|
|
|
struct www_tag *www_tag_duplicate(struct www_tag *oldtag) {
|
|
struct www_tag *newtag = www_tag_new(oldtag->tag, oldtag->data);
|
|
for (int i=0;i<oldtag->attribs.len;i++) {
|
|
www_tag_add_attrib(newtag, strdup(ptr_vector_get(&oldtag->attribs, i)), strdup(ptr_vector_get(&oldtag->values, i)));
|
|
}
|
|
return newtag;
|
|
}
|
|
|
|
void www_tag_add_attrib(struct www_tag *tag, char *attrib, char *value) {
|
|
ptr_vector_append(&tag->attribs, strdup(attrib));
|
|
ptr_vector_append(&tag->values, www_tag_sanatize(value, 0));
|
|
}
|
|
|
|
void www_tag_add_child(struct www_tag *tag, struct www_tag *child) {
|
|
ptr_vector_append(&tag->children, child);
|
|
}
|
|
|
|
char *www_tag_destroy(struct www_tag *tag) {
|
|
while (tag->children.len > 0) {
|
|
struct www_tag *child = ptr_vector_del(&tag->children, 0);
|
|
www_tag_destroy(child);
|
|
}
|
|
|
|
if (tag->tag != NULL) {
|
|
ptr_vector_apply(&tag->attribs, free);
|
|
destroy_ptr_vector(&tag->attribs);
|
|
ptr_vector_apply(&tag->values, free);
|
|
destroy_ptr_vector(&tag->values);
|
|
}
|
|
destroy_ptr_vector(&tag->children);
|
|
}
|
|
|
|
char *www_tag_unwravel(struct www_tag *tag) {
|
|
stralloc thedata = EMPTY_STRALLOC;
|
|
while (tag->children.len > 0) {
|
|
struct www_tag *child = ptr_vector_del(&tag->children, 0);
|
|
if (child->children.len > 0) {
|
|
if (child->tag != NULL) {
|
|
stralloc_append1(&thedata, '<');
|
|
stralloc_cats(&thedata, child->tag);
|
|
for (int i = 0; i < child->attribs.len; i++) {
|
|
stralloc_append1(&thedata, ' ');
|
|
stralloc_cats(&thedata, (char *)ptr_vector_get(&child->attribs, i));
|
|
stralloc_append1(&thedata, '=');
|
|
stralloc_append1(&thedata, '\"');
|
|
stralloc_cats(&thedata, (char *)ptr_vector_get(&child->values, i));
|
|
stralloc_append1(&thedata, '\"');
|
|
}
|
|
|
|
|
|
stralloc_append1(&thedata, '>');
|
|
}
|
|
char *data = www_tag_unwravel(child);
|
|
stralloc_cats(&thedata, data);
|
|
free(data);
|
|
|
|
if (child->tag != NULL) {
|
|
stralloc_cats(&thedata, "</");
|
|
stralloc_cats(&thedata, child->tag);
|
|
stralloc_append1(&thedata, '>');
|
|
ptr_vector_apply(&child->attribs, free);
|
|
destroy_ptr_vector(&child->attribs);
|
|
ptr_vector_apply(&child->values, free);
|
|
destroy_ptr_vector(&child->values);
|
|
}
|
|
} else {
|
|
if (child->tag != NULL) {
|
|
stralloc_append1(&thedata, '<');
|
|
stralloc_cats(&thedata, child->tag);
|
|
for (int i = 0; i < child->attribs.len; i++) {
|
|
stralloc_append1(&thedata, ' ');
|
|
stralloc_cats(&thedata, (char *)ptr_vector_get(&child->attribs, i));
|
|
stralloc_append1(&thedata, '=');
|
|
stralloc_append1(&thedata, '\"');
|
|
stralloc_cats(&thedata, (char *)ptr_vector_get(&child->values, i));
|
|
stralloc_append1(&thedata, '\"');
|
|
}
|
|
stralloc_cats(&thedata, " />");
|
|
ptr_vector_apply(&child->attribs, free);
|
|
destroy_ptr_vector(&child->attribs);
|
|
ptr_vector_apply(&child->values, free);
|
|
destroy_ptr_vector(&child->values);
|
|
} else {
|
|
stralloc_cats(&thedata, child->data);
|
|
}
|
|
}
|
|
destroy_ptr_vector(&child->children);
|
|
|
|
}
|
|
|
|
stralloc_0(&thedata);
|
|
|
|
return thedata.s;
|
|
}
|
|
|
|
#endif
|