diff options
author | Jeremias Stotter <jeremias@stotter.eu> | 2022-04-11 21:43:40 +0200 |
---|---|---|
committer | Jeremias Stotter <jeremias@stotter.eu> | 2022-04-11 21:43:40 +0200 |
commit | ddd301d3bfd80e7008e9fbd5bab4d6bf904d5bc6 (patch) | |
tree | 3fa19ba4ee1ac2e8d913965f44c26c90e2dc2df0 | |
parent | d38b0fcdaf1721eb6fad6ad55f3f681aa58bc8f2 (diff) | |
download | JBlog-ddd301d3bfd80e7008e9fbd5bab4d6bf904d5bc6.tar.gz JBlog-ddd301d3bfd80e7008e9fbd5bab4d6bf904d5bc6.tar.bz2 JBlog-ddd301d3bfd80e7008e9fbd5bab4d6bf904d5bc6.zip |
Markdown now gets escaped before being served in textarea
-rw-r--r-- | admin.c | 35 | ||||
-rw-r--r-- | jblog.c | 30 | ||||
-rw-r--r-- | jblog.h | 7 | ||||
-rw-r--r-- | md.c | 40 |
4 files changed, 75 insertions, 37 deletions
@@ -127,8 +127,37 @@ void urldecode(char* src, char* dest) { } */ +// Escapes all the non-html capable characters in buffer. It returns a newly created buffer that needs to be freed later +char* escape_buffer(char* buffer) { + if(buffer == NULL) + return NULL; + int in_length = strlen(buffer) + 1; + int utf8_length = 0; + long int unicode_char = 0; + char escape_buffer[96] = {0}; + char* out_buffer = calloc(in_length, 1); + int available_buffer = in_length; + int used_buffer = 1; + for(char* cur_char = buffer; *cur_char != 0; cur_char++) { + if(NEEDS_ESCAPE_CHECK(*cur_char)) { + used_buffer += html_escape(escape_buffer, *cur_char, &utf8_length, &unicode_char) + 1; + // Check if we need more space + } else { + used_buffer++; + escape_buffer[0] = *cur_char; + escape_buffer[1] = '\0'; + } + if(used_buffer > available_buffer) { + out_buffer = realloc(out_buffer, used_buffer); + memset(out_buffer+available_buffer, '\0', used_buffer - available_buffer); + available_buffer = used_buffer; + } + strcat(out_buffer, escape_buffer); + } + return out_buffer; +} + int create_admin(char* buffer, size_t buffer_size, char* adm_save_dir, char* path_argument) { - // @todo: actually parse the file if(path_argument != NULL) { char filepath[PATH_MAX] = ""; if(*path_argument == '!') { @@ -170,6 +199,7 @@ int create_admin(char* buffer, size_t buffer_size, char* adm_save_dir, char* pat close(edit_file); return 0; } + char* blog_text = escape_buffer(jblog_values.blog_text); snprintf(buffer, buffer_size, ADMIN_HTML, jblog_values.type_str ? jblog_values.type_str : "", "", "", @@ -178,9 +208,10 @@ int create_admin(char* buffer, size_t buffer_size, char* adm_save_dir, char* pat jblog_values.time_str ? jblog_values.time_str : "", jblog_values.author ? jblog_values.author : "", jblog_values.title ? jblog_values.title : "", - jblog_values.blog_text ? jblog_values.blog_text : "", + blog_text ? blog_text : "", path_argument); free(edit_file_content); + free(blog_text); } else { snprintf(buffer, buffer_size, ADMIN_HTML, "", "", "", "", "", "", "", "", "", ""); } @@ -99,6 +99,36 @@ void jb_log(int loglevel, bool include_errno, char* error_string) { fprintf(nologfile_out, error_full); } +// Escape a html character +// utf8_length and unicode_char need to be preserved between calls +int html_escape(char output_buffer[96], char input, int* utf8_length, long int* unicode_char) { + if((input & 0xFFFF0000) == 0xFFFF0000) { + // UTF-8 + int leading_ones = 0; + char copy_input = input; + while(copy_input & 0b10000000) { + leading_ones++; + copy_input = copy_input << 1; + } + if(leading_ones > 1) { + *utf8_length = leading_ones; + *unicode_char = 0x0; + } + *unicode_char = *unicode_char << (8 - leading_ones -1); + *unicode_char = *unicode_char | ( input & (UCHAR_MAX >> leading_ones) ); + (*utf8_length)--; + + if(*utf8_length) { + *output_buffer = '\0'; + return 0; + } else { + return snprintf(output_buffer, 96, "&#x%lX;", *unicode_char); + } + } else { + return snprintf(output_buffer, 96, "&#x%X;", input); + } +} + void sigint_catch(int signo) { if(shutdown(sockfd, SHUT_RDWR) != 0) { jb_log(LL_ERR, true, "Could not shutdown socket"); @@ -49,4 +49,11 @@ void retrieve_headvals(char* head, char retrieve_values[][32], char** returned_s char* trim_whitespace(char** str); int process_blog_text(char* buffer, size_t buffer_size, char* blog_text, char* title, char* author, char* date, char* time); int split_jblog(struct jblog_file* jblog_values, char* blog_content); + +int html_escape(char output_buffer[96], char input, int* utf8_length, long int* unicode_char); + +#define NEEDS_ESCAPE_CHECK(input) (input <= 47 || \ + (input >=58 && input <=64) || \ + (input >=91 && input <=96) || \ + input > 122) && input != 0x20 #endif @@ -116,35 +116,6 @@ struct tree_element* new_child(struct tree_element* parent, int index) { return child; } -int utf8_length; -long int unicode_char; -// Returns the bytes written -void html_escape(char* output_buffer, char input) { - if((input & 0xFFFF0000) == 0xFFFF0000) { - // UTF-8 - int leading_ones = 0; - char copy_input = input; - while(copy_input & 0b10000000) { - leading_ones++; - copy_input = copy_input << 1; - } - if(leading_ones > 1) { - utf8_length = leading_ones; - unicode_char = 0x0; - } - unicode_char = unicode_char << (8 - leading_ones -1); - unicode_char = unicode_char | ( input & (UCHAR_MAX >> leading_ones) ); - utf8_length--; - - if(utf8_length) - *output_buffer = '\0'; - else { - snprintf(output_buffer, 96, "&#x%lX;", unicode_char); - } - } else { - snprintf(output_buffer, 96, "&#x%X;", input); - } -} // Reallocs the string dest to fit src, then append char* realloc_append(char* dest, char* src) { @@ -291,6 +262,8 @@ char* tree_to_html(struct tree_element* root) { // Use this to find the next parent that allows inner elements #define NEXT_ALLOW_INNER(active_element, root) while(!(active_element == root) && (!active_element->allow_inner && active_element)) active_element = active_element->parent; +int utf8_length; +long int unicode_char; // This appends the cur_char to active element / it creates a new active element if the active element can not have text void append_char_to_active(struct tree_element* root, struct tree_element** active_element, char cur_char) { // We are not allowed to add inner to this element so we'll start a new paragraph @@ -304,13 +277,10 @@ void append_char_to_active(struct tree_element* root, struct tree_element** acti if(new_active_element->type != t_inner) { NEW_ACTIVE_CHILD(new_active_element, new_active_element, -1, t_inner, false); } - if((cur_char <= 47 || - (cur_char >=58 && cur_char <=64) || - (cur_char >=91 && cur_char <=96) || - cur_char > 122) && cur_char != 0x20) { + if(NEEDS_ESCAPE_CHECK(cur_char)) { // Escape just to be safe char append[96] = ""; - html_escape(append, cur_char); + html_escape(append, cur_char, &utf8_length, &unicode_char); new_active_element->value = realloc_append(new_active_element->value, append); } else { // This is stupid, improve this later xD @@ -436,7 +406,7 @@ void str_chr_hit(struct tree_element* root, struct tree_element** active_element // The program needs to loop through the loop again to cose all the open things at the end, THIS NEEDS TO BE IMPLEMENTED for xhtml int parse_markdown(char* input, char* buffer, size_t buffer_size) { utf8_length = 0; - + unicode_char = 0; clock_t before = clock(); memset(buffer, 0, buffer_size); bool escaped = false; |