FreeRDP
Loading...
Searching...
No Matches
TestEncodedTypes.c
1
20#include <stdio.h>
21#include <float.h>
22#include <limits.h>
23#include <math.h>
24
25#include <winpr/crypto.h>
26#include <freerdp/utils/encoded_types.h>
27
28#ifndef MIN
29#define MIN(x, y) ((x) < (y)) ? (x) : (y)
30#endif
31
32#ifndef MAX
33#define MAX(x, y) ((x) > (y)) ? (x) : (y)
34#endif
35
36static BOOL test_signed_integer_read_write_equal(INT32 value)
37{
38 INT32 rvalue = 0;
39 BYTE buffer[32] = WINPR_C_ARRAY_INIT;
40 wStream sbuffer = WINPR_C_ARRAY_INIT;
41 wStream* s = Stream_StaticInit(&sbuffer, buffer, sizeof(buffer));
42 WINPR_ASSERT(s);
43
44 if (!freerdp_write_four_byte_signed_integer(s, value))
45 {
46 (void)fprintf(stderr, "[%s(%" PRId32 ")] failed to write to stream\n", __func__, value);
47 return FALSE;
48 }
49 Stream_ResetPosition(s);
50
51 if (!freerdp_read_four_byte_signed_integer(s, &rvalue))
52 {
53 (void)fprintf(stderr, "[%s(%" PRId32 ")] failed to read from stream\n", __func__, value);
54 return FALSE;
55 }
56 if (value != rvalue)
57 {
58 (void)fprintf(stderr, "[%s(%" PRId32 ")] read invalid value %" PRId32 " from stream\n",
59 __func__, value, rvalue);
60 return FALSE;
61 }
62 return TRUE;
63}
64
65static BOOL test_signed_integer_write_oor(INT32 value)
66{
67 BYTE buffer[32] = WINPR_C_ARRAY_INIT;
68 wStream sbuffer = WINPR_C_ARRAY_INIT;
69 wStream* s = Stream_StaticInit(&sbuffer, buffer, sizeof(buffer));
70 WINPR_ASSERT(s);
71
72 if (freerdp_write_four_byte_signed_integer(s, value))
73 {
74 (void)fprintf(stderr,
75 "[%s(%" PRId32 ")] out of range value not detected and written to stream\n",
76 __func__, value);
77 return FALSE;
78 }
79 return TRUE;
80}
81
82static BOOL test_signed_integers(void)
83{
84 const INT32 outofrange[] = { FREERDP_FOUR_BYTE_SIGNED_INT_MAX + 1,
85 FREERDP_FOUR_BYTE_SIGNED_INT_MIN - 1, INT32_MAX, INT32_MIN };
86 const INT32 limits[] = { 1, 0, -1, FREERDP_FOUR_BYTE_SIGNED_INT_MAX,
87 FREERDP_FOUR_BYTE_SIGNED_INT_MIN };
88
89 for (size_t x = 0; x < ARRAYSIZE(limits); x++)
90 {
91 if (!test_signed_integer_read_write_equal(limits[x]))
92 return FALSE;
93 }
94 for (size_t x = 0; x < ARRAYSIZE(outofrange); x++)
95 {
96 if (!test_signed_integer_write_oor(outofrange[x]))
97 return FALSE;
98 }
99 for (size_t x = 0; x < 100000; x++)
100 {
101 INT32 val = 0;
102 if (winpr_RAND(&val, sizeof(val)) < 0)
103 return FALSE;
104 val = MAX(val, 0);
105 val = MIN(val, FREERDP_FOUR_BYTE_SIGNED_INT_MAX);
106
107 const INT32 nval = -val;
108 if (!test_signed_integer_read_write_equal(val))
109 return FALSE;
110 if (!test_signed_integer_read_write_equal(nval))
111 return FALSE;
112 }
113 return TRUE;
114}
115
116static BOOL test_float_read_write_equal(double value)
117{
118 BYTE exp = 0;
119 double rvalue = FP_NAN;
120 BYTE buffer[32] = WINPR_C_ARRAY_INIT;
121 wStream sbuffer = WINPR_C_ARRAY_INIT;
122 wStream* s = Stream_StaticInit(&sbuffer, buffer, sizeof(buffer));
123 WINPR_ASSERT(s);
124
125 if (!freerdp_write_four_byte_float(s, value))
126 {
127 (void)fprintf(stderr, "[%s(%lf)] failed to write to stream\n", __func__, value);
128 return FALSE;
129 }
130 Stream_ResetPosition(s);
131
132 if (!freerdp_read_four_byte_float_exp(s, &rvalue, &exp))
133 {
134 (void)fprintf(stderr, "[%s(%lf)] failed to read from stream\n", __func__, value);
135 return FALSE;
136 }
137 const double diff = fabs(value - rvalue);
138 const double expdiff = diff * pow(10, exp);
139 if (expdiff >= 1.0)
140 {
141 (void)fprintf(stderr, "[%s(%lf)] read invalid value %lf from stream\n", __func__, value,
142 rvalue);
143 return FALSE;
144 }
145 return TRUE;
146}
147
148static BOOL test_floag_write_oor(double value)
149{
150 BYTE buffer[32] = WINPR_C_ARRAY_INIT;
151 wStream sbuffer = WINPR_C_ARRAY_INIT;
152 wStream* s = Stream_StaticInit(&sbuffer, buffer, sizeof(buffer));
153 WINPR_ASSERT(s);
154
155 if (freerdp_write_four_byte_float(s, value))
156 {
157 (void)fprintf(stderr, "[%s(%lf)] out of range value not detected and written to stream\n",
158 __func__, value);
159 return FALSE;
160 }
161 return TRUE;
162}
163
164static double get(void)
165{
166 double val = NAN;
167 do
168 {
169 if (winpr_RAND(&val, sizeof(val)) < 0)
170 {
171 // NOLINTNEXTLINE(concurrency-mt-unsafe)
172 exit(-1);
173 }
174 } while ((val < 0.0) || (val > FREERDP_FOUR_BYTE_FLOAT_MAX) || isnan(val) || isinf(val));
175 return val;
176}
177
178static BOOL test_floats(void)
179{
180 const double outofrange[] = { FREERDP_FOUR_BYTE_FLOAT_MAX + 1, FREERDP_FOUR_BYTE_FLOAT_MIN - 1,
181 DBL_MAX, -DBL_MAX };
182 const double limits[] = { 100045.26129238126, 1, 0, -1, FREERDP_FOUR_BYTE_FLOAT_MAX,
183 FREERDP_FOUR_BYTE_FLOAT_MIN };
184
185 for (size_t x = 0; x < ARRAYSIZE(limits); x++)
186 {
187 if (!test_float_read_write_equal(limits[x]))
188 return FALSE;
189 }
190 for (size_t x = 0; x < ARRAYSIZE(outofrange); x++)
191 {
192 if (!test_floag_write_oor(outofrange[x]))
193 return FALSE;
194 }
195 for (size_t x = 0; x < 100000; x++)
196 {
197 double val = get();
198
199 const double nval = -val;
200 if (!test_float_read_write_equal(val))
201 return FALSE;
202 if (!test_float_read_write_equal(nval))
203 return FALSE;
204 }
205 return TRUE;
206}
207
208int TestEncodedTypes(int argc, char* argv[])
209{
210 WINPR_UNUSED(argc);
211 WINPR_UNUSED(argv);
212
213 if (!test_signed_integers())
214 return -1;
215 if (!test_floats())
216 return -1;
217 return 0;
218}