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