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

Generated by: LCOV version 1.13