LCOV - code coverage report
Current view: top level - src/odbc/unittests - connection_string_parse.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 68 72 94.4 %
Date: 2025-01-18 12:13:41 Functions: 10 10 100.0 %

          Line data    Source code
       1             : #include "common.h"
       2             : #include <assert.h>
       3             : #include "freetds/odbc.h"
       4             : 
       5             : 
       6             : #ifdef _WIN32
       7             : HINSTANCE hinstFreeTDS;
       8             : #endif
       9             : 
      10             : static void
      11          96 : assert_equal_dstr(DSTR a, const char *b)
      12             : {
      13         192 :         assert(b && strcmp(tds_dstr_cstr(&a), b)==0);
      14          96 : }
      15             : 
      16             : static void
      17          96 : assert_equal_str(TDS_PARSED_PARAM param, const char *b)
      18             : {
      19             :         /* printf("param %.*s b %s\n", (int) param.len, param.p, b); */
      20          96 :         assert(b && strlen(b) == param.len && strncmp(param.p, b, param.len)==0);
      21          96 : }
      22             : 
      23             : typedef void check_func_t(TDSLOGIN *login, TDS_PARSED_PARAM *parsed_params);
      24             : 
      25             : static void
      26          56 : test_common(const char *name, const char *connect_string, check_func_t *check_func)
      27             : {
      28             :         TDSLOGIN *login;
      29          56 :         TDS_ERRS errs = {0};
      30             :         TDSLOCALE *locale;
      31             :         TDS_PARSED_PARAM parsed_params[ODBC_PARAM_SIZE];
      32             : 
      33          56 :         const char *connect_string_end = connect_string + strlen(connect_string);
      34          56 :         login = tds_alloc_login(0);
      35          56 :         if (!tds_set_language(login, "us_english")) {
      36           0 :                 fprintf(stderr, "Error setting language in test '%s'\n", name);
      37           0 :                 exit(1);
      38             :         }
      39          56 :         locale = tds_alloc_locale();
      40          56 :         login = tds_init_login(login, locale);
      41             : 
      42          56 :         odbc_errs_reset(&errs);
      43             : 
      44          56 :         if (!odbc_parse_connect_string(&errs, connect_string, connect_string_end, login, parsed_params)) {
      45           8 :                 assert(errs.num_errors > 0);
      46           8 :                 if (check_func) {
      47           0 :                         fprintf(stderr, "Error parsing string in test '%s'\n", name);
      48           0 :                         exit(1);
      49             :                 }
      50             :         } else {
      51          48 :                 assert(errs.num_errors == 0);
      52          48 :                 assert(check_func != NULL);
      53          48 :                 check_func(login, parsed_params);
      54             :         }
      55             : 
      56          56 :         odbc_errs_reset(&errs);
      57          56 :         tds_free_login(login);
      58          56 :         tds_free_locale(locale);
      59          56 : }
      60             : 
      61             : #define CHECK(name, s) \
      62             :         static const char *name ## _connect_string = s; \
      63             :         static void name ## _check(TDSLOGIN *login, TDS_PARSED_PARAM *parsed_params); \
      64             :         static void name(void) { \
      65             :                 test_common(#name, name ## _connect_string, name ## _check); \
      66             :         } \
      67             :         static void name ## _check(TDSLOGIN *login, TDS_PARSED_PARAM *parsed_params)
      68             : 
      69             : #define CHECK_ERROR(name, s) \
      70             :         static const char *name ## _connect_string = s; \
      71             :         static void name(void) { \
      72             :                 test_common(#name, name ## _connect_string, NULL); \
      73             :         }
      74             : 
      75          16 : CHECK(simple_string,
      76             :         "DRIVER=libtdsodbc.so;SERVER=127.0.0.1;PORT=1337;UID=test_username;PWD=test_password;DATABASE=test_db;ClientCharset=UTF-8;")
      77             : {
      78           8 :         assert_equal_str(parsed_params[ODBC_PARAM_UID], "test_username");
      79           8 :         assert_equal_dstr(login->server_name, "127.0.0.1");
      80           8 :         assert_equal_dstr(login->password, "test_password");
      81           8 :         assert_equal_str(parsed_params[ODBC_PARAM_PWD], "test_password");
      82           8 :         assert(login->port == 1337);
      83           8 : }
      84             : 
      85          16 : CHECK(simple_escaped_string,
      86             :         "DRIVER={libtdsodbc.so};SERVER={127.0.0.1};PORT={1337};UID={test_username};PWD={test_password};DATABASE={test_db};ClientCharset={UTF-8};")
      87             : {
      88           8 :         assert_equal_str(parsed_params[ODBC_PARAM_UID], "{test_username}");
      89           8 :         assert_equal_dstr(login->server_name, "127.0.0.1");
      90           8 :         assert_equal_dstr(login->password, "test_password");
      91           8 :         assert_equal_str(parsed_params[ODBC_PARAM_PWD], "{test_password}");
      92           8 :         assert(login->port == 1337);
      93           8 : }
      94             : 
      95          16 : CHECK(test_special_symbols,
      96             :         "DRIVER={libtdsodbc.so};SERVER={127.0.0.1};PORT={1337};UID={test_username};PWD={[]{}}(),;?*=!@};DATABASE={test_db};ClientCharset={UTF-8};")
      97             : {
      98           8 :         assert_equal_str(parsed_params[ODBC_PARAM_UID], "{test_username}");
      99           8 :         assert_equal_dstr(login->server_name, "127.0.0.1");
     100           8 :         assert_equal_dstr(login->password, "[]{}(),;?*=!@");
     101           8 :         assert_equal_str(parsed_params[ODBC_PARAM_PWD], "{[]{}}(),;?*=!@}");
     102           8 :         assert(login->port == 1337);
     103           8 : }
     104             : 
     105          16 : CHECK(password_contains_curly_braces,
     106             :         "DRIVER={libtdsodbc.so};SERVER={127.0.0.1};PORT={1337};UID={test_username};PWD={test{}}_password};DATABASE={test_db};ClientCharset={UTF-8};")
     107             : {
     108           8 :         assert_equal_str(parsed_params[ODBC_PARAM_UID], "{test_username}");
     109           8 :         assert_equal_dstr(login->server_name, "127.0.0.1");
     110           8 :         assert_equal_dstr(login->password, "test{}_password");
     111           8 :         assert_equal_str(parsed_params[ODBC_PARAM_PWD], "{test{}}_password}");
     112           8 :         assert(login->port == 1337);
     113           8 : }
     114             : 
     115          16 : CHECK(password_contains_curly_braces_and_separator,
     116             :         "DRIVER={libtdsodbc.so};SERVER={127.0.0.1};PORT={1337};UID={test_username};PWD={test{}};_password};DATABASE={test_db};ClientCharset={UTF-8};")
     117             : {
     118           8 :         assert_equal_str(parsed_params[ODBC_PARAM_UID], "{test_username}");
     119           8 :         assert_equal_dstr(login->server_name, "127.0.0.1");
     120           8 :         assert_equal_dstr(login->password, "test{};_password");
     121           8 :         assert_equal_str(parsed_params[ODBC_PARAM_PWD], "{test{}};_password}");
     122           8 :         assert(login->port == 1337);
     123           8 : }
     124             : 
     125          16 : CHECK(password_bug_report,
     126             :         "Driver=FreeTDS;Server=1.2.3.4;Port=1433;Database=test;uid=test_user;pwd={p@ssw0rd}")
     127             : {
     128           8 :         assert_equal_str(parsed_params[ODBC_PARAM_UID], "test_user");
     129           8 :         assert_equal_dstr(login->server_name, "1.2.3.4");
     130           8 :         assert_equal_dstr(login->password, "p@ssw0rd");
     131           8 :         assert_equal_str(parsed_params[ODBC_PARAM_PWD], "{p@ssw0rd}");
     132           8 :         assert(login->port == 1433);
     133           8 : }
     134             : 
     135             : /* unfinished "pwd", the "Port" before "pwd" is to reveal a leak */
     136           8 : CHECK_ERROR(unfinished,
     137             :         "Driver=FreeTDS;Server=1.2.3.4;Port=1433;pwd={p@ssw0rd");
     138             : 
     139             : int
     140           8 : main(void)
     141             : {
     142             : #ifdef _WIN32
     143             :         hinstFreeTDS = GetModuleHandle(NULL);
     144             : #endif
     145             : 
     146             :         simple_string();
     147             : 
     148             :         simple_escaped_string();
     149             : 
     150             :         password_contains_curly_braces();
     151             : 
     152             :         test_special_symbols();
     153             : 
     154             :         password_contains_curly_braces_and_separator();
     155             : 
     156             :         password_bug_report();
     157             : 
     158             :         unfinished();
     159             : 
     160             :         return 0;
     161             : }

Generated by: LCOV version 1.13