1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "utilstrencodings.h"
7 
8 #include "tinyformat.h"
9 
10 #include <cstdlib>
11 #include <cstring>
12 #include <errno.h>
13 #include <limits>
14 
15 using namespace std;
16 
17 static const string CHARS_ALPHA_NUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
18 
19 static const string SAFE_CHARS[] =
20 {
21     CHARS_ALPHA_NUM + " .,;-_/:?@()", // SAFE_CHARS_DEFAULT
22     CHARS_ALPHA_NUM + " .,;-_?@" // SAFE_CHARS_UA_COMMENT
23 };
24 
SanitizeString(const string & str,int rule)25 string SanitizeString(const string& str, int rule)
26 {
27     string strResult;
28     for (std::string::size_type i = 0; i < str.size(); i++)
29     {
30         if (SAFE_CHARS[rule].find(str[i]) != std::string::npos)
31             strResult.push_back(str[i]);
32     }
33     return strResult;
34 }
35 
36 const signed char p_util_hexdigit[256] =
37 { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
38   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
39   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
40   0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
41   -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
42   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
43   -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
44   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
45   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
46   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
47   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
48   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
49   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
50   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
51   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
52   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
53 
HexDigit(char c)54 signed char HexDigit(char c)
55 {
56     return p_util_hexdigit[(unsigned char)c];
57 }
58 
IsHex(const string & str)59 bool IsHex(const string& str)
60 {
61     for(std::string::const_iterator it(str.begin()); it != str.end(); ++it)
62     {
63         if (HexDigit(*it) < 0)
64             return false;
65     }
66     return (str.size() > 0) && (str.size()%2 == 0);
67 }
68 
ParseHex(const char * psz)69 vector<unsigned char> ParseHex(const char* psz)
70 {
71     // convert hex dump to vector
72     vector<unsigned char> vch;
73     while (true)
74     {
75         while (isspace(*psz))
76             psz++;
77         signed char c = HexDigit(*psz++);
78         if (c == (signed char)-1)
79             break;
80         unsigned char n = (c << 4);
81         c = HexDigit(*psz++);
82         if (c == (signed char)-1)
83             break;
84         n |= c;
85         vch.push_back(n);
86     }
87     return vch;
88 }
89 
ParseHex(const string & str)90 vector<unsigned char> ParseHex(const string& str)
91 {
92     return ParseHex(str.c_str());
93 }
94 
EncodeBase64(const unsigned char * pch,size_t len)95 string EncodeBase64(const unsigned char* pch, size_t len)
96 {
97     static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
98 
99     string strRet="";
100     strRet.reserve((len+2)/3*4);
101 
102     int mode=0, left=0;
103     const unsigned char *pchEnd = pch+len;
104 
105     while (pch<pchEnd)
106     {
107         int enc = *(pch++);
108         switch (mode)
109         {
110             case 0: // we have no bits
111                 strRet += pbase64[enc >> 2];
112                 left = (enc & 3) << 4;
113                 mode = 1;
114                 break;
115 
116             case 1: // we have two bits
117                 strRet += pbase64[left | (enc >> 4)];
118                 left = (enc & 15) << 2;
119                 mode = 2;
120                 break;
121 
122             case 2: // we have four bits
123                 strRet += pbase64[left | (enc >> 6)];
124                 strRet += pbase64[enc & 63];
125                 mode = 0;
126                 break;
127         }
128     }
129 
130     if (mode)
131     {
132         strRet += pbase64[left];
133         strRet += '=';
134         if (mode == 1)
135             strRet += '=';
136     }
137 
138     return strRet;
139 }
140 
EncodeBase64(const string & str)141 string EncodeBase64(const string& str)
142 {
143     return EncodeBase64((const unsigned char*)str.c_str(), str.size());
144 }
145 
DecodeBase64(const char * p,bool * pfInvalid)146 vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
147 {
148     static const int decode64_table[256] =
149     {
150         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
151         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
152         -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
153         -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
154         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
155         29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
156         49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
157         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
158         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
159         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
160         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
161         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
162         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
163     };
164 
165     if (pfInvalid)
166         *pfInvalid = false;
167 
168     vector<unsigned char> vchRet;
169     vchRet.reserve(strlen(p)*3/4);
170 
171     int mode = 0;
172     int left = 0;
173 
174     while (1)
175     {
176          int dec = decode64_table[(unsigned char)*p];
177          if (dec == -1) break;
178          p++;
179          switch (mode)
180          {
181              case 0: // we have no bits and get 6
182                  left = dec;
183                  mode = 1;
184                  break;
185 
186               case 1: // we have 6 bits and keep 4
187                   vchRet.push_back((left<<2) | (dec>>4));
188                   left = dec & 15;
189                   mode = 2;
190                   break;
191 
192              case 2: // we have 4 bits and get 6, we keep 2
193                  vchRet.push_back((left<<4) | (dec>>2));
194                  left = dec & 3;
195                  mode = 3;
196                  break;
197 
198              case 3: // we have 2 bits and get 6
199                  vchRet.push_back((left<<6) | dec);
200                  mode = 0;
201                  break;
202          }
203     }
204 
205     if (pfInvalid)
206         switch (mode)
207         {
208             case 0: // 4n base64 characters processed: ok
209                 break;
210 
211             case 1: // 4n+1 base64 character processed: impossible
212                 *pfInvalid = true;
213                 break;
214 
215             case 2: // 4n+2 base64 characters processed: require '=='
216                 if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
217                     *pfInvalid = true;
218                 break;
219 
220             case 3: // 4n+3 base64 characters processed: require '='
221                 if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
222                     *pfInvalid = true;
223                 break;
224         }
225 
226     return vchRet;
227 }
228 
DecodeBase64(const string & str)229 string DecodeBase64(const string& str)
230 {
231     vector<unsigned char> vchRet = DecodeBase64(str.c_str());
232     return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size());
233 }
234 
EncodeBase32(const unsigned char * pch,size_t len)235 string EncodeBase32(const unsigned char* pch, size_t len)
236 {
237     static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
238 
239     string strRet="";
240     strRet.reserve((len+4)/5*8);
241 
242     int mode=0, left=0;
243     const unsigned char *pchEnd = pch+len;
244 
245     while (pch<pchEnd)
246     {
247         int enc = *(pch++);
248         switch (mode)
249         {
250             case 0: // we have no bits
251                 strRet += pbase32[enc >> 3];
252                 left = (enc & 7) << 2;
253                 mode = 1;
254                 break;
255 
256             case 1: // we have three bits
257                 strRet += pbase32[left | (enc >> 6)];
258                 strRet += pbase32[(enc >> 1) & 31];
259                 left = (enc & 1) << 4;
260                 mode = 2;
261                 break;
262 
263             case 2: // we have one bit
264                 strRet += pbase32[left | (enc >> 4)];
265                 left = (enc & 15) << 1;
266                 mode = 3;
267                 break;
268 
269             case 3: // we have four bits
270                 strRet += pbase32[left | (enc >> 7)];
271                 strRet += pbase32[(enc >> 2) & 31];
272                 left = (enc & 3) << 3;
273                 mode = 4;
274                 break;
275 
276             case 4: // we have two bits
277                 strRet += pbase32[left | (enc >> 5)];
278                 strRet += pbase32[enc & 31];
279                 mode = 0;
280         }
281     }
282 
283     static const int nPadding[5] = {0, 6, 4, 3, 1};
284     if (mode)
285     {
286         strRet += pbase32[left];
287         for (int n=0; n<nPadding[mode]; n++)
288              strRet += '=';
289     }
290 
291     return strRet;
292 }
293 
EncodeBase32(const string & str)294 string EncodeBase32(const string& str)
295 {
296     return EncodeBase32((const unsigned char*)str.c_str(), str.size());
297 }
298 
DecodeBase32(const char * p,bool * pfInvalid)299 vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid)
300 {
301     static const int decode32_table[256] =
302     {
303         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
304         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
305         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
306         -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
307         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1,  0,  1,  2,
308          3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
309         23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
310         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
311         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
312         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
313         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
314         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
315         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
316     };
317 
318     if (pfInvalid)
319         *pfInvalid = false;
320 
321     vector<unsigned char> vchRet;
322     vchRet.reserve((strlen(p))*5/8);
323 
324     int mode = 0;
325     int left = 0;
326 
327     while (1)
328     {
329          int dec = decode32_table[(unsigned char)*p];
330          if (dec == -1) break;
331          p++;
332          switch (mode)
333          {
334              case 0: // we have no bits and get 5
335                  left = dec;
336                  mode = 1;
337                  break;
338 
339               case 1: // we have 5 bits and keep 2
340                   vchRet.push_back((left<<3) | (dec>>2));
341                   left = dec & 3;
342                   mode = 2;
343                   break;
344 
345              case 2: // we have 2 bits and keep 7
346                  left = left << 5 | dec;
347                  mode = 3;
348                  break;
349 
350              case 3: // we have 7 bits and keep 4
351                  vchRet.push_back((left<<1) | (dec>>4));
352                  left = dec & 15;
353                  mode = 4;
354                  break;
355 
356              case 4: // we have 4 bits, and keep 1
357                  vchRet.push_back((left<<4) | (dec>>1));
358                  left = dec & 1;
359                  mode = 5;
360                  break;
361 
362              case 5: // we have 1 bit, and keep 6
363                  left = left << 5 | dec;
364                  mode = 6;
365                  break;
366 
367              case 6: // we have 6 bits, and keep 3
368                  vchRet.push_back((left<<2) | (dec>>3));
369                  left = dec & 7;
370                  mode = 7;
371                  break;
372 
373              case 7: // we have 3 bits, and keep 0
374                  vchRet.push_back((left<<5) | dec);
375                  mode = 0;
376                  break;
377          }
378     }
379 
380     if (pfInvalid)
381         switch (mode)
382         {
383             case 0: // 8n base32 characters processed: ok
384                 break;
385 
386             case 1: // 8n+1 base32 characters processed: impossible
387             case 3: //   +3
388             case 6: //   +6
389                 *pfInvalid = true;
390                 break;
391 
392             case 2: // 8n+2 base32 characters processed: require '======'
393                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1)
394                     *pfInvalid = true;
395                 break;
396 
397             case 4: // 8n+4 base32 characters processed: require '===='
398                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)
399                     *pfInvalid = true;
400                 break;
401 
402             case 5: // 8n+5 base32 characters processed: require '==='
403                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1)
404                     *pfInvalid = true;
405                 break;
406 
407             case 7: // 8n+7 base32 characters processed: require '='
408                 if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1)
409                     *pfInvalid = true;
410                 break;
411         }
412 
413     return vchRet;
414 }
415 
DecodeBase32(const string & str)416 string DecodeBase32(const string& str)
417 {
418     vector<unsigned char> vchRet = DecodeBase32(str.c_str());
419     return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size());
420 }
421 
ParsePrechecks(const std::string & str)422 static bool ParsePrechecks(const std::string& str)
423 {
424     if (str.empty()) // No empty string allowed
425         return false;
426     if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed
427         return false;
428     if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
429         return false;
430     return true;
431 }
432 
ParseInt32(const std::string & str,int32_t * out)433 bool ParseInt32(const std::string& str, int32_t *out)
434 {
435     if (!ParsePrechecks(str))
436         return false;
437     char *endp = NULL;
438     errno = 0; // strtol will not set errno if valid
439     long int n = strtol(str.c_str(), &endp, 10);
440     if(out) *out = (int32_t)n;
441     // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
442     // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
443     // platforms the size of these types may be different.
444     return endp && *endp == 0 && !errno &&
445         n >= std::numeric_limits<int32_t>::min() &&
446         n <= std::numeric_limits<int32_t>::max();
447 }
448 
ParseInt64(const std::string & str,int64_t * out)449 bool ParseInt64(const std::string& str, int64_t *out)
450 {
451     if (!ParsePrechecks(str))
452         return false;
453     char *endp = NULL;
454     errno = 0; // strtoll will not set errno if valid
455     long long int n = strtoll(str.c_str(), &endp, 10);
456     if(out) *out = (int64_t)n;
457     // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
458     // we still have to check that the returned value is within the range of an *int64_t*.
459     return endp && *endp == 0 && !errno &&
460         n >= std::numeric_limits<int64_t>::min() &&
461         n <= std::numeric_limits<int64_t>::max();
462 }
463 
ParseUInt32(const std::string & str,uint32_t * out)464 bool ParseUInt32(const std::string& str, uint32_t *out)
465 {
466     if (!ParsePrechecks(str))
467         return false;
468     if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoul accepts these by default if they fit in the range
469         return false;
470     char *endp = NULL;
471     errno = 0; // strtoul will not set errno if valid
472     unsigned long int n = strtoul(str.c_str(), &endp, 10);
473     if(out) *out = (uint32_t)n;
474     // Note that strtoul returns a *unsigned long int*, so even if it doesn't report a over/underflow
475     // we still have to check that the returned value is within the range of an *uint32_t*. On 64-bit
476     // platforms the size of these types may be different.
477     return endp && *endp == 0 && !errno &&
478         n <= std::numeric_limits<uint32_t>::max();
479 }
480 
ParseUInt64(const std::string & str,uint64_t * out)481 bool ParseUInt64(const std::string& str, uint64_t *out)
482 {
483     if (!ParsePrechecks(str))
484         return false;
485     if (str.size() >= 1 && str[0] == '-') // Reject negative values, unfortunately strtoull accepts these by default if they fit in the range
486         return false;
487     char *endp = NULL;
488     errno = 0; // strtoull will not set errno if valid
489     unsigned long long int n = strtoull(str.c_str(), &endp, 10);
490     if(out) *out = (uint64_t)n;
491     // Note that strtoull returns a *unsigned long long int*, so even if it doesn't report a over/underflow
492     // we still have to check that the returned value is within the range of an *uint64_t*.
493     return endp && *endp == 0 && !errno &&
494         n <= std::numeric_limits<uint64_t>::max();
495 }
496 
497 
ParseDouble(const std::string & str,double * out)498 bool ParseDouble(const std::string& str, double *out)
499 {
500     if (!ParsePrechecks(str))
501         return false;
502     if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
503         return false;
504     std::istringstream text(str);
505     text.imbue(std::locale::classic());
506     double result;
507     text >> result;
508     if(out) *out = result;
509     return text.eof() && !text.fail();
510 }
511 
FormatParagraph(const std::string & in,size_t width,size_t indent)512 std::string FormatParagraph(const std::string& in, size_t width, size_t indent)
513 {
514     std::stringstream out;
515     size_t ptr = 0;
516     size_t indented = 0;
517     while (ptr < in.size())
518     {
519         size_t lineend = in.find_first_of('\n', ptr);
520         if (lineend == std::string::npos) {
521             lineend = in.size();
522         }
523         const size_t linelen = lineend - ptr;
524         const size_t rem_width = width - indented;
525         if (linelen <= rem_width) {
526             out << in.substr(ptr, linelen + 1);
527             ptr = lineend + 1;
528             indented = 0;
529         } else {
530             size_t finalspace = in.find_last_of(" \n", ptr + rem_width);
531             if (finalspace == std::string::npos || finalspace < ptr) {
532                 // No place to break; just include the entire word and move on
533                 finalspace = in.find_first_of("\n ", ptr);
534                 if (finalspace == std::string::npos) {
535                     // End of the string, just add it and break
536                     out << in.substr(ptr);
537                     break;
538                 }
539             }
540             out << in.substr(ptr, finalspace - ptr) << "\n";
541             if (in[finalspace] == '\n') {
542                 indented = 0;
543             } else if (indent) {
544                 out << std::string(indent, ' ');
545                 indented = indent;
546             }
547             ptr = finalspace + 1;
548         }
549     }
550     return out.str();
551 }
552 
i64tostr(int64_t n)553 std::string i64tostr(int64_t n)
554 {
555     return strprintf("%d", n);
556 }
557 
itostr(int n)558 std::string itostr(int n)
559 {
560     return strprintf("%d", n);
561 }
562 
atoi64(const char * psz)563 int64_t atoi64(const char* psz)
564 {
565 #ifdef _MSC_VER
566     return _atoi64(psz);
567 #else
568     return strtoll(psz, NULL, 10);
569 #endif
570 }
571 
atoi64(const std::string & str)572 int64_t atoi64(const std::string& str)
573 {
574 #ifdef _MSC_VER
575     return _atoi64(str.c_str());
576 #else
577     return strtoll(str.c_str(), NULL, 10);
578 #endif
579 }
580 
atoi(const std::string & str)581 int atoi(const std::string& str)
582 {
583     return atoi(str.c_str());
584 }
585 
586 /** Upper bound for mantissa.
587  * 10^18-1 is the largest arbitrary decimal that will fit in a signed 64-bit integer.
588  * Larger integers cannot consist of arbitrary combinations of 0-9:
589  *
590  *   999999999999999999  1^18-1
591  *  9223372036854775807  (1<<63)-1  (max int64_t)
592  *  9999999999999999999  1^19-1     (would overflow)
593  */
594 static const int64_t UPPER_BOUND = 1000000000000000000LL - 1LL;
595 
596 /** Helper function for ParseFixedPoint */
ProcessMantissaDigit(char ch,int64_t & mantissa,int & mantissa_tzeros)597 static inline bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantissa_tzeros)
598 {
599     if(ch == '0')
600         ++mantissa_tzeros;
601     else {
602         for (int i=0; i<=mantissa_tzeros; ++i) {
603             if (mantissa > (UPPER_BOUND / 10LL))
604                 return false; /* overflow */
605             mantissa *= 10;
606         }
607         mantissa += ch - '0';
608         mantissa_tzeros = 0;
609     }
610     return true;
611 }
612 
ParseFixedPoint(const std::string & val,int decimals,int64_t * amount_out)613 bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
614 {
615     int64_t mantissa = 0;
616     int64_t exponent = 0;
617     int mantissa_tzeros = 0;
618     bool mantissa_sign = false;
619     bool exponent_sign = false;
620     int ptr = 0;
621     int end = val.size();
622     int point_ofs = 0;
623 
624     if (ptr < end && val[ptr] == '-') {
625         mantissa_sign = true;
626         ++ptr;
627     }
628     if (ptr < end)
629     {
630         if (val[ptr] == '0') {
631             /* pass single 0 */
632             ++ptr;
633         } else if (val[ptr] >= '1' && val[ptr] <= '9') {
634             while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
635                 if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
636                     return false; /* overflow */
637                 ++ptr;
638             }
639         } else return false; /* missing expected digit */
640     } else return false; /* empty string or loose '-' */
641     if (ptr < end && val[ptr] == '.')
642     {
643         ++ptr;
644         if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9')
645         {
646             while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
647                 if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
648                     return false; /* overflow */
649                 ++ptr;
650                 ++point_ofs;
651             }
652         } else return false; /* missing expected digit */
653     }
654     if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E'))
655     {
656         ++ptr;
657         if (ptr < end && val[ptr] == '+')
658             ++ptr;
659         else if (ptr < end && val[ptr] == '-') {
660             exponent_sign = true;
661             ++ptr;
662         }
663         if (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
664             while (ptr < end && val[ptr] >= '0' && val[ptr] <= '9') {
665                 if (exponent > (UPPER_BOUND / 10LL))
666                     return false; /* overflow */
667                 exponent = exponent * 10 + val[ptr] - '0';
668                 ++ptr;
669             }
670         } else return false; /* missing expected digit */
671     }
672     if (ptr != end)
673         return false; /* trailing garbage */
674 
675     /* finalize exponent */
676     if (exponent_sign)
677         exponent = -exponent;
678     exponent = exponent - point_ofs + mantissa_tzeros;
679 
680     /* finalize mantissa */
681     if (mantissa_sign)
682         mantissa = -mantissa;
683 
684     /* convert to one 64-bit fixed-point value */
685     exponent += decimals;
686     if (exponent < 0)
687         return false; /* cannot represent values smaller than 10^-decimals */
688     if (exponent >= 18)
689         return false; /* cannot represent values larger than or equal to 10^(18-decimals) */
690 
691     for (int i=0; i < exponent; ++i) {
692         if (mantissa > (UPPER_BOUND / 10LL) || mantissa < -(UPPER_BOUND / 10LL))
693             return false; /* overflow */
694         mantissa *= 10;
695     }
696     if (mantissa > UPPER_BOUND || mantissa < -UPPER_BOUND)
697         return false; /* overflow */
698 
699     if (amount_out)
700         *amount_out = mantissa;
701 
702     return true;
703 }
704 
705