Line data Source code
1 : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2 : * Copyright (C) 2015 Frediano Ziglio
3 : *
4 : * This library is free software; you can redistribute it and/or
5 : * modify it under the terms of the GNU Library General Public
6 : * License as published by the Free Software Foundation; either
7 : * version 2 of the License, or (at your option) any later version.
8 : *
9 : * This library is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : * Library General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU Library General Public
15 : * License along with this library; if not, write to the
16 : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 : * Boston, MA 02111-1307, USA.
18 : */
19 :
20 : /*
21 : * Check sending integer till they overlap a packet.
22 : * This is to check if an integer can spread in multiple
23 : * packets. The problem raise from internal implementation
24 : * and how is handled the overlapping.
25 : */
26 : #include "common.h"
27 : #include <freetds/checks.h>
28 :
29 : static const char select_query[] = "\nselect 'test'";
30 :
31 : static void
32 8 : unfinished_query_test(TDSSOCKET *tds)
33 : {
34 : int char_len;
35 : char *buf, *p;
36 : int i, len;
37 : union {
38 : TDS_USMALLINT si;
39 : TDS_UINT i;
40 : TDS_INT8 i8;
41 : char buf[8];
42 : } conv;
43 :
44 8 : if (IS_TDS72_PLUS(tds->conn))
45 : return;
46 :
47 6 : tds_init_write_buf(tds);
48 :
49 : /* try to build an invalid (unfinished) query split in two packets */
50 6 : char_len = IS_TDS7_PLUS(tds->conn) ? 2 : 1;
51 6 : buf = tds_new0(char, tds->out_buf_max + 200);
52 6 : memset(buf, '-', tds->out_buf_max + 200);
53 6 : strcpy(buf + (tds->out_buf_max - 8) / char_len - strlen(select_query) + 1, select_query);
54 6 : memset(strchr(buf, 0), 0, 16);
55 :
56 : /* convert if needed */
57 6 : len = strlen(buf);
58 12274 : for (i = len; --i >= 0; ) {
59 12262 : char c = buf[i];
60 12262 : buf[i * char_len + 0] = c;
61 12262 : if (IS_TDS7_PLUS(tds->conn))
62 8180 : buf[i * char_len + 1] = 0;
63 : }
64 6 : len *= char_len;
65 :
66 : /* send the query using tds_put_int8, not aligned */
67 6 : tds->out_flag = TDS_QUERY;
68 6 : if (tds_set_state(tds, TDS_WRITING) != TDS_WRITING)
69 0 : exit(1);
70 6 : p = buf;
71 6 : memcpy(conv.buf, p, 2);
72 : #ifdef WORDS_BIGENDIAN
73 : tds_swap_bytes(conv.buf, 2);
74 : #endif
75 6 : tds_put_smallint(tds, conv.si);
76 6 : p += 2;
77 2560 : for (; p < buf + len; p += 8) {
78 2554 : CHECK_TDS_EXTRA(tds);
79 2554 : memcpy(conv.buf, p, 8);
80 : #ifdef WORDS_BIGENDIAN
81 : tds_swap_bytes(conv.buf, 8);
82 : #endif
83 2554 : tds_put_int8(tds, conv.i8);
84 : }
85 6 : tds_flush_packet(tds);
86 6 : tds_set_state(tds, TDS_PENDING);
87 :
88 : /* check result was fine */
89 6 : if (TDS_FAILED(tds_process_simple_query(tds))) {
90 0 : fprintf(stderr, "Error in prepared query\n");
91 0 : exit(1);
92 : }
93 6 : free(buf);
94 : }
95 :
96 : int
97 8 : main(void)
98 : {
99 : TDSLOGIN *login;
100 : TDSSOCKET *tds;
101 : int ret;
102 8 : int verbose = 0;
103 : TDS_INT8 i8;
104 : unsigned limit;
105 :
106 8 : printf("%s: Testing login, logout\n", __FILE__);
107 8 : ret = try_tds_login(&login, &tds, __FILE__, verbose);
108 8 : if (ret != TDS_SUCCESS) {
109 0 : fprintf(stderr, "try_tds_login() failed\n");
110 0 : return 1;
111 : }
112 :
113 8 : unfinished_query_test(tds);
114 :
115 8 : tds->out_flag = TDS_QUERY;
116 8 : if (tds_set_state(tds, TDS_WRITING) != TDS_WRITING) {
117 : return 1;
118 : }
119 :
120 8 : tds_put_n(tds, "aaa", 3);
121 8 : limit = tds->out_buf_max / 8 + 100;
122 4392 : for (i8 = 0; i8 < limit; ++i8) {
123 4384 : CHECK_TDS_EXTRA(tds);
124 4384 : tds_put_int8(tds, i8);
125 : }
126 :
127 8 : tds_send_cancel(tds);
128 8 : tds_process_simple_query(tds);
129 :
130 8 : try_tds_logout(login, tds, verbose);
131 8 : return 0;
132 : }
|