2424# define snprintf _snprintf // C compilers have this in stdio.h
2525#endif
2626
27+ #ifndef PERL_UNUSED_RESULT
28+ # if defined(__GNUC__ ) && defined(HASATTRIBUTE_WARN_UNUSED_RESULT )
29+ # define PERL_UNUSED_RESULT (v ) STMT_START { __typeof__(v) z = (v); (void)sizeof(z); } STMT_END
30+ # else
31+ # define PERL_UNUSED_RESULT (v ) ((void)(v))
32+ # endif
33+ #endif
34+
2735#if defined(_AIX ) && (!defined(HAS_LONG_DOUBLE ) || AIX_WORKAROUND )
2836#define HAVE_NO_POWL
2937#endif
@@ -268,10 +276,12 @@ mingw_modfl(long double x, long double *ip)
268276#define F_ESCAPE_SLASH 0x00080000UL
269277#define F_SORT_BY 0x00100000UL
270278#define F_ALLOW_STRINGIFY 0x00200000UL
279+ #define F_UNBLESSED_BOOL 0x00400000UL
280+ #define F_ALLOW_DUPKEYS 0x00800000UL
271281#define F_HOOK 0x80000000UL /* some hooks exist, so slow-path processing */
272282
273283#define F_PRETTY F_INDENT | F_SPACE_BEFORE | F_SPACE_AFTER
274- #define SET_RELAXED (F_RELAXED | F_ALLOW_BAREKEY | F_ALLOW_SQUOTE)
284+ #define SET_RELAXED (F_RELAXED | F_ALLOW_BAREKEY | F_ALLOW_SQUOTE | F_ALLOW_DUPKEYS )
275285
276286#define INIT_SIZE 32 /* initial scalar size to be allocated */
277287#define INDENT_STEP 3 /* default spaces per indentation level */
@@ -1810,11 +1820,13 @@ encode_sv (pTHX_ enc_t *enc, SV *sv, SV *typesv)
18101820# endif
18111821 }
18121822#endif
1823+
18131824#ifdef USE_QUADMATH
18141825 quadmath_snprintf (enc -> cur , enc -> end - enc -> cur , "%.*Qg" , (int )NV_DIG , nv );
18151826#else
1816- ( void ) Gconvert (nv , NV_DIG , 0 , enc -> cur );
1827+ PERL_UNUSED_RESULT ( Gconvert (nv , NV_DIG , 0 , enc -> cur ) );
18171828#endif
1829+
18181830#ifdef NEED_NUMERIC_LOCALE_C
18191831 if (loc_changed ) {
18201832# ifdef HAS_USELOCALE
@@ -3243,7 +3255,7 @@ decode_hv (pTHX_ dec_t *dec, SV *typesv)
32433255 SV * typerv ;
32443256 int allow_squote = dec -> json .flags & F_ALLOW_SQUOTE ;
32453257 int allow_barekey = dec -> json .flags & F_ALLOW_BAREKEY ;
3246- int relaxed = dec -> json .flags & F_RELAXED ;
3258+ int allow_dupkeys = dec -> json .flags & F_ALLOW_DUPKEYS ;
32473259 char endstr = '"' ;
32483260
32493261 DEC_INC_DEPTH ;
@@ -3303,14 +3315,16 @@ decode_hv (pTHX_ dec_t *dec, SV *typesv)
33033315 if (!key )
33043316 goto fail ;
33053317
3318+ if (!allow_dupkeys && UNLIKELY (hv_exists_ent (hv , key , 0 ))) {
3319+ ERR ("Duplicate keys not allowed" );
3320+ }
33063321 decode_ws (dec ); EXPECT_CH (':' );
3307-
33083322 decode_ws (dec );
33093323
33103324 if (typesv )
33113325 {
33123326 value_typesv = newSV (0 );
3313- hv_store_ent (typehv , key , value_typesv , 0 );
3327+ ( void ) hv_store_ent (typehv , key , value_typesv , 0 );
33143328 }
33153329
33163330 value = decode_sv (aTHX_ dec , value_typesv );
@@ -3320,7 +3334,7 @@ decode_hv (pTHX_ dec_t *dec, SV *typesv)
33203334 goto fail ;
33213335 }
33223336
3323- hv_store_ent (hv , key , value , 0 );
3337+ ( void ) hv_store_ent (hv , key , value , 0 );
33243338 SvREFCNT_dec (key );
33253339
33263340 break ;
@@ -3340,14 +3354,12 @@ decode_hv (pTHX_ dec_t *dec, SV *typesv)
33403354 if (UNLIKELY (p - key > I32_MAX ))
33413355 ERR ("Hash key too large" );
33423356#endif
3343- if (!relaxed && UNLIKELY (hv_exists (hv , key , len ))) {
3357+ if (!allow_dupkeys && UNLIKELY (hv_exists (hv , key , len ))) {
33443358 ERR ("Duplicate keys not allowed" );
33453359 }
33463360
33473361 dec -> cur = p + 1 ;
3348-
33493362 decode_ws (dec ); if (* p != ':' ) EXPECT_CH (':' );
3350-
33513363 decode_ws (dec );
33523364
33533365 if (typesv )
@@ -3590,6 +3602,8 @@ decode_sv (pTHX_ dec_t *dec, SV *typesv)
35903602 dec -> cur += 4 ;
35913603 if (typesv )
35923604 sv_setiv_mg (typesv , JSON_TYPE_BOOL );
3605+ if (dec -> json .flags & F_UNBLESSED_BOOL )
3606+ return newSVsv (& PL_sv_yes );
35933607 return newSVsv (MY_CXT .json_true );
35943608 }
35953609 else
@@ -3604,6 +3618,8 @@ decode_sv (pTHX_ dec_t *dec, SV *typesv)
36043618 dec -> cur += 5 ;
36053619 if (typesv )
36063620 sv_setiv_mg (typesv , JSON_TYPE_BOOL );
3621+ if (dec -> json .flags & F_UNBLESSED_BOOL )
3622+ return newSVsv (& PL_sv_no );
36073623 return newSVsv (MY_CXT .json_false );
36083624 }
36093625 else
@@ -4093,6 +4109,8 @@ void ascii (JSON *self, int enable = 1)
40934109 allow_bignum = F_ALLOW_BIGNUM
40944110 escape_slash = F_ESCAPE_SLASH
40954111 allow_stringify = F_ALLOW_STRINGIFY
4112+ unblessed_bool = F_UNBLESSED_BOOL
4113+ allow_dupkeys = F_ALLOW_DUPKEYS
40964114 PPCODE :
40974115 if (enable )
40984116 self -> flags |= ix ;
@@ -4121,7 +4139,9 @@ void get_ascii (JSON *self)
41214139 get_allow_singlequote = F_ALLOW_SQUOTE
41224140 get_allow_bignum = F_ALLOW_BIGNUM
41234141 get_escape_slash = F_ESCAPE_SLASH
4124- get_allow_stringify = F_ALLOW_STRINGIFY
4142+ get_allow_stringify = F_ALLOW_STRINGIFY
4143+ get_unblessed_bool = F_UNBLESSED_BOOL
4144+ get_allow_dupkeys = F_ALLOW_DUPKEYS
41254145 PPCODE :
41264146 XPUSHs (boolSV (self -> flags & ix ));
41274147
0 commit comments