From c7aefa2cd7ef9bae68773df9f338da4b44a76d73 Mon Sep 17 00:00:00 2001 From: Jorge Arellano Cid Date: Tue, 26 May 2015 11:29:21 -0300 Subject: Fix view-source dpi to handle null characters correctly Although not allowed in text contexts, null characters should not stop/halt/fail dpi protocol, thus the patch. Test Example. Display a file with these contents: null padding^@^@ (two trailing null characters) and view source for it. Note that dillo will not _display_ the file completely correct, it will eat a char after each null, but this is not a problem in dpi nor dpip but in rendering, the cache gets it right. Adding code to correctly _display_ these anomalous pages is probably not worth the effort though. --- dpi/vsource.c | 56 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 25 deletions(-) (limited to 'dpi') diff --git a/dpi/vsource.c b/dpi/vsource.c index 2f1129cb..c28e7b49 100644 --- a/dpi/vsource.c +++ b/dpi/vsource.c @@ -3,7 +3,7 @@ * * This server is an example. Play with it and modify to your taste. * - * Copyright 2010 Jorge Arellano Cid + * Copyright 2010-2015 Jorge Arellano Cid * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,7 +25,7 @@ * Debugging macros */ #define _MSG(...) -#define MSG(...) printf("[vsource dpi]: " __VA_ARGS__) +#define MSG(...) fprintf(stderr, "[vsource dpi]: " __VA_ARGS__) /*---------------------------------------------------------------------------*/ @@ -42,38 +42,41 @@ void send_dpip_tag(Dsh *sh, char *dpip_tag) /* * Send source as plain text + * (handles embedded null chars correctly). */ void send_plain_text(Dsh *sh, int data_size) { - int bytes_read = 0; - char *src_str; + char *token; + int bytes_read = 0, token_size; /* Send HTTP header for plain text MIME type */ a_Dpip_dsh_write_str(sh, 0, "Content-type: text/plain\n\n"); while (bytes_read < data_size && - (src_str = a_Dpip_dsh_read_token(sh, 1))) { - bytes_read += strlen(src_str); - a_Dpip_dsh_write_str(sh, 1, src_str); - dFree(src_str); + (token = a_Dpip_dsh_read_token2(sh, 1, &token_size))) { + bytes_read += token_size; + _MSG("data_size=%d bytes_read=%d\n", data_size, bytes_read); + a_Dpip_dsh_write(sh, 1, token, token_size); + dFree(token); } } /* * Send source as plain text with line numbers + * (handles embedded null chars correctly). */ void send_numbered_text(Dsh *sh, int data_size) { - int bytes_read = 0, line = 1; - char *p, *q, *src_str, line_str[32]; + int bytes_read = 0, line = 1, token_size = 0; + char *p, *q, *token, line_str[32]; /* Send HTTP header for plain text MIME type */ a_Dpip_dsh_write_str(sh, 0, "Content-type: text/plain\n\n"); while (bytes_read < data_size && - (src_str = a_Dpip_dsh_read_token(sh, 1))) { - bytes_read += strlen(src_str); - p = q = src_str; + (token = a_Dpip_dsh_read_token2(sh, 1, &token_size))) { + bytes_read += token_size; + p = q = token; while (*p) { snprintf(line_str, 32, "%2d: ", line); @@ -84,28 +87,30 @@ void send_numbered_text(Dsh *sh, int data_size) ++p; ++line; } else { - a_Dpip_dsh_write_str(sh, 1, q); + /* send all the rest */ + a_Dpip_dsh_write(sh, 1, q, token_size - (q - token)); break; } q = ++p; } - dFree(src_str); + dFree(token); } } /* * Send source as html text with line numbers + * (handles embedded null chars correctly). */ void send_html_text(Dsh *sh, const char *url, int data_size) { - int bytes_read = 0, old_line = 0, line = 1; - char *p, *q, *src_str, line_str[128]; + int bytes_read = 0, old_line = 0, line = 1, token_size = 0; + char *p, *q, *token, line_str[128]; if (dStrnAsciiCasecmp(url, "dpi:", 4) == 0 && strncmp(url+4, "/vsource/:", 10) == 0) url += 14; - /* Send HTTP header for plain text MIME type */ + /* Send HTTP header for html text MIME type */ a_Dpip_dsh_write_str(sh, 0, "Content-type: text/html\n\n"); a_Dpip_dsh_write_str(sh, 0, DOCTYPE); @@ -119,9 +124,9 @@ void send_html_text(Dsh *sh, const char *url, int data_size) "\n\n", url); while (bytes_read < data_size && - (src_str = a_Dpip_dsh_read_token(sh, 1))) { - bytes_read += strlen(src_str); - p = q = src_str; + (token = a_Dpip_dsh_read_token2(sh, 1, &token_size))) { + bytes_read += token_size; + p = q = token; while (*p) { if (line > old_line) { @@ -143,13 +148,14 @@ void send_html_text(Dsh *sh, const char *url, int data_size) a_Dpip_dsh_write(sh, 0, q, p - q); a_Dpip_dsh_write_str(sh, 0, (*p == '<') ? "<" : "&"); } - } else { - a_Dpip_dsh_write_str(sh, 1, q); + } else { + /* send all the rest */ + a_Dpip_dsh_write(sh, 1, q, token_size - (q - token)); break; } q = ++p; } - dFree(src_str); + dFree(token); } if (data_size > 0) @@ -194,7 +200,7 @@ int main(void) * asking from us. a_Dpip_dsh_read_token() will block and return * a full dpip token or null on error (it's commented in dpip.c) */ dpip_tag = a_Dpip_dsh_read_token(sh, 1); - MSG("tag = [%s]\n", dpip_tag); + _MSG("tag = [%s]\n", dpip_tag); /* Now that we have the dpip_tag, let's isolate the command and url */ cmd = a_Dpip_get_attr(dpip_tag, "cmd"); -- cgit v1.2.3