1
1
#include <err.h>
2
+ #include <limits.h>
2
3
#include <math.h>
3
4
#include <stdbool.h>
4
5
#include <stdint.h>
@@ -33,7 +34,7 @@ static void des_object_begin(void *arg);
33
34
static void des_object_end (void * arg );
34
35
static void des_map_begin (void * arg );
35
36
static void des_map_end (void * arg );
36
- static void des_object_ref (void * arg , uint32_t id );
37
+ static void des_object_ref (void * arg , long id );
37
38
// des_error_begin: followed by des_object_begin + des_object_end calls
38
39
static void des_error_begin (void * arg );
39
40
static void des_error_end (void * arg );
@@ -42,7 +43,7 @@ static void des_error_end(void *arg);
42
43
// have to worry about allocation failures for small payloads
43
44
typedef struct Buf {
44
45
uint8_t * buf ;
45
- uint32_t len , cap ;
46
+ size_t len , cap ;
46
47
uint8_t buf_s [48 ];
47
48
} Buf ;
48
49
@@ -54,13 +55,18 @@ typedef struct Ser {
54
55
static const uint8_t the_nan [8 ] = {0 ,0 ,0 ,0 ,0 ,0 ,0xF8 ,0x7F }; // canonical nan
55
56
56
57
// note: returns |v| if v in [0,1,2]
57
- static inline uint32_t next_power_of_two (uint32_t v ) {
58
+ static inline size_t next_power_of_two (size_t v ) {
58
59
v -= 1 ;
59
60
v |= v >> 1 ;
60
61
v |= v >> 2 ;
61
62
v |= v >> 4 ;
62
63
v |= v >> 8 ;
64
+ #if SIZE_MAX >= 0xFFFFFFFFU
63
65
v |= v >> 16 ;
66
+ #endif
67
+ #if SIZE_MAX >= 0xFFFFFFFFFFFFFFFFULL
68
+ v |= v >> 32 ;
69
+ #endif
64
70
v += 1 ;
65
71
return v ;
66
72
}
@@ -240,24 +246,26 @@ static void ser_num(Ser *s, double v)
240
246
}
241
247
242
248
// ser_bigint: |n| is in bytes, not quadwords
243
- static void ser_bigint (Ser * s , const uint64_t * p , size_t n , int sign )
249
+ static void ser_bigint (Ser * s , const void * p , size_t stride , size_t n , int sign )
244
250
{
251
+ static const uint8_t zero [16 ] = {0 };
252
+
245
253
if (* s -> err )
246
254
return ;
247
- if (n % 8 ) {
255
+ if (n % stride ) {
248
256
snprintf (s -> err , sizeof (s -> err ), "bad bigint" );
249
257
return ;
250
258
}
251
259
w_byte (s , 'Z' );
252
260
// chop off high all-zero words
253
- n /= 8 ;
261
+ n /= stride ;
254
262
while (n -- )
255
- if (p [ n ] )
263
+ if (! memcmp ( & (( uint8_t * ) p )[ n * stride ], zero , stride ) )
256
264
break ;
257
265
if (n == (size_t )-1 ) {
258
266
w_byte (s , 0 ); // normalized zero
259
267
} else {
260
- n = 8 * n + 8 ;
268
+ n = ( n + 1 ) * stride ;
261
269
w_varint (s , 2 * n + (sign < 0 ));
262
270
w (s , p , n );
263
271
}
@@ -276,7 +284,7 @@ static void ser_int(Ser *s, int64_t v)
276
284
return ser_num (s , v );
277
285
t = v < 0 ? - v : v ;
278
286
sign = v < 0 ? -1 : 1 ;
279
- ser_bigint (s , & t , sizeof (t ), sign );
287
+ ser_bigint (s , & t , sizeof (t ), sizeof ( t ), sign );
280
288
} else {
281
289
w_byte (s , 'I' );
282
290
w_zigzag (s , v );
@@ -324,26 +332,26 @@ static void ser_object_begin(Ser *s)
324
332
}
325
333
326
334
// |count| is the property count
327
- static void ser_object_end (Ser * s , uint32_t count )
335
+ static void ser_object_end (Ser * s , size_t count )
328
336
{
329
337
w_byte (s , '{' );
330
338
w_varint (s , count );
331
339
}
332
340
333
- static void ser_object_ref (Ser * s , uint32_t id )
341
+ static void ser_object_ref (Ser * s , size_t id )
334
342
{
335
343
w_byte (s , '^' );
336
344
w_varint (s , id );
337
345
}
338
346
339
- static void ser_array_begin (Ser * s , uint32_t count )
347
+ static void ser_array_begin (Ser * s , size_t count )
340
348
{
341
349
w_byte (s , 'A' ); // 'A'=dense, 'a'=sparse
342
350
w_varint (s , count ); // element count
343
351
}
344
352
345
353
// |count| is the element count
346
- static void ser_array_end (Ser * s , uint32_t count )
354
+ static void ser_array_end (Ser * s , size_t count )
347
355
{
348
356
w_byte (s , '$' );
349
357
w_varint (s , 0 ); // property count, always zero
@@ -569,7 +577,7 @@ static int des1(char (*err)[64], const uint8_t **p, const uint8_t *pe,
569
577
return bail (err , "negative zero bigint" );
570
578
if (pe - * p < (int64_t )u )
571
579
goto too_short ;
572
- des_bigint (arg , * p , u , 1 - 2 * t );
580
+ des_bigint (arg , * p , u , ( int ) ( 1 - 2 * t ) );
573
581
* p += u ;
574
582
break ;
575
583
case 'R' : // RegExp, deserialized as string
0 commit comments