1+ #include "config.h"
2+ #include <assert.h>
3+ #include <common/amount.h>
4+ #include <common/pseudorand.h>
5+ #include <common/setup.h>
6+ #include <common/utils.h>
7+ #include <stdio.h>
8+ #include <wire/wire.h>
9+
10+ /* AUTOGENERATED MOCKS START */
11+ /* Generated stub for amount_asset_is_main */
12+ bool amount_asset_is_main (struct amount_asset * asset UNNEEDED )
13+ { fprintf (stderr , "amount_asset_is_main called!\n" ); abort (); }
14+ /* Generated stub for amount_asset_to_sat */
15+ struct amount_sat amount_asset_to_sat (struct amount_asset * asset UNNEEDED )
16+ { fprintf (stderr , "amount_asset_to_sat called!\n" ); abort (); }
17+ /* Generated stub for amount_feerate */
18+ bool amount_feerate (u32 * feerate UNNEEDED , struct amount_sat fee UNNEEDED , size_t weight UNNEEDED )
19+ { fprintf (stderr , "amount_feerate called!\n" ); abort (); }
20+ /* Generated stub for amount_sat */
21+ struct amount_sat amount_sat (u64 satoshis UNNEEDED )
22+ { fprintf (stderr , "amount_sat called!\n" ); abort (); }
23+ /* Generated stub for amount_sat_add */
24+ bool amount_sat_add (struct amount_sat * val UNNEEDED ,
25+ struct amount_sat a UNNEEDED ,
26+ struct amount_sat b UNNEEDED )
27+ { fprintf (stderr , "amount_sat_add called!\n" ); abort (); }
28+ /* Generated stub for amount_sat_eq */
29+ bool amount_sat_eq (struct amount_sat a UNNEEDED , struct amount_sat b UNNEEDED )
30+ { fprintf (stderr , "amount_sat_eq called!\n" ); abort (); }
31+ /* Generated stub for amount_sat_greater_eq */
32+ bool amount_sat_greater_eq (struct amount_sat a UNNEEDED , struct amount_sat b UNNEEDED )
33+ { fprintf (stderr , "amount_sat_greater_eq called!\n" ); abort (); }
34+ /* Generated stub for amount_sat_sub */
35+ bool amount_sat_sub (struct amount_sat * val UNNEEDED ,
36+ struct amount_sat a UNNEEDED ,
37+ struct amount_sat b UNNEEDED )
38+ { fprintf (stderr , "amount_sat_sub called!\n" ); abort (); }
39+ /* Generated stub for amount_sat_to_asset */
40+ struct amount_asset amount_sat_to_asset (struct amount_sat * sat UNNEEDED , const u8 * asset UNNEEDED )
41+ { fprintf (stderr , "amount_sat_to_asset called!\n" ); abort (); }
42+ /* Generated stub for amount_tx_fee */
43+ struct amount_sat amount_tx_fee (u32 fee_per_kw UNNEEDED , size_t weight UNNEEDED )
44+ { fprintf (stderr , "amount_tx_fee called!\n" ); abort (); }
45+ /* Generated stub for fromwire */
46+ const u8 * fromwire (const u8 * * cursor UNNEEDED , size_t * max UNNEEDED , void * copy UNNEEDED , size_t n UNNEEDED )
47+ { fprintf (stderr , "fromwire called!\n" ); abort (); }
48+ /* Generated stub for fromwire_bool */
49+ bool fromwire_bool (const u8 * * cursor UNNEEDED , size_t * max UNNEEDED )
50+ { fprintf (stderr , "fromwire_bool called!\n" ); abort (); }
51+ /* Generated stub for fromwire_fail */
52+ void * fromwire_fail (const u8 * * cursor UNNEEDED , size_t * max UNNEEDED )
53+ { fprintf (stderr , "fromwire_fail called!\n" ); abort (); }
54+ /* Generated stub for fromwire_secp256k1_ecdsa_signature */
55+ void fromwire_secp256k1_ecdsa_signature (const u8 * * cursor UNNEEDED , size_t * max UNNEEDED ,
56+ secp256k1_ecdsa_signature * signature UNNEEDED )
57+ { fprintf (stderr , "fromwire_secp256k1_ecdsa_signature called!\n" ); abort (); }
58+ /* Generated stub for fromwire_sha256 */
59+ void fromwire_sha256 (const u8 * * cursor UNNEEDED , size_t * max UNNEEDED , struct sha256 * sha256 UNNEEDED )
60+ { fprintf (stderr , "fromwire_sha256 called!\n" ); abort (); }
61+ /* Generated stub for fromwire_tal_arrn */
62+ u8 * fromwire_tal_arrn (const tal_t * ctx UNNEEDED ,
63+ const u8 * * cursor UNNEEDED , size_t * max UNNEEDED , size_t num UNNEEDED )
64+ { fprintf (stderr , "fromwire_tal_arrn called!\n" ); abort (); }
65+ /* Generated stub for fromwire_u32 */
66+ u32 fromwire_u32 (const u8 * * cursor UNNEEDED , size_t * max UNNEEDED )
67+ { fprintf (stderr , "fromwire_u32 called!\n" ); abort (); }
68+ /* Generated stub for fromwire_u64 */
69+ u64 fromwire_u64 (const u8 * * cursor UNNEEDED , size_t * max UNNEEDED )
70+ { fprintf (stderr , "fromwire_u64 called!\n" ); abort (); }
71+ /* Generated stub for fromwire_u8 */
72+ u8 fromwire_u8 (const u8 * * cursor UNNEEDED , size_t * max UNNEEDED )
73+ { fprintf (stderr , "fromwire_u8 called!\n" ); abort (); }
74+ /* Generated stub for fromwire_u8_array */
75+ void fromwire_u8_array (const u8 * * cursor UNNEEDED , size_t * max UNNEEDED , u8 * arr UNNEEDED , size_t num UNNEEDED )
76+ { fprintf (stderr , "fromwire_u8_array called!\n" ); abort (); }
77+ /* Generated stub for siphash_seed */
78+ const struct siphash_seed * siphash_seed (void )
79+ { fprintf (stderr , "siphash_seed called!\n" ); abort (); }
80+ /* Generated stub for towire */
81+ void towire (u8 * * pptr UNNEEDED , const void * data UNNEEDED , size_t len UNNEEDED )
82+ { fprintf (stderr , "towire called!\n" ); abort (); }
83+ /* Generated stub for towire_bool */
84+ void towire_bool (u8 * * pptr UNNEEDED , bool v UNNEEDED )
85+ { fprintf (stderr , "towire_bool called!\n" ); abort (); }
86+ /* Generated stub for towire_secp256k1_ecdsa_signature */
87+ void towire_secp256k1_ecdsa_signature (u8 * * pptr UNNEEDED ,
88+ const secp256k1_ecdsa_signature * signature UNNEEDED )
89+ { fprintf (stderr , "towire_secp256k1_ecdsa_signature called!\n" ); abort (); }
90+ /* Generated stub for towire_sha256 */
91+ void towire_sha256 (u8 * * pptr UNNEEDED , const struct sha256 * sha256 UNNEEDED )
92+ { fprintf (stderr , "towire_sha256 called!\n" ); abort (); }
93+ /* Generated stub for towire_u32 */
94+ void towire_u32 (u8 * * pptr UNNEEDED , u32 v UNNEEDED )
95+ { fprintf (stderr , "towire_u32 called!\n" ); abort (); }
96+ /* Generated stub for towire_u64 */
97+ void towire_u64 (u8 * * pptr UNNEEDED , u64 v UNNEEDED )
98+ { fprintf (stderr , "towire_u64 called!\n" ); abort (); }
99+ /* Generated stub for towire_u8 */
100+ void towire_u8 (u8 * * pptr UNNEEDED , u8 v UNNEEDED )
101+ { fprintf (stderr , "towire_u8 called!\n" ); abort (); }
102+ /* Generated stub for towire_u8_array */
103+ void towire_u8_array (u8 * * pptr UNNEEDED , const u8 * arr UNNEEDED , size_t num UNNEEDED )
104+ { fprintf (stderr , "towire_u8_array called!\n" ); abort (); }
105+ /* AUTOGENERATED MOCKS END */
106+
107+ #include <assert.h>
108+ #include <stdint.h>
109+
110+ static void test_str_to_s64 (void )
111+ {
112+ s64 val ;
113+
114+ /* Empty input */
115+ assert (!str_to_s64 ("" , 0 , & val ));
116+
117+ /* Single digit */
118+ assert (str_to_s64 ("0" , 1 , & val ) && val == 0 );
119+ assert (str_to_s64 ("5" , 1 , & val ) && val == 5 );
120+ assert (str_to_s64 ("9" , 1 , & val ) && val == 9 );
121+
122+ /* Negative single digit */
123+ assert (str_to_s64 ("-0" , 2 , & val ) && val == 0 );
124+ assert (str_to_s64 ("-5" , 2 , & val ) && val == -5 );
125+ assert (str_to_s64 ("-9" , 2 , & val ) && val == -9 );
126+
127+ /* Multi-digit */
128+ assert (str_to_s64 ("123" , 3 , & val ) && val == 123 );
129+ assert (str_to_s64 ("-123" , 4 , & val ) && val == -123 );
130+ assert (str_to_s64 ("000" , 3 , & val ) && val == 0 );
131+ assert (str_to_s64 ("000123" , 6 , & val ) && val == 123 );
132+ assert (str_to_s64 ("-000123" , 7 , & val ) && val == -123 );
133+
134+ /* Exact length prefix */
135+ assert (str_to_s64 ("1234" , 2 , & val ) && val == 12 );
136+ assert (str_to_s64 ("-1234" , 3 , & val ) && val == -12 );
137+
138+ /* Max positive value (2^63-1) */
139+ assert (str_to_s64 ("9223372036854775807" , 19 , & val ) &&
140+ val == 9223372036854775807LL );
141+
142+ /* Min negative value (-2^63) */
143+ assert (str_to_s64 ("-9223372036854775808" , 20 , & val ) &&
144+ val == -9223372036854775807LL - 1 );
145+
146+ /* Overflow (positive) */
147+ assert (!str_to_s64 ("9223372036854775808" , 19 , & val )); /* 2^63 */
148+ assert (!str_to_s64 ("92233720368547758080" , 20 , & val ));
149+
150+ /* Overflow (negative) */
151+ assert (!str_to_s64 ("-9223372036854775809" , 20 , & val )); /* -2^63 - 1 */
152+
153+ /* Invalid characters */
154+ assert (!str_to_s64 ("12a3" , 4 , & val ));
155+ assert (!str_to_s64 ("1.23" , 4 , & val ));
156+ assert (!str_to_s64 ("123 " , 4 , & val ));
157+ assert (!str_to_s64 (" 123" , 4 , & val ));
158+ assert (!str_to_s64 ("--123" , 5 , & val )); /* Multiple signs */
159+ assert (!str_to_s64 ("+-123" , 5 , & val )); /* Mixed signs */
160+
161+ /* Non-digit at various positions */
162+ assert (!str_to_s64 ("x" , 1 , & val ));
163+ assert (!str_to_s64 ("1x" , 2 , & val ));
164+ assert (!str_to_s64 ("12x" , 3 , & val ));
165+ assert (!str_to_s64 ("-x" , 2 , & val ));
166+ assert (!str_to_s64 ("-1x" , 3 , & val ));
167+
168+ /* Long string of zeros (21) must succeed as 0 */
169+ assert (str_to_s64 ("000000000000000000000" , 21 , & val ) && val == 0 );
170+ assert (str_to_s64 ("-000000000000000000000" , 22 , & val ) && val == 0 );
171+
172+ /* Max value with leading zeros */
173+ assert (str_to_s64 ("009223372036854775807" , 21 , & val ) &&
174+ val == 9223372036854775807LL );
175+ assert (str_to_s64 ("-009223372036854775808" , 22 , & val ) &&
176+ val == -9223372036854775807LL - 1 );
177+
178+ /* 1 followed by 19 zeros (10^19), must overflow */
179+ assert (!str_to_s64 ("100000000000000000000" , 21 , & val ));
180+
181+ /* 1 followed by 18 zeros (10^18), fits */
182+ assert (str_to_s64 ("1000000000000000000" , 19 , & val ) &&
183+ val == 1000000000000000000LL );
184+
185+ /* 999...9 (19 times) overflows */
186+ assert (!str_to_s64 ("9999999999999999999" , 19 , & val ));
187+
188+ /* Just below INT64_MAX */
189+ assert (str_to_s64 ("9223372036854775806" , 19 , & val ) &&
190+ val == 9223372036854775806LL );
191+
192+ /* Just above INT64_MIN */
193+ assert (str_to_s64 ("-9223372036854775807" , 20 , & val ) &&
194+ val == -9223372036854775807LL );
195+
196+ /* Prefix of the max (first 18 chars of the 19-digit max) */
197+ assert (str_to_s64 ("9223372036854775807" , 18 , & val ) &&
198+ val == 922337203685477580LL );
199+
200+ /* Prefix of the min (first 19 chars of the 20-digit min) */
201+ assert (str_to_s64 ("-9223372036854775808" , 19 , & val ) &&
202+ val == -922337203685477580LL );
203+
204+ /* Ensure we do not write *num on failure paths */
205+ {
206+ s64 before = 0xdeadbeefcafebabeULL ;
207+ val = before ;
208+
209+ assert (!str_to_s64 ("12a3" , 4 , & val ));
210+ assert (val == before );
211+
212+ assert (!str_to_s64 ("" , 0 , & val ));
213+ assert (val == before );
214+
215+ assert (!str_to_s64 ("9223372036854775808" , 19 , & val ));
216+ assert (val == before );
217+
218+ assert (!str_to_s64 ("-9223372036854775809" , 20 , & val ));
219+ assert (val == before );
220+
221+ assert (!str_to_s64 ("1234567890" , 0 , & val ));
222+ assert (val == before );
223+ }
224+ }
225+
226+
227+ int main (int argc , char * argv [])
228+ {
229+ common_setup (argv [0 ]);
230+ test_str_to_s64 ();
231+ common_shutdown ();
232+
233+ return 0 ;
234+ }
0 commit comments