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