diff --git a/examples/http-client/Makefile b/examples/http-client/Makefile index a3a3a1f5..66c5e9f6 100644 --- a/examples/http-client/Makefile +++ b/examples/http-client/Makefile @@ -1,5 +1,7 @@ PROG ?= example CFLAGS ?= -DMG_ENABLE_LINES $(EXTRA) +ROOT ?= $(realpath $(CURDIR)/../..) +LIN = docker run -it --rm -v $(ROOT):$(ROOT) -w $(CURDIR) mdashnet/cc2 ifneq ($(MBEDTLS),) CFLAGS += -DMG_ENABLE_MBEDTLS=1 -I$(MBEDTLS)/include -I/usr/include @@ -14,9 +16,13 @@ endif all: $(PROG) $(DEBUGGER) ./$(PROG) $(ARGS) - $(PROG): main.c $(CC) ../../mongoose.c -I../.. -W -Wall $(CFLAGS) -o $(PROG) main.c +linux: all +linux: CFLAGS += -O2 -g -fsanitize=address,undefined,shift,null,return,bounds,alignment,object-size,bool,enum -static-libasan +linux: CC = $(LIN) cc +linux: DEBUGGER = $(LIN) + clean: rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb diff --git a/examples/http-client/main.c b/examples/http-client/main.c index f75c2164..9400bf2c 100644 --- a/examples/http-client/main.c +++ b/examples/http-client/main.c @@ -12,7 +12,7 @@ #include "mongoose.h" // The very first web page in history. You can replace it from command line -static const char *s_url = "http://info.cern.ch"; +static const char *s_url = "http://info.cern.ch//foo"; // Print HTTP response and signal that we're done static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { diff --git a/mongoose.c b/mongoose.c index 2314f90e..f3cf64d1 100644 --- a/mongoose.c +++ b/mongoose.c @@ -3875,19 +3875,19 @@ static struct url urlparse(const char *url) { struct url u; memset(&u, 0, sizeof(u)); for (i = 0; url[i] != '\0'; i++) { - if (i > 0 && url[i - 1] == '/' && url[i] == '/') { + if (i > 0 && u.host == 0 && url[i - 1] == '/' && url[i] == '/') { u.host = i + 1; u.port = 0; } else if (url[i] == ']') { u.port = 0; // IPv6 URLs, like http://[::1]/bar - } else if (url[i] == ':') { + } else if (url[i] == ':' && u.port == 0) { u.port = i + 1; - } else if (url[i] == '@') { + } else if (url[i] == '@' && u.user == 0 && u.pass == 0) { u.user = u.host; u.pass = u.port; u.host = i + 1; u.port = 0; - } else if (u.host && !u.uri && url[i] == '/') { + } else if (u.host && u.uri == 0 && url[i] == '/') { u.uri = i; } } @@ -4283,7 +4283,7 @@ unsigned long mg_millis(void) { #else struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); - return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + return (unsigned long) ((uint64_t) ts.tv_sec * 1000 + ts.tv_nsec / 1000000); #endif } diff --git a/src/url.c b/src/url.c index 9e35a5bb..01b50dab 100644 --- a/src/url.c +++ b/src/url.c @@ -16,19 +16,19 @@ static struct url urlparse(const char *url) { struct url u; memset(&u, 0, sizeof(u)); for (i = 0; url[i] != '\0'; i++) { - if (i > 0 && url[i - 1] == '/' && url[i] == '/') { + if (i > 0 && u.host == 0 && url[i - 1] == '/' && url[i] == '/') { u.host = i + 1; u.port = 0; } else if (url[i] == ']') { u.port = 0; // IPv6 URLs, like http://[::1]/bar - } else if (url[i] == ':') { + } else if (url[i] == ':' && u.port == 0) { u.port = i + 1; - } else if (url[i] == '@') { + } else if (url[i] == '@' && u.user == 0 && u.pass == 0) { u.user = u.host; u.pass = u.port; u.host = i + 1; u.port = 0; - } else if (u.host && !u.uri && url[i] == '/') { + } else if (u.host && u.uri == 0 && url[i] == '/') { u.uri = i; } } diff --git a/src/util.c b/src/util.c index d6e0f776..a5b590d4 100644 --- a/src/util.c +++ b/src/util.c @@ -332,6 +332,6 @@ unsigned long mg_millis(void) { #else struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts); - return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; + return (unsigned long) ((uint64_t) ts.tv_sec * 1000 + ts.tv_nsec / 1000000); #endif } diff --git a/test/unit_test.c b/test/unit_test.c index 872eb545..b8be7b6d 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -113,6 +113,11 @@ static void test_url(void) { ASSERT(vcmp(mg_url_host("p://foo"), "foo")); ASSERT(vcmp(mg_url_host("p://foo/"), "foo")); ASSERT(vcmp(mg_url_host("p://foo/x"), "foo")); + ASSERT(vcmp(mg_url_host("p://foo/x/"), "foo")); + ASSERT(vcmp(mg_url_host("p://foo/x//"), "foo")); + ASSERT(vcmp(mg_url_host("p://foo//x"), "foo")); + ASSERT(vcmp(mg_url_host("p://foo///x"), "foo")); + ASSERT(vcmp(mg_url_host("p://foo///x//"), "foo")); ASSERT(vcmp(mg_url_host("p://bar:1234"), "bar")); ASSERT(vcmp(mg_url_host("p://bar:1234/"), "bar")); ASSERT(vcmp(mg_url_host("p://bar:1234/a"), "bar")); @@ -128,6 +133,7 @@ static void test_url(void) { ASSERT(mg_url_port("x://foo:1234/xx") == 1234); ASSERT(mg_url_port("x://foo:1234") == 1234); ASSERT(mg_url_port("p://bar:1234/a") == 1234); + ASSERT(mg_url_port("p://bar:1234/a:b") == 1234); ASSERT(mg_url_port("http://bar") == 80); ASSERT(mg_url_port("http://localhost:1234") == 1234); ASSERT(mg_url_port("https://bar") == 443); @@ -138,6 +144,7 @@ static void test_url(void) { ASSERT(mg_url_port("wss://u:p@bar:123/abc") == 123); ASSERT(mg_url_port("http://u:p@[::1]/abc") == 80); ASSERT(mg_url_port("http://u:p@[::1]:2121/abc") == 2121); + ASSERT(mg_url_port("http://u:p@[::1]:2121/abc/cd:ef") == 2121); // User / pass ASSERT(vcmp(mg_url_user("p://foo"), "")); @@ -152,6 +159,7 @@ static void test_url(void) { ASSERT(vcmp(mg_url_pass("p://:p@foo"), "p")); ASSERT(vcmp(mg_url_user("p://u:p@foo"), "u")); ASSERT(vcmp(mg_url_pass("p://u:p@foo"), "p")); + ASSERT(vcmp(mg_url_pass("p://u:p@foo//a@b"), "p")); // URI ASSERT(strcmp(mg_url_uri("p://foo"), "/") == 0);