1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
/* kc3
* Copyright 2022,2023,2024 kmx.io <contact@kmx.io>
*
* Permission is hereby granted to use this software granted the above
* copyright notice and this permission paragraph are included in all
* copies and substantial portions of this software.
*
* THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
* PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
* AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
* THIS SOFTWARE.
*/
#include <libkc3/kc3.h>
#include "html.h"
s_str * html_escape (const s_str *str, s_str *dest)
{
s_buf buf;
character c;
const s_list *e;
const s_list *escape;
s_ident escape_ident;
s_tag escape_tag;
s_tag *replace;
s_tag *reserved;
s_str s;
s_tag tag;
assert(str);
assert(dest);
ident_init(&escape_ident, sym_1("EKC3"), sym_1("html_escape"));
if (! ident_get(&escape_ident, &escape_tag)) {
err_puts("html_escape: ident_get");
assert(! "html_escape: ident_get");
return NULL;
}
if (! tag_is_alist(&escape_tag)) {
tag_clean(&escape_tag);
err_puts("html_escape: EKC3.html_escape is not an associative"
" List");
assert(!("html_escape: EKC3.html_escape is not an associative"
" List"));
return NULL;
}
escape = escape_tag.data.list;
if (! buf_init_alloc(&buf, str->size * 8)) {
tag_clean(&escape_tag);
return NULL;
}
tag.type = TAG_STR;
tag.data.str = (s_str) {0};
s = *str;
while (str_read_character_utf8(&s, &c) > 0) {
if (! str_init_character(&tag.data.str, c))
goto ko;
replace = NULL;
e = escape;
while (e) {
reserved = e->tag.data.tuple.tag;
if (reserved->type != TAG_STR) {
err_puts("html_escape: EKC3.html_escape: reserved that is"
" not a Str");
assert(!("html_escape: EKC3.html_escape: reserved that is"
" not a Str"));
str_clean(&tag.data.str);
goto ko;
}
if (! compare_tag(reserved, &tag)) {
replace = e->tag.data.tuple.tag + 1;
if (replace->type != TAG_STR) {
err_puts("html_escape: EKC3.html_escape: replacement that is"
" not a Str");
assert(!("html_escape: EKC3.html_escape: replacement that is"
" not a Str"));
str_clean(&tag.data.str);
goto ko;
}
break;
}
e = list_next(e);
}
str_clean(&tag.data.str);
if (replace) {
if (buf_write_str(&buf, &replace->data.str) <= 0) {
err_puts("html_escape: buf_write_str");
assert(! "html_escape: buf_write_str");
goto ko;
}
}
else {
if (buf_write_character_utf8(&buf, c) <= 0) {
err_puts("html_escape: buf_write_character_utf8");
assert(! "html_escape: buf_write_character_utf8");
goto ko;
}
}
}
tag_clean(&escape_tag);
s = (s_str) {0};
if (! buf_read_to_str(&buf, &s)) {
buf_clean(&buf);
return NULL;
}
buf_clean(&buf);
*dest = s;
return dest;
ko:
tag_clean(&escape_tag);
buf_clean(&buf);
return NULL;
}