diff -Naur a/src/protocol/gopher/gopher.c b/src/protocol/gopher/gopher.c --- a/src/protocol/gopher/gopher.c 2020-01-09 09:19:54.983674477 +0000 +++ b/src/protocol/gopher/gopher.c 2020-01-09 09:21:58.885286474 +0000 @@ -663,6 +663,25 @@ return line[0] == '.' && !line[1] ? NULL : line; } +/* substring replacement */ +static void +str_replace(char * in_string, char * s_string, char * r_string) +{ + /* max == replace all characters */ + char temp[strlen(in_string) * (strlen(r_string) - strlen(s_string))]; + char * pos; + + if (!(pos = strstr(in_string, s_string))) + return; + + strncpy(temp, in_string, pos - in_string); + temp[pos - in_string] = 0; + sprintf(temp + (pos - in_string), "%s%s", r_string, pos + strlen(s_string)); + in_string[0] = 0; + strcpy(in_string, temp); + return str_replace(in_string, s_string, r_string); +} + /* Parse a Gopher Menu document */ static struct connection_state read_gopher_directory_data(struct connection *conn, struct read_buffer *rb) @@ -682,6 +701,17 @@ return connection_state(S_OUT_OF_MEM); } + /* Lines with characters that need to be converted to html */ + if (strstr(rb->data, "<")) { + str_replace(rb->data, "<", "<"); + } + if (strstr(rb->data, ">")) { + str_replace(rb->data, ">", ">"); + } + if (strstr(rb->data, "\"")) { + str_replace(rb->data, "\"", """); + } + while ((end = get_gopher_line_end(rb->data, rb->length))) { unsigned char *line = check_gopher_last_line(rb->data, end);