11#include <err.h>
2+ #include <limits.h>
23#include <math.h>
34#include <stdbool.h>
45#include <stdint.h>
@@ -33,7 +34,7 @@ static void des_object_begin(void *arg);
3334static void des_object_end (void * arg );
3435static void des_map_begin (void * arg );
3536static 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 );
3738// des_error_begin: followed by des_object_begin + des_object_end calls
3839static void des_error_begin (void * arg );
3940static void des_error_end (void * arg );
@@ -42,7 +43,7 @@ static void des_error_end(void *arg);
4243// have to worry about allocation failures for small payloads
4344typedef struct Buf {
4445 uint8_t * buf ;
45- uint32_t len , cap ;
46+ size_t len , cap ;
4647 uint8_t buf_s [48 ];
4748} Buf ;
4849
@@ -54,13 +55,18 @@ typedef struct Ser {
5455static const uint8_t the_nan [8 ] = {0 ,0 ,0 ,0 ,0 ,0 ,0xF8 ,0x7F }; // canonical nan
5556
5657// 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 ) {
5859 v -= 1 ;
5960 v |= v >> 1 ;
6061 v |= v >> 2 ;
6162 v |= v >> 4 ;
6263 v |= v >> 8 ;
64+ #if SIZE_MAX >= 0xFFFFFFFFU
6365 v |= v >> 16 ;
66+ #endif
67+ #if SIZE_MAX >= 0xFFFFFFFFFFFFFFFFULL
68+ v |= v >> 32 ;
69+ #endif
6470 v += 1 ;
6571 return v ;
6672}
@@ -240,24 +246,26 @@ static void ser_num(Ser *s, double v)
240246}
241247
242248// 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 )
244250{
251+ static const uint8_t zero [16 ] = {0 };
252+
245253 if (* s -> err )
246254 return ;
247- if (n % 8 ) {
255+ if (n % stride ) {
248256 snprintf (s -> err , sizeof (s -> err ), "bad bigint" );
249257 return ;
250258 }
251259 w_byte (s , 'Z' );
252260 // chop off high all-zero words
253- n /= 8 ;
261+ n /= stride ;
254262 while (n -- )
255- if (p [ n ] )
263+ if (! memcmp ( & (( uint8_t * ) p )[ n * stride ], zero , stride ) )
256264 break ;
257265 if (n == (size_t )-1 ) {
258266 w_byte (s , 0 ); // normalized zero
259267 } else {
260- n = 8 * n + 8 ;
268+ n = ( n + 1 ) * stride ;
261269 w_varint (s , 2 * n + (sign < 0 ));
262270 w (s , p , n );
263271 }
@@ -276,7 +284,7 @@ static void ser_int(Ser *s, int64_t v)
276284 return ser_num (s , v );
277285 t = v < 0 ? - v : v ;
278286 sign = v < 0 ? -1 : 1 ;
279- ser_bigint (s , & t , sizeof (t ), sign );
287+ ser_bigint (s , & t , sizeof (t ), sizeof ( t ), sign );
280288 } else {
281289 w_byte (s , 'I' );
282290 w_zigzag (s , v );
@@ -324,26 +332,26 @@ static void ser_object_begin(Ser *s)
324332}
325333
326334// |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 )
328336{
329337 w_byte (s , '{' );
330338 w_varint (s , count );
331339}
332340
333- static void ser_object_ref (Ser * s , uint32_t id )
341+ static void ser_object_ref (Ser * s , size_t id )
334342{
335343 w_byte (s , '^' );
336344 w_varint (s , id );
337345}
338346
339- static void ser_array_begin (Ser * s , uint32_t count )
347+ static void ser_array_begin (Ser * s , size_t count )
340348{
341349 w_byte (s , 'A' ); // 'A'=dense, 'a'=sparse
342350 w_varint (s , count ); // element count
343351}
344352
345353// |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 )
347355{
348356 w_byte (s , '$' );
349357 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,
569577 return bail (err , "negative zero bigint" );
570578 if (pe - * p < (int64_t )u )
571579 goto too_short ;
572- des_bigint (arg , * p , u , 1 - 2 * t );
580+ des_bigint (arg , * p , u , ( int ) ( 1 - 2 * t ) );
573581 * p += u ;
574582 break ;
575583 case 'R' : // RegExp, deserialized as string
0 commit comments