END_TEST START_TEST(test_remove_double_dots_and_double_slashes) { /* Adapted from unit_test.c */ /* Copyright (c) 2013-2015 the Civetweb developers */ /* Copyright (c) 2004-2013 Sergey Lyubka */ struct { char before[20], after[20]; } data[] = { {"////a", "/a"}, {"/.....", "/."}, {"/......", "/"}, {"..", "."}, {"...", "."}, {"/...///", "/./"}, {"/a...///", "/a.../"}, {"/.x", "/.x"}, {"/\\", "/"}, {"/a\\", "/a\\"}, {"/a\\\\...", "/a\\."}, }; size_t i; for (i = 0; i < ARRAY_SIZE(data); i++) { remove_double_dots_and_double_slashes(data[i].before); ck_assert_str_eq(data[i].before, data[i].after); } }
END_TEST START_TEST(test_remove_double_dots_and_double_slashes) { struct { char before[20], after[20]; } data[] = { {"////a", "/a"}, {"/.....", "/."}, {"/......", "/"}, {"...", "..."}, {"/...///", "/./"}, {"/a...///", "/a.../"}, {"/.x", "/.x"}, {"/\\", "/"}, {"/a\\", "/a\\"}, {"/a\\\\...", "/a\\."}, }; size_t i; for (i = 0; i < ARRAY_SIZE(data); i++) { remove_double_dots_and_double_slashes(data[i].before); ck_assert_str_eq(data[i].before, data[i].after); } }
// This is the heart of the Mongoose's logic. // This function is called when the request is read, parsed and validated, // and Mongoose must decide what action to take: serve a file, or // a directory, or call embedded function, etcetera. static void handle_request(struct mg_connection *conn) { struct mg_request_info *ri = &conn->request_info; int uri_len; if ((conn->request_info.query_string = strchr(ri->uri, '?')) != NULL) { * conn->request_info.query_string++ = '\0'; } uri_len = strlen(ri->uri); (void) url_decode(ri->uri, (size_t)uri_len, ri->uri, (size_t)(uri_len + 1), 0); remove_double_dots_and_double_slashes(ri->uri); DEBUG_TRACE(("%s", ri->uri)); if (call_user(conn, MG_NEW_REQUEST) == NULL) { mg_send_http_error(conn, 404, "Not Found", "%s", "File not found"); } }
static void test_remove_double_dots() { struct { char before[20], after[20]; } data[] = { {"////a", "/a"}, {"/.....", "/."}, {"/......", "/"}, {"...", "..."}, {"/...///", "/./"}, {"/a...///", "/a.../"}, {"/.x", "/.x"}, {"/\\", "/"}, {"/a\\", "/a\\"}, {"/a\\\\...", "/a\\."}, }; size_t i; for (i = 0; i < ARRAY_SIZE(data); i++) { remove_double_dots_and_double_slashes(data[i].before); ASSERT(strcmp(data[i].before, data[i].after) == 0); } }
static void test_remove_double_dots() { struct { char before[20], after[20]; } data[] = { {"////a", "/a"}, {"/.....", "/."}, {"/......", "/"}, {"...", "..."}, {"/...///", "/./"}, {"/a...///", "/a.../"}, {"/.x", "/.x"}, #if defined(_WIN32) {"/\\", "/"}, #else {"/\\", "/\\"}, #endif {"/a\\", "/a\\"}, }; size_t i; for (i = 0; i < ARRAY_SIZE(data); i++) { //printf("[%s] -> [%s]\n", data[i].before, data[i].after); remove_double_dots_and_double_slashes(data[i].before); ASSERT(strcmp(data[i].before, data[i].after) == 0); } }
static void handle_ssi_request(struct ezcfg_worker *worker) { struct ezcfg *ezcfg; struct ezcfg_http *http; struct ezcfg_master *master; struct ezcfg_nvram *nvram; struct ezcfg_ssi *ssi = NULL; char buf[1024]; char *request_uri; char *accept_language = NULL; size_t uri_len; char *msg = NULL; int msg_len; char *p; int len; time_t t; struct tm *tmp; ASSERT(worker != NULL); http = (struct ezcfg_http *)ezcfg_worker_get_proto_data(worker); ASSERT(http != NULL); ezcfg = ezcfg_worker_get_ezcfg(worker); master = ezcfg_worker_get_master(worker); nvram = ezcfg_master_get_nvram(master); /* HTTP header has been parsed */ p = ezcfg_http_get_header_value(http, EZCFG_HTTP_HEADER_ACCEPT_LANGUAGE); if (p != NULL) { accept_language = strdup(p); if (accept_language == NULL) goto func_exit; } ssi = ezcfg_ssi_new(ezcfg, nvram); if (ssi == NULL) { send_http_error(worker, 500, "Internal Server Error", "%s", "Not enough memory"); goto func_exit; } request_uri = ezcfg_http_get_request_uri(http); uri_len = strlen(request_uri); /* set default document root */ if (ezcfg_ssi_set_document_root(ssi, "/etc/ezcfg_upnpd") == false) { send_http_error(worker, 500, "Internal Server Error", "%s", "Not enough memory"); goto func_exit; } /* set file path */ uri_len = strlen(request_uri); if (uri_len+2 > sizeof(buf)) { send_http_error(worker, 505, "Bad Request", "%s", "File name is too large"); goto func_exit; } snprintf(buf, sizeof(buf), "%s", *request_uri == '/' ? "" : "/"); url_decode(request_uri, uri_len, buf+strlen(buf), uri_len+1, 0); remove_double_dots_and_double_slashes(buf); if (ezcfg_ssi_set_path(ssi, buf) == false) { send_http_error(worker, 500, "Internal Server Error", "%s", "Not enough memory"); goto func_exit; } if (ezcfg_ssi_open_file(ssi, "r") == NULL) { send_http_error(worker, 500, "Internal Server Error", "%s", "Cannot open file"); goto func_exit; } if (ezcfg_http_handle_ssi_request(http, nvram, ssi) < 0) { send_http_bad_request(worker); goto func_exit; } else { /* process SSI file */ msg_len = 0; msg = NULL; len = ezcfg_ssi_file_get_line(ssi, buf, sizeof(buf)); while(len >= 0) { if (len > 0) { p = realloc(msg, msg_len+len); if (p == NULL) { goto func_exit; } msg = p; p += msg_len; strncpy(p, buf, len); msg_len += len; } len = ezcfg_ssi_file_get_line(ssi, buf, sizeof(buf)); } p = ezcfg_http_set_message_body(http, msg, msg_len); if (p == NULL) { goto func_exit; } /* clean msg */ free(msg); msg = NULL; /* build HTTP response */ /* HTTP header Content-Language */ if (accept_language != NULL) { if (ezcfg_http_add_header(http, EZCFG_HTTP_HEADER_CONTENT_LANGUAGE, accept_language) == false) { err(ezcfg, "HTTP add header error.\n"); goto func_exit; } } /* HTTP header Content-Length */ snprintf(buf, sizeof(buf), "%d", msg_len); if (ezcfg_http_add_header(http, EZCFG_HTTP_HEADER_CONTENT_LENGTH, buf) == false) { err(ezcfg, "HTTP add header error.\n"); goto func_exit; } /* HTTP header Content-Type */ snprintf(buf, sizeof(buf), "%s; %s=%s", EZCFG_HTTP_MIME_TEXT_XML, EZCFG_HTTP_CHARSET_NAME, EZCFG_HTTP_CHARSET_UTF8); if (ezcfg_http_add_header(http, EZCFG_HTTP_HEADER_CONTENT_TYPE, buf) == false) { err(ezcfg, "HTTP add header error.\n"); goto func_exit; } /* HTTP header Date */ /* Date: Thu, 01 Jan 1970 00:00:45 GMT */ t = time(NULL); tmp = localtime(&t); if (tmp == NULL) { err(ezcfg, "localtime error.\n"); goto func_exit; } if (strftime(buf, sizeof(buf), "%a, %d %b %Y %T GMT", tmp) == 0) { err(ezcfg, "strftime returned 0\n"); goto func_exit; } if (ezcfg_http_add_header(http, EZCFG_HTTP_HEADER_DATE, buf) == false) { err(ezcfg, "HTTP add header error.\n"); goto func_exit; } msg_len = ezcfg_http_get_message_length(http); if (msg_len < 0) { err(ezcfg, "ezcfg_http_get_message_length error.\n"); goto func_exit; } msg_len++; /* one more for '\0' */ msg = (char *)malloc(msg_len); if (msg == NULL) { err(ezcfg, "malloc msg error.\n"); goto func_exit; } memset(msg, 0, msg_len); msg_len = ezcfg_http_write_message(http, msg, msg_len); ezcfg_worker_write(worker, msg, msg_len); goto func_exit; } func_exit: if (accept_language != NULL) free(accept_language); if (msg != NULL) free(msg); if (ssi != NULL) ezcfg_ssi_delete(ssi); }