Line data Source code
1 : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2 : * Copyright (C) 1998-1999 Brian Bruns
3 : * Copyright (C) 2015 Frediano Ziglio
4 : *
5 : * This library is free software; you can redistribute it and/or
6 : * modify it under the terms of the GNU Library General Public
7 : * License as published by the Free Software Foundation; either
8 : * version 2 of the License, or (at your option) any later version.
9 : *
10 : * This library is distributed in the hope that it will be useful,
11 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : * Library General Public License for more details.
14 : *
15 : * You should have received a copy of the GNU Library General Public
16 : * License along with this library; if not, write to the
17 : * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 : * Boston, MA 02111-1307, USA.
19 : */
20 :
21 : #include "common.h"
22 : #include <freetds/convert.h>
23 :
24 : static int g_result = 0;
25 : static TDSCONTEXT ctx;
26 :
27 : static void
28 160 : test(const char *src, const char *intro, const char *cont, int prec, int scale, int n2s, int line)
29 : {
30 : int i;
31 : char buf[256];
32 : char result[256];
33 : CONV_RESULT cr;
34 :
35 : /* build result string from intro and cont */
36 160 : strcpy(result, intro);
37 160 : if (*cont) {
38 4224 : for (i = 0; i < sizeof(cr.n.array); ++i)
39 4224 : strcat(result, " 00");
40 128 : memcpy(result + strlen(intro) + 1, cont, strlen(cont));
41 : }
42 :
43 160 : memset(&cr.n, 0, sizeof(cr.n));
44 160 : cr.n.precision = prec;
45 160 : cr.n.scale = scale;
46 160 : if (tds_convert(&ctx, SYBVARCHAR, src, strlen(src), SYBNUMERIC, &cr) < 0)
47 32 : strcpy(buf, "error");
48 : else {
49 128 : sprintf(buf, "prec=%d scale=%d", cr.n.precision, cr.n.scale);
50 4352 : for (i = 0; i < sizeof(cr.n.array); ++i)
51 4224 : sprintf(strchr(buf, 0), " %02X", cr.n.array[i]);
52 : }
53 160 : printf("%s\n", buf);
54 160 : if (strcmp(buf, result) != 0) {
55 0 : fprintf(stderr, "line %d: Failed! Should be\n\t%s\n", line, result);
56 0 : g_result = 1;
57 : }
58 :
59 160 : if (!n2s || strcmp(buf, "error") == 0)
60 56 : return;
61 104 : tds_numeric_to_string(&cr.n, buf);
62 104 : printf("%s\n", buf);
63 104 : if (strcmp(buf, src) != 0) {
64 0 : fprintf(stderr, "line %d: Failed! Should be\n\t%s\n", line, src);
65 0 : g_result = 1;
66 : }
67 : }
68 :
69 : #define test(a,b,c,d,e,f) test(a,b,c,d,e,f,__LINE__)
70 :
71 : int
72 8 : main(void)
73 : {
74 : /* very long string for test buffer overflow */
75 : int i;
76 : char long_test[201];
77 :
78 8 : memset(&ctx, 0, sizeof(ctx));
79 :
80 8 : printf("test some valid values..\n");
81 8 : test(" 1234", "prec=18 scale=0", "00 00 00 00 00 00 00 04 D2", 18, 0, 0);
82 8 : test("1234567890", "prec=18 scale=0", "00 00 00 00 00 49 96 02 D2", 18, 0, 1);
83 8 : test("123456789012345678", "prec=18 scale=0", "00 01 B6 9B 4B A6 30 F3 4E", 18, 0, 1);
84 8 : test("999999999999999999", "prec=18 scale=0", "00 0D E0 B6 B3 A7 63 FF FF", 18, 0, 1);
85 :
86 8 : printf("test overflow..\n");
87 8 : test("123456789012345678901234567890", "error", "", 18, 0, 0);
88 :
89 8 : long_test[0] = 0;
90 168 : for (i = 0; i < 20; ++i)
91 160 : strcat(long_test, "1234567890");
92 8 : test(long_test, "error", "", 18, 0, 0);
93 :
94 8 : memcpy(long_test, "1234.", 5);
95 8 : test(long_test, "prec=18 scale=0", "00 00 00 00 00 00 00 04 D2", 18, 0, 0);
96 :
97 8 : test("123456789012345678901234567890", "prec=38 scale=0", "00 00 00 00 01 8E E9 0F F6 C3 73 E0 EE 4E 3F 0A D2", 38, 0, 1);
98 8 : test("1234567890123456789012345678901234567890123456789012345678901234567890-00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00", "error", "", 38, 0, 1);
99 8 : test("99999999999999999999999999999999999999",
100 : "prec=38 scale=0", "00 4B 3B 4C A8 5A 86 C4 7A 09 8A 22 3F FF FF FF FF", 38, 0, 1);
101 8 : test("100000000000000000000000000000000000000", "error", "", 38, 0, 1);
102 :
103 8 : test(" 1234", "prec=18 scale=1", "00 00 00 00 00 00 00 30 34", 18, 1, 0);
104 :
105 8 : test("1234.56", "prec=18 scale=2", "00 00 00 00 00 00 01 E2 40", 18, 2, 1);
106 :
107 8 : test("0.00123", "prec=18 scale=5", "00 00 00 00 00 00 00 00 7B", 18, 5, 1);
108 :
109 8 : test("0.0123", "prec=18 scale=4", "00 00 00 00 00 00 00 00 7B", 18, 4, 1);
110 :
111 8 : test("0.123", "prec=18 scale=3", "00 00 00 00 00 00 00 00 7B", 18, 3, 1);
112 :
113 8 : test("1.23", "prec=18 scale=2", "00 00 00 00 00 00 00 00 7B", 18, 2, 1);
114 :
115 8 : test("12.3", "prec=18 scale=1", "00 00 00 00 00 00 00 00 7B", 18, 1, 1);
116 :
117 8 : test("0.0000", "prec=18 scale=4", "00", 18, 4, 1);
118 :
119 8 : test("0", "prec=18 scale=0", "00", 18, 0, 1);
120 :
121 8 : return g_result;
122 : }
|