diff --git a/daemon/cmd_load_studio.c b/daemon/cmd_load_studio.c index 6c9f2731..31f7caef 100644 --- a/daemon/cmd_load_studio.c +++ b/daemon/cmd_load_studio.c @@ -776,7 +776,7 @@ static void callback_elend(void * data, const char * el) else if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_APPLICATION) { context_ptr->data[unescape(context_ptr->data, context_ptr->data_used, context_ptr->data)] = 0; - unescape(context_ptr->str, strlen(context_ptr->str) + 1, context_ptr->str); + unescape_simple(context_ptr->str); log_info("application '%s' (%s, %s, level %u) with commandline '%s'", context_ptr->str, context_ptr->terminal ? "terminal" : "shell", context_ptr->autorun ? "autorun" : "stopped", (unsigned int)context_ptr->level, context_ptr->data); diff --git a/daemon/cmd_save_studio.c b/daemon/cmd_save_studio.c index afb56561..d7ec5e3d 100644 --- a/daemon/cmd_save_studio.c +++ b/daemon/cmd_save_studio.c @@ -60,7 +60,7 @@ write_jack_parameter( do { *dst++ = '/'; - escape(&src, &dst); + escape(&src, &dst, LADISH_ESCAPE_FLAG_ALL); src++; } while (*src != 0); diff --git a/daemon/escape.c b/daemon/escape.c index 233c269a..1d4e0ccd 100644 --- a/daemon/escape.c +++ b/daemon/escape.c @@ -30,7 +30,7 @@ static char hex_digits[] = "0123456789ABCDEF"; #define HEX_TO_INT(hexchar) ((hexchar) <= '9' ? hexchar - '0' : 10 + (hexchar - 'A')) -void escape(const char ** src_ptr, char ** dst_ptr) +void escape(const char ** src_ptr, char ** dst_ptr, unsigned int flags) { const char * src; char * dst; @@ -43,30 +43,38 @@ void escape(const char ** src_ptr, char ** dst_ptr) switch (*src) { case '/': /* used as separator for address components */ - case '<': /* invalid attribute value char (XML spec) */ - case '&': /* invalid attribute value char (XML spec) */ - case '"': /* we store attribute values in double quotes - invalid attribute value char (XML spec) */ case '\'': case '>': case '%': + if ((flags & LADISH_ESCAPE_FLAG_OTHER) == 0) + { + break; + } + case '<': /* invalid attribute value char (XML spec) */ + case '&': /* invalid attribute value char (XML spec) */ + case '"': /* we store attribute values in double quotes - invalid attribute value char (XML spec) */ + if ((flags & LADISH_ESCAPE_FLAG_XML_ATTR) == 0) + { + break; + } dst[0] = '%'; dst[1] = hex_digits[*src >> 4]; dst[2] = hex_digits[*src & 0x0F]; dst += 3; src++; - break; - default: - *dst++ = *src++; + continue; } + + *dst++ = *src++; } *src_ptr = src; *dst_ptr = dst; } -void escape_simple(const char * src_ptr, char * dst_ptr) +void escape_simple(const char * src_ptr, char * dst_ptr, unsigned int flags) { - escape(&src_ptr, &dst_ptr); + escape(&src_ptr, &dst_ptr, flags); *dst_ptr = 0; } @@ -102,3 +110,24 @@ size_t unescape(const char * src, size_t src_len, char * dst) return dst_len; } + +void unescape_simple(char * buffer) +{ + unescape(buffer, strlen(buffer) + 1, buffer); +} + +char * unescape_dup(const char * src) +{ + size_t len; + char * dst; + + len = strlen(src) + 1; + + dst = malloc(len); + if (dst != NULL) + { + unescape(src, len, dst); + } + + return dst; +} diff --git a/daemon/escape.h b/daemon/escape.h index 15bf9d8a..bd73181d 100644 --- a/daemon/escape.h +++ b/daemon/escape.h @@ -28,10 +28,17 @@ #define ESCAPE_H__FABBE484_1093_41C1_9FC9_62ED0106E542__INCLUDED #include "common.h" +#include /* UINT_MAX */ -void escape(const char ** src_ptr, char ** dst_ptr); -void escape_simple(const char * src_ptr, char * dst_ptr); +#define LADISH_ESCAPE_FLAG_XML_ATTR ((unsigned int)1 << 0) +#define LADISH_ESCAPE_FLAG_OTHER ((unsigned int)1 << 1) +#define LADISH_ESCAPE_FLAG_ALL UINT_MAX + +void escape(const char ** src_ptr, char ** dst_ptr, unsigned int flags); +void escape_simple(const char * src_ptr, char * dst_ptr, unsigned int flags); size_t unescape(const char * src, size_t src_len, char * dst); +void unescape_simple(char * buffer); +char * unescape_dup(const char * src); /* encode each char in three bytes (percent encoding) */ #define max_escaped_length(unescaped_length) ((unescaped_length) * 3) diff --git a/daemon/room_load.c b/daemon/room_load.c index 37978200..a4c7e47f 100644 --- a/daemon/room_load.c +++ b/daemon/room_load.c @@ -655,7 +655,7 @@ static void callback_elend(void * data, const char * el) else if (context_ptr->element[context_ptr->depth] == PARSE_CONTEXT_APPLICATION) { context_ptr->data[unescape(context_ptr->data, context_ptr->data_used, context_ptr->data)] = 0; - unescape(context_ptr->str, strlen(context_ptr->str) + 1, context_ptr->str); + unescape_simple(context_ptr->str); log_info("application '%s' (%s, %s, level %u) with commandline '%s'", context_ptr->str, context_ptr->terminal ? "terminal" : "shell", context_ptr->autorun ? "autorun" : "stopped", (unsigned int)context_ptr->level, context_ptr->data); diff --git a/daemon/room_save.c b/daemon/room_save.c index 151fbc25..38db5913 100644 --- a/daemon/room_save.c +++ b/daemon/room_save.c @@ -267,7 +267,7 @@ char * compose_project_dir_from_name(const char * project_name) memcpy(project_dir, home_dir, home_dir_len); memcpy(project_dir + home_dir_len, DEFAULT_PROJECT_BASE_DIR, DEFAULT_PROJECT_BASE_DIR_LEN); - escape_simple(project_name, project_dir + home_dir_len + DEFAULT_PROJECT_BASE_DIR_LEN); + escape_simple(project_name, project_dir + home_dir_len + DEFAULT_PROJECT_BASE_DIR_LEN, LADISH_ESCAPE_FLAG_ALL); return project_dir; } diff --git a/daemon/save.c b/daemon/save.c index db00f90b..b14cc468 100644 --- a/daemon/save.c +++ b/daemon/save.c @@ -71,7 +71,7 @@ bool ladish_write_indented_string(int fd, int indent, const char * string) return true; } -bool ladish_write_string_escape(int fd, const char * string) +bool ladish_write_string_escape_ex(int fd, const char * string, unsigned int flags) { bool ret; char * escaped_buffer; @@ -83,7 +83,7 @@ bool ladish_write_string_escape(int fd, const char * string) return false; } - escape_simple(string, escaped_buffer); + escape_simple(string, escaped_buffer, flags); ret = ladish_write_string(fd, escaped_buffer); @@ -92,6 +92,11 @@ bool ladish_write_string_escape(int fd, const char * string) return ret; } +bool ladish_write_string_escape(int fd, const char * string) +{ + return ladish_write_string_escape_ex(fd, string, LADISH_ESCAPE_FLAG_ALL); +} + #define fd (((struct ladish_write_context *)context)->fd) #define indent (((struct ladish_write_context *)context)->indent) @@ -462,7 +467,7 @@ ladish_save_app( unescaped_string = name; escaped_string = escaped_buffer; - escape(&unescaped_string, &escaped_string); + escape(&unescaped_string, &escaped_string, LADISH_ESCAPE_FLAG_ALL); *escaped_string = 0; if (!ladish_write_string(fd, escaped_buffer)) { @@ -508,7 +513,7 @@ ladish_save_app( unescaped_string = command; escaped_string = escaped_buffer; - escape(&unescaped_string, &escaped_string); + escape(&unescaped_string, &escaped_string, LADISH_ESCAPE_FLAG_ALL); *escaped_string = 0; if (!ladish_write_string(fd, escaped_buffer)) { diff --git a/daemon/save.h b/daemon/save.h index 77c9acae..c340178a 100644 --- a/daemon/save.h +++ b/daemon/save.h @@ -44,6 +44,7 @@ struct ladish_write_context bool ladish_write_string(int fd, const char * string); bool ladish_write_indented_string(int fd, int indent, const char * string); bool ladish_write_string_escape(int fd, const char * string); +bool ladish_write_string_escape_ex(int fd, const char * string, unsigned int flags); bool ladish_write_dict(int fd, int indent, ladish_dict_handle dict); bool ladish_write_vgraph(int fd, int indent, ladish_graph_handle vgraph, ladish_app_supervisor_handle app_supervisor); bool ladish_write_room_link_ports(int fd, int indent, ladish_room_handle room); diff --git a/daemon/studio.c b/daemon/studio.c index 2cfe98aa..3c256e8e 100644 --- a/daemon/studio.c +++ b/daemon/studio.c @@ -733,7 +733,7 @@ bool ladish_studio_compose_filename(const char * name, char ** filename_ptr_ptr, *p++ = '/'; src = name; - escape(&src, &p); + escape(&src, &p, LADISH_ESCAPE_FLAG_ALL); strcpy(p, ".xml"); *filename_ptr_ptr = filename_ptr;