| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524 |
- /* _
- * ___ __ _ __ _ _ _(_)
- * / __|/ _` |/ _` | | | | |
- * \__ \ (_| | (_| | |_| | |
- * |___/\__,_|\__, |\__,_|_|
- * |___/
- *
- * Cross-platform library which helps to develop web servers or frameworks.
- *
- * Copyright (C) 2016-2024 Silvio Clecio <[email protected]>
- *
- * Sagui library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * Sagui library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with Sagui library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #include "sg_assert.h"
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #ifdef _WIN32
- #include <ws2tcpip.h>
- #include <winsock2.h>
- #include <windows.h>
- #else /* _WIN32 */
- #include <sys/socket.h>
- #endif /* _WIN32 */
- #include "sg_macros.h"
- #include "sg_utils.h"
- #include <sagui.h>
- static void test__strdup(void) {
- char *str1, *str2;
- ASSERT(!sg__strdup(NULL));
- str1 = sg__strdup("");
- ASSERT(strcmp(str1, "") == 0);
- sg_free(str1);
- str1 = sg__strdup("abc123");
- ASSERT(strcmp(str1, "abc123") == 0);
- str2 = sg__strdup(str1);
- ASSERT(str1 != str2);
- ASSERT(strcmp(str1, str2) == 0);
- sg_free(str1);
- sg_free(str2);
- }
- static void test__pow(void) {
- ASSERT(sg__pow(1, 2) == 0);
- }
- static void test__fmod(void) {
- ASSERT(sg__fmod(1, 2) == 0);
- }
- static void test__toasciilower(void) {
- char str[100];
- memset(str, 0, sizeof(str));
- ASSERT(strcmp(str, "") == 0);
- sg__toasciilower(str);
- ASSERT(strcmp(str, "") == 0);
- sprintf(str, "A");
- ASSERT(strcmp(str, "A") == 0);
- sg__toasciilower(str);
- ASSERT(strcmp(str, "a") == 0);
- sprintf(str, "ABC");
- sg__toasciilower(str);
- ASSERT(strcmp(str, "abc") == 0);
- sprintf(str, "ABC123 def456");
- sg__toasciilower(str);
- ASSERT(strcmp(str, "abc123 def456") == 0);
- sprintf(str, "ABC");
- sg__toasciilower(str);
- ASSERT(strcmp(str, "abc") == 0);
- sprintf(str, "ABÇñãÁÊD");
- sg__toasciilower(str);
- ASSERT(strcmp(str, "abÇñãÁÊd") == 0);
- }
- static void test__strjoin(void) {
- char *str;
- ASSERT(!sg__strjoin(0, "", ""));
- ASSERT(!sg__strjoin('/', NULL, ""));
- ASSERT(!sg__strjoin('/', "", NULL));
- str = sg__strjoin('/', "", "");
- ASSERT(strcmp(str, "") == 0);
- sg_free(str);
- str = sg__strjoin('/', "abc", "");
- ASSERT(strcmp(str, "abc") == 0);
- sg_free(str);
- str = sg__strjoin('/', "", "123");
- ASSERT(strcmp(str, "123") == 0);
- sg_free(str);
- str = sg__strjoin('/', "abc", "123");
- ASSERT(strcmp(str, "abc/123") == 0);
- sg_free(str);
- str = sg__strjoin('/', "a", "b");
- ASSERT(strcmp(str, "a/b") == 0);
- sg_free(str);
- }
- static void test__is_cookie_name(void) {
- char *str = strdup("");
- ASSERT(sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("a");
- ASSERT(sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc");
- ASSERT(sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc_123");
- ASSERT(sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("123_abc");
- ASSERT(sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc-123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc 123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc|123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abç");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc\a123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc(123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc)123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc<123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc>123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc@123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc,123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc;123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc:123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc\\123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc\"123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc/123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc[123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc]123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc?123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc=123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc{123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- str = strdup("abc}123");
- ASSERT(!sg__is_cookie_name(str));
- sg_free(str);
- }
- static void test__is_cookie_val(void) {
- char *str = strdup("");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("a");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("abc");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("abc_123");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("123_abc");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("abc=123");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("abc-123");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("\"abc123\"");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("abc 123");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("abc\"123");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("abc,123");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("abc;123");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("abc\\123");
- ASSERT(sg__is_cookie_val(str));
- sg_free(str);
- str = strdup("abc\a123");
- ASSERT(!sg__is_cookie_val(str));
- sg_free(str);
- }
- static void test_version(void) {
- const char *ver_original;
- char ver_local[9];
- size_t ver_len;
- ASSERT(sg_version() == ((SG_VERSION_MAJOR << 16) | (SG_VERSION_MINOR << 8) |
- (SG_VERSION_PATCH)));
- ver_original = sg_version_str();
- ASSERT(ver_original);
- ver_len = strlen(ver_original);
- ASSERT(ver_len > 0);
- sprintf(ver_local, "%d.%d.%d", SG_VERSION_MAJOR, SG_VERSION_MINOR,
- SG_VERSION_PATCH);
- ASSERT(strcmp(ver_original, ver_local) == 0);
- ASSERT(ver_original[ver_len] == '\0');
- }
- static int mm_tester = 0;
- static void *mm_malloc(size_t size) {
- mm_tester = size;
- return &mm_tester;
- }
- static void *mm_realloc(void *ptr, size_t size) {
- *((int *) ptr) = size;
- return ptr;
- }
- static void mm_free(void *ptr) {
- *((int *) ptr) = 0;
- }
- static void test_mm_set(void) {
- ASSERT(sg_mm_set(NULL, mm_realloc, mm_free) == EINVAL);
- ASSERT(sg_mm_set(mm_malloc, NULL, mm_free) == EINVAL);
- ASSERT(sg_mm_set(mm_malloc, mm_realloc, NULL) == EINVAL);
- ASSERT(sg_mm_set(mm_malloc, mm_realloc, mm_free) == 0);
- mm_tester = 0;
- ASSERT(sg_malloc(123) == &mm_tester);
- ASSERT(mm_tester == 123);
- ASSERT(sg_realloc(&mm_tester, 456) == &mm_tester);
- ASSERT(mm_tester == 456);
- sg_free(&mm_tester);
- ASSERT(mm_tester == 0);
- sg_mm_set(malloc, realloc, free);
- }
- static void test_malloc(void) {
- char *buf;
- #define TEST_MEM_BUF_LEN 10
- buf = sg_malloc(TEST_MEM_BUF_LEN);
- ASSERT(buf);
- memset(buf, 'a', TEST_MEM_BUF_LEN - 1);
- buf[TEST_MEM_BUF_LEN - 1] = '\0';
- ASSERT(strlen(buf) == TEST_MEM_BUF_LEN - 1);
- #undef TEST_MEM_BUF_LEN
- sg_free(buf);
- }
- static void test_alloc(void) {
- char *buf;
- #define TEST_MEM_BUF_LEN 10
- buf = sg_alloc(TEST_MEM_BUF_LEN);
- ASSERT(buf);
- for (unsigned char i = 0; i < TEST_MEM_BUF_LEN; i++)
- ASSERT(buf[i] == 0);
- memset(buf, 'a', TEST_MEM_BUF_LEN - 1);
- buf[TEST_MEM_BUF_LEN - 1] = '\0';
- ASSERT(strlen(buf) == TEST_MEM_BUF_LEN - 1);
- #undef TEST_MEM_BUF_LEN
- sg_free(buf);
- }
- static void test_realloc(void) {
- char *buf;
- #define TEST_MEM_BUF_LEN 10
- buf = sg_alloc(TEST_MEM_BUF_LEN / 2);
- ASSERT(buf);
- buf = sg_realloc(buf, TEST_MEM_BUF_LEN);
- ASSERT(buf);
- memset(buf, 'a', TEST_MEM_BUF_LEN - 1);
- buf[TEST_MEM_BUF_LEN - 1] = '\0';
- ASSERT(strlen(buf) == TEST_MEM_BUF_LEN - 1);
- #undef TEST_MEM_BUF_LEN
- sg_free(buf);
- }
- static void test_free(void) {
- sg_free(NULL);
- }
- static double math_tester_x = 0;
- static double math_tester_y = 0;
- static double math_pow(double x, double y) {
- math_tester_x = x;
- math_tester_y = y;
- return 789;
- }
- static double math_fmod(double x, double y) {
- math_tester_x = x;
- math_tester_y = y;
- return 789;
- }
- static void test_math_set(void) {
- ASSERT(sg_math_set(NULL, math_fmod) == EINVAL);
- ASSERT(sg_math_set(math_pow, NULL) == EINVAL);
- ASSERT(sg_math_set(math_pow, math_fmod) == 0);
- math_tester_x = 0;
- math_tester_y = 0;
- ASSERT(sg__pow(123, 456) == 789);
- ASSERT(math_tester_x == 123);
- ASSERT(math_tester_y == 456);
- math_tester_x = 0;
- math_tester_y = 0;
- ASSERT(sg__fmod(123, 456) == 789);
- ASSERT(math_tester_x == 123);
- ASSERT(math_tester_y == 456);
- sg_math_set(sg__pow, sg__fmod);
- }
- static void test_strerror(void) {
- char err[256];
- ASSERT(!sg_strerror(0, NULL, sizeof(err)));
- ASSERT(!sg_strerror(0, err, 0));
- ASSERT(sg_strerror(EINTR, err, sizeof(err)) == err);
- ASSERT(strcmp(err, strerror(EINTR)) == 0);
- ASSERT(sg_strerror(EINVAL, err, sizeof(err)) == err);
- ASSERT(strcmp(err, strerror(EINVAL)) == 0);
- }
- static void test_is_post(void) {
- ASSERT(!sg_is_post(NULL));
- ASSERT(!sg_is_post(""));
- ASSERT(!sg_is_post("abc"));
- ASSERT(!sg_is_post("GET"));
- ASSERT(!sg_is_post("HEAD"));
- ASSERT(sg_is_post("POST"));
- ASSERT(sg_is_post("PUT"));
- ASSERT(sg_is_post("DELETE"));
- ASSERT(sg_is_post("OPTIONS"));
- }
- static void test_extract_entrypoint(void) {
- char *str;
- errno = 0;
- ASSERT(!sg_extract_entrypoint(NULL));
- ASSERT(errno == EINVAL);
- ASSERT((str = sg_extract_entrypoint("")));
- ASSERT(strcmp(str, "/") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("/")));
- ASSERT(strcmp(str, "/") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("//")));
- ASSERT(strcmp(str, "/") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("///////")));
- ASSERT(strcmp(str, "/") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("foo")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("/foo")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("//foo")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("///////foo")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("foo/")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("foo//")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("/foo/")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("///foo///")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("/foo/bar")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("///foo/bar")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("/foo///bar")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("///foo///bar")));
- ASSERT(strcmp(str, "/foo") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("/a")));
- ASSERT(strcmp(str, "/a") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("/a/b")));
- ASSERT(strcmp(str, "/a") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("//a/b")));
- ASSERT(strcmp(str, "/a") == 0);
- sg_free(str);
- ASSERT((str = sg_extract_entrypoint("//a//b")));
- ASSERT(strcmp(str, "/a") == 0);
- sg_free(str);
- }
- static void test_tmpdir(void) {
- #ifdef _WIN32
- char path[MAX_PATH + 1];
- size_t len;
- #endif /* _WIN32 */
- char *tmp = sg_tmpdir();
- ASSERT(tmp != NULL);
- #if defined(_WIN32)
- len = GetTempPath(MAX_PATH + 1, path);
- if (path[len - 1] == '\\') {
- len--;
- path[len] = '\0';
- }
- ASSERT(strcmp(tmp, path) == 0);
- #elif defined(__ANDROID__) /* _WIN32 */
- ASSERT(strcmp(tmp, "/data/local/tmp") == 0);
- #elif defined(__APPLE__) /* __ANDROID__*/
- ASSERT(strncmp(tmp, getenv("TMPDIR"), strlen(tmp)) == 0);
- #else /* __APPLE__ */
- ASSERT(strcmp(tmp, "/tmp") == 0);
- #endif /* _WIN32 */
- sg_free(tmp);
- }
- static void test_ip(void) {
- struct sockaddr sa;
- char buf[46];
- memset(&sa, 0, sizeof(struct sockaddr));
- ASSERT(sg_ip(NULL, buf, sizeof(buf)) == EINVAL);
- ASSERT(sg_ip(&sa, NULL, sizeof(buf)) == EINVAL);
- ASSERT(sg_ip(&sa, buf, -1) == EINVAL);
- sa.sa_family = AF_INET;
- ASSERT(sg_ip(&sa, buf, sizeof(buf)) == 0);
- ASSERT(strcmp(buf, "0.0.0.0") == 0);
- /* we do not need massive testing for inet_ntop() since it is already tested by the glibc team. */
- }
- int main(void) {
- test__strdup();
- test__pow();
- test__fmod();
- test__toasciilower();
- test__strjoin();
- test__is_cookie_name();
- test__is_cookie_val();
- test_version();
- test_mm_set();
- test_malloc();
- test_alloc();
- test_realloc();
- test_free();
- test_math_set();
- test_strerror();
- test_is_post();
- test_extract_entrypoint();
- test_tmpdir();
- test_ip();
- return EXIT_SUCCESS;
- }
|