passenger 5.1.6 → 5.1.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of passenger might be problematic. Click here for more details.

@@ -101,6 +101,18 @@ private:
101
101
  }
102
102
  }
103
103
 
104
+ static Json::Value maybeFilterPassword(const Entry &entry, const Json::Value &value) {
105
+ if (entry.schemaEntry->type == PASSWORD_TYPE) {
106
+ if (value.isNull()) {
107
+ return Json::nullValue;
108
+ } else {
109
+ return "[FILTERED]";
110
+ }
111
+ } else {
112
+ return value;
113
+ }
114
+ }
115
+
104
116
  bool isWritable(const Entry &entry) const {
105
117
  return !(entry.schemaEntry->flags & READ_ONLY) || !updatedOnce;
106
118
  }
@@ -308,11 +320,11 @@ public:
308
320
  const Entry &entry = it.getValue();
309
321
  Json::Value subdoc(Json::objectValue);
310
322
 
311
- subdoc["user_value"] = entry.userValue;
323
+ subdoc["user_value"] = maybeFilterPassword(entry, entry.userValue);
312
324
  if (entry.schemaEntry->defaultValueGetter) {
313
- subdoc["default_value"] = entry.getDefaultValue(*this);
325
+ subdoc["default_value"] = maybeFilterPassword(entry, entry.getDefaultValue(*this));
314
326
  }
315
- subdoc["effective_value"] = entry.getEffectiveValue(*this);
327
+ subdoc["effective_value"] = maybeFilterPassword(entry, entry.getEffectiveValue(*this));
316
328
  entry.schemaEntry->inspect(subdoc);
317
329
 
318
330
  result[it.getKey()] = subdoc;
@@ -107,6 +107,8 @@ getTypeString(Type type) {
107
107
  switch (type) {
108
108
  case STRING_TYPE:
109
109
  return P_STATIC_STRING("string");
110
+ case PASSWORD_TYPE:
111
+ return P_STATIC_STRING("password");
110
112
  case INT_TYPE:
111
113
  return P_STATIC_STRING("integer");
112
114
  case UINT_TYPE:
@@ -115,6 +117,10 @@ getTypeString(Type type) {
115
117
  return P_STATIC_STRING("float");
116
118
  case BOOL_TYPE:
117
119
  return P_STATIC_STRING("boolean");
120
+ case ARRAY_TYPE:
121
+ return P_STATIC_STRING("array");
122
+ case STRING_ARRAY_TYPE:
123
+ return P_STATIC_STRING("array of strings");
118
124
  default:
119
125
  return P_STATIC_STRING("unknown");
120
126
  }
@@ -48,6 +48,7 @@ variantMapToJson(const Schema &schema, const VariantMap &options) {
48
48
  if (options.has(key)) {
49
49
  switch (entry.type) {
50
50
  case STRING_TYPE:
51
+ case PASSWORD_TYPE:
51
52
  doc[key.toString()] = options.get(key);
52
53
  break;
53
54
  case INT_TYPE:
@@ -62,6 +63,17 @@ variantMapToJson(const Schema &schema, const VariantMap &options) {
62
63
  case BOOL_TYPE:
63
64
  doc[key.toString()] = options.getBool(key);
64
65
  break;
66
+ case ARRAY_TYPE:
67
+ case STRING_ARRAY_TYPE: {
68
+ Json::Value subdoc(Json::arrayValue);
69
+ vector<string> set = options.getStrSet(key);
70
+ vector<string>::const_iterator it, end = set.end();
71
+ for (it = set.begin(); it != end; it++) {
72
+ subdoc.append(*it);
73
+ }
74
+ doc[key.toString()] = subdoc;
75
+ break;
76
+ }
65
77
  default:
66
78
  P_BUG("Unknown type " + Passenger::toString((int) entry.type));
67
79
  break;
@@ -80,7 +80,7 @@
80
80
  #define PASSENGER_API_VERSION_MAJOR 0
81
81
  #define PASSENGER_API_VERSION_MINOR 3
82
82
  #define PASSENGER_DEFAULT_USER "nobody"
83
- #define PASSENGER_VERSION "5.1.6"
83
+ #define PASSENGER_VERSION "5.1.7"
84
84
  #define POOL_HELPER_THREAD_STACK_SIZE 262144
85
85
  #define PROCESS_SHUTDOWN_TIMEOUT 60
86
86
  #define PROCESS_SHUTDOWN_TIMEOUT_DISPLAY "1 minute"
@@ -1033,8 +1033,8 @@ runShellCommand(const StaticString &command) {
1033
1033
 
1034
1034
  string
1035
1035
  runCommandAndCaptureOutput(const char **command, int *status) {
1036
- pid_t pid;
1037
- int e, waitRet;
1036
+ pid_t pid, waitRet;
1037
+ int e, waitStatus;
1038
1038
  Pipe p;
1039
1039
 
1040
1040
  p = createPipe(__FILE__, __LINE__);
@@ -1089,9 +1089,19 @@ runCommandAndCaptureOutput(const char **command, int *status) {
1089
1089
  }
1090
1090
  p[0].close();
1091
1091
 
1092
- waitRet = syscalls::waitpid(pid, NULL, 0);
1093
- if (status != NULL) {
1094
- *status = waitRet;
1092
+ waitRet = syscalls::waitpid(pid, &waitStatus, 0);
1093
+ if (waitRet != -1) {
1094
+ if (status != NULL) {
1095
+ *status = waitStatus;
1096
+ }
1097
+ } else if (errno == ECHILD || errno == ESRCH) {
1098
+ if (status != NULL) {
1099
+ *status = -1;
1100
+ }
1101
+ } else {
1102
+ int e = errno;
1103
+ throw SystemException(string("Error waiting for the '") +
1104
+ command[0] + "' command", e);
1095
1105
  }
1096
1106
  return result;
1097
1107
  }
@@ -349,6 +349,8 @@ int runShellCommand(const StaticString &command);
349
349
  *
350
350
  * @param command The argument to pass to execvp().
351
351
  * @param status The status of the child process will be stored here, if non-NULL.
352
+ * When unable to waitpid() the child process because of an ECHILD
353
+ * or ESRCH, this will be set to -1.
352
354
  * @throws SystemException
353
355
  */
354
356
  string runCommandAndCaptureOutput(const char **command, int *status = NULL);
@@ -219,7 +219,7 @@ setCurlDefaultCaInfo(CURL *curl) {
219
219
  "/usr/share/ssl/certs/ca-bundle.crt",
220
220
  // FreeBSD
221
221
  "/usr/local/share/certs/ca-root-nss.crt",
222
- // OpenBSD, FreeBSD (symlink)
222
+ // OpenBSD, FreeBSD (symlink), macOS
223
223
  "/etc/ssl/cert.pem",
224
224
  // SUSE
225
225
  "/etc/ssl/certs"
@@ -11,12 +11,12 @@ The JsonCpp library's source code, including accompanying documentation,
11
11
  tests and demonstration applications, are licensed under the following
12
12
  conditions...
13
13
 
14
- The author (Baptiste Lepilleur) explicitly disclaims copyright in all
14
+ The JsonCpp Authors explicitly disclaim copyright in all
15
15
  jurisdictions which recognize such a disclaimer. In such jurisdictions,
16
16
  this software is released into the Public Domain.
17
17
 
18
18
  In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
19
- 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
19
+ 2010), this software is Copyright (c) 2007-2010 by The JsonCpp Authors, and is
20
20
  released under the terms of the MIT License (see below).
21
21
 
22
22
  In jurisdictions which recognize Public Domain property, the user of this
@@ -32,7 +32,7 @@ described in clear, concise terms at:
32
32
  The full text of the MIT License follows:
33
33
 
34
34
  ========================================================================
35
- Copyright (c) 2007-2010 Baptiste Lepilleur
35
+ Copyright (c) 2007-2010 The JsonCpp Authors
36
36
 
37
37
  Permission is hereby granted, free of charge, to any person
38
38
  obtaining a copy of this software and associated documentation
@@ -168,10 +168,16 @@ license you like.
168
168
  // managable and fixes a set of common hard-to-find bugs.
169
169
  #if __cplusplus >= 201103L
170
170
  # define JSONCPP_OVERRIDE override
171
- #elif defined(_MSC_VER) && _MSC_VER > 1600
171
+ # define JSONCPP_NOEXCEPT noexcept
172
+ #elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900
172
173
  # define JSONCPP_OVERRIDE override
174
+ # define JSONCPP_NOEXCEPT throw()
175
+ #elif defined(_MSC_VER) && _MSC_VER >= 1900
176
+ # define JSONCPP_OVERRIDE override
177
+ # define JSONCPP_NOEXCEPT noexcept
173
178
  #else
174
179
  # define JSONCPP_OVERRIDE
180
+ # define JSONCPP_NOEXCEPT throw()
175
181
  #endif
176
182
 
177
183
  #ifndef JSON_HAS_RVALUE_REFERENCES
@@ -10,12 +10,12 @@ The JsonCpp library's source code, including accompanying documentation,
10
10
  tests and demonstration applications, are licensed under the following
11
11
  conditions...
12
12
 
13
- The author (Baptiste Lepilleur) explicitly disclaims copyright in all
13
+ The JsonCpp Authors explicitly disclaim copyright in all
14
14
  jurisdictions which recognize such a disclaimer. In such jurisdictions,
15
15
  this software is released into the Public Domain.
16
16
 
17
17
  In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
18
- 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
18
+ 2010), this software is Copyright (c) 2007-2010 by The JsonCpp Authors, and is
19
19
  released under the terms of the MIT License (see below).
20
20
 
21
21
  In jurisdictions which recognize Public Domain property, the user of this
@@ -31,7 +31,7 @@ described in clear, concise terms at:
31
31
  The full text of the MIT License follows:
32
32
 
33
33
  ========================================================================
34
- Copyright (c) 2007-2010 Baptiste Lepilleur
34
+ Copyright (c) 2007-2010 The JsonCpp Authors
35
35
 
36
36
  Permission is hereby granted, free of charge, to any person
37
37
  obtaining a copy of this software and associated documentation
@@ -87,10 +87,10 @@ license you like.
87
87
  #ifndef JSON_VERSION_H_INCLUDED
88
88
  # define JSON_VERSION_H_INCLUDED
89
89
 
90
- # define JSONCPP_VERSION_STRING "1.7.7"
90
+ # define JSONCPP_VERSION_STRING "1.8.1"
91
91
  # define JSONCPP_VERSION_MAJOR 1
92
- # define JSONCPP_VERSION_MINOR 7
93
- # define JSONCPP_VERSION_PATCH 7
92
+ # define JSONCPP_VERSION_MINOR 8
93
+ # define JSONCPP_VERSION_PATCH 1
94
94
  # define JSONCPP_VERSION_QUALIFIER
95
95
  # define JSONCPP_VERSION_HEXA ((JSONCPP_VERSION_MAJOR << 24) | (JSONCPP_VERSION_MINOR << 16) | (JSONCPP_VERSION_PATCH << 8))
96
96
 
@@ -201,10 +201,16 @@ license you like.
201
201
  // managable and fixes a set of common hard-to-find bugs.
202
202
  #if __cplusplus >= 201103L
203
203
  # define JSONCPP_OVERRIDE override
204
- #elif defined(_MSC_VER) && _MSC_VER > 1600
204
+ # define JSONCPP_NOEXCEPT noexcept
205
+ #elif defined(_MSC_VER) && _MSC_VER > 1600 && _MSC_VER < 1900
205
206
  # define JSONCPP_OVERRIDE override
207
+ # define JSONCPP_NOEXCEPT throw()
208
+ #elif defined(_MSC_VER) && _MSC_VER >= 1900
209
+ # define JSONCPP_OVERRIDE override
210
+ # define JSONCPP_NOEXCEPT noexcept
206
211
  #else
207
212
  # define JSONCPP_OVERRIDE
213
+ # define JSONCPP_NOEXCEPT throw()
208
214
  #endif
209
215
 
210
216
  #ifndef JSON_HAS_RVALUE_REFERENCES
@@ -371,6 +377,8 @@ class ValueConstIterator;
371
377
  #include "forwards.h"
372
378
  #endif // if !defined(JSON_IS_AMALGAMATION)
373
379
 
380
+ #pragma pack(push, 8)
381
+
374
382
  namespace Json {
375
383
 
376
384
  /** \brief Configuration passed to reader and writer.
@@ -415,6 +423,8 @@ public:
415
423
 
416
424
  } // namespace Json
417
425
 
426
+ #pragma pack(pop)
427
+
418
428
  #endif // CPPTL_JSON_FEATURES_H_INCLUDED
419
429
 
420
430
  // //////////////////////////////////////////////////////////////////////
@@ -474,6 +484,8 @@ public:
474
484
  #pragma warning(disable : 4251)
475
485
  #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
476
486
 
487
+ #pragma pack(push, 8)
488
+
477
489
  /** \brief JSON (JavaScript Object Notation).
478
490
  */
479
491
  namespace Json {
@@ -485,8 +497,8 @@ namespace Json {
485
497
  class JSON_API Exception : public std::exception {
486
498
  public:
487
499
  Exception(JSONCPP_STRING const& msg);
488
- ~Exception() throw() JSONCPP_OVERRIDE;
489
- char const* what() const throw() JSONCPP_OVERRIDE;
500
+ ~Exception() JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
501
+ char const* what() const JSONCPP_NOEXCEPT JSONCPP_OVERRIDE;
490
502
  protected:
491
503
  JSONCPP_STRING msg_;
492
504
  };
@@ -1291,6 +1303,7 @@ template<>
1291
1303
  inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
1292
1304
  }
1293
1305
 
1306
+ #pragma pack(pop)
1294
1307
 
1295
1308
  #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
1296
1309
  #pragma warning(pop)
@@ -1336,6 +1349,8 @@ inline void swap(Json::Value& a, Json::Value& b) { a.swap(b); }
1336
1349
  #pragma warning(disable : 4251)
1337
1350
  #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
1338
1351
 
1352
+ #pragma pack(push, 8)
1353
+
1339
1354
  namespace Json {
1340
1355
 
1341
1356
  /** \brief Unserialize a <a HREF="http://www.json.org">JSON</a> document into a
@@ -1710,6 +1725,8 @@ JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
1710
1725
 
1711
1726
  } // namespace Json
1712
1727
 
1728
+ #pragma pack(pop)
1729
+
1713
1730
  #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
1714
1731
  #pragma warning(pop)
1715
1732
  #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
@@ -1751,6 +1768,8 @@ JSON_API JSONCPP_ISTREAM& operator>>(JSONCPP_ISTREAM&, Value&);
1751
1768
  #pragma warning(disable : 4251)
1752
1769
  #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
1753
1770
 
1771
+ #pragma pack(push, 8)
1772
+
1754
1773
  namespace Json {
1755
1774
 
1756
1775
  class Value;
@@ -2055,6 +2074,8 @@ JSON_API JSONCPP_OSTREAM& operator<<(JSONCPP_OSTREAM&, const Value& root);
2055
2074
 
2056
2075
  } // namespace Json
2057
2076
 
2077
+ #pragma pack(pop)
2078
+
2058
2079
  #if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
2059
2080
  #pragma warning(pop)
2060
2081
  #endif // if defined(JSONCPP_DISABLE_DLL_INTERFACE_WARNING)
@@ -10,12 +10,12 @@ The JsonCpp library's source code, including accompanying documentation,
10
10
  tests and demonstration applications, are licensed under the following
11
11
  conditions...
12
12
 
13
- The author (Baptiste Lepilleur) explicitly disclaims copyright in all
13
+ The JsonCpp Authors explicitly disclaim copyright in all
14
14
  jurisdictions which recognize such a disclaimer. In such jurisdictions,
15
15
  this software is released into the Public Domain.
16
16
 
17
17
  In jurisdictions which do not recognize Public Domain property (e.g. Germany as of
18
- 2010), this software is Copyright (c) 2007-2010 by Baptiste Lepilleur, and is
18
+ 2010), this software is Copyright (c) 2007-2010 by The JsonCpp Authors, and is
19
19
  released under the terms of the MIT License (see below).
20
20
 
21
21
  In jurisdictions which recognize Public Domain property, the user of this
@@ -31,7 +31,7 @@ described in clear, concise terms at:
31
31
  The full text of the MIT License follows:
32
32
 
33
33
  ========================================================================
34
- Copyright (c) 2007-2010 Baptiste Lepilleur
34
+ Copyright (c) 2007-2010 The JsonCpp Authors
35
35
 
36
36
  Permission is hereby granted, free of charge, to any person
37
37
  obtaining a copy of this software and associated documentation
@@ -92,7 +92,13 @@ license you like.
92
92
  #ifndef LIB_JSONCPP_JSON_TOOL_H_INCLUDED
93
93
  #define LIB_JSONCPP_JSON_TOOL_H_INCLUDED
94
94
 
95
- #ifndef NO_LOCALE_SUPPORT
95
+
96
+ // Also support old flag NO_LOCALE_SUPPORT
97
+ #ifdef NO_LOCALE_SUPPORT
98
+ #define JSONCPP_NO_LOCALE_SUPPORT
99
+ #endif
100
+
101
+ #ifndef JSONCPP_NO_LOCALE_SUPPORT
96
102
  #include <clocale>
97
103
  #endif
98
104
 
@@ -104,7 +110,7 @@ license you like.
104
110
 
105
111
  namespace Json {
106
112
  static char getDecimalPoint() {
107
- #ifdef NO_LOCALE_SUPPORT
113
+ #ifdef JSONCPP_NO_LOCALE_SUPPORT
108
114
  return '\0';
109
115
  #else
110
116
  struct lconv* lc = localeconv();
@@ -210,6 +216,7 @@ static inline void fixNumericLocaleInput(char* begin, char* end) {
210
216
  // //////////////////////////////////////////////////////////////////////
211
217
 
212
218
  // Copyright 2007-2011 Baptiste Lepilleur
219
+ // Copyright (C) 2016 InfoTeCS JSC. All rights reserved.
213
220
  // Distributed under MIT license, or public domain if desired and
214
221
  // recognized in your jurisdiction.
215
222
  // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
@@ -255,8 +262,12 @@ static inline void fixNumericLocaleInput(char* begin, char* end) {
255
262
  #pragma warning(disable : 4996)
256
263
  #endif
257
264
 
258
- static int const stackLimit_g = 1000;
259
- static int stackDepth_g = 0; // see readValue()
265
+ // Define JSONCPP_DEPRECATED_STACK_LIMIT as an appropriate integer at compile time to change the stack limit
266
+ #if !defined(JSONCPP_DEPRECATED_STACK_LIMIT)
267
+ #define JSONCPP_DEPRECATED_STACK_LIMIT 1000
268
+ #endif
269
+
270
+ static size_t const stackLimit_g = JSONCPP_DEPRECATED_STACK_LIMIT; // see readValue()
260
271
 
261
272
  namespace Json {
262
273
 
@@ -343,13 +354,12 @@ bool Reader::parse(const char* beginDoc,
343
354
  current_ = begin_;
344
355
  lastValueEnd_ = 0;
345
356
  lastValue_ = 0;
346
- commentsBefore_ = "";
357
+ commentsBefore_.clear();
347
358
  errors_.clear();
348
359
  while (!nodes_.empty())
349
360
  nodes_.pop();
350
361
  nodes_.push(&root);
351
362
 
352
- stackDepth_g = 0; // Yes, this is bad coding, but options are limited.
353
363
  bool successful = readValue();
354
364
  Token token;
355
365
  skipCommentTokens(token);
@@ -372,12 +382,10 @@ bool Reader::parse(const char* beginDoc,
372
382
  }
373
383
 
374
384
  bool Reader::readValue() {
375
- // This is a non-reentrant way to support a stackLimit. Terrible!
376
- // But this deprecated class has a security problem: Bad input can
377
- // cause a seg-fault. This seems like a fair, binary-compatible way
378
- // to prevent the problem.
379
- if (stackDepth_g >= stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
380
- ++stackDepth_g;
385
+ // readValue() may call itself only if it calls readObject() or ReadArray().
386
+ // These methods execute nodes_.push() just before and nodes_.pop)() just after calling readValue().
387
+ // parse() executes one nodes_.push(), so > instead of >=.
388
+ if (nodes_.size() > stackLimit_g) throwRuntimeError("Exceeded stackLimit in readValue().");
381
389
 
382
390
  Token token;
383
391
  skipCommentTokens(token);
@@ -385,7 +393,7 @@ bool Reader::readValue() {
385
393
 
386
394
  if (collectComments_ && !commentsBefore_.empty()) {
387
395
  currentValue().setComment(commentsBefore_, commentBefore);
388
- commentsBefore_ = "";
396
+ commentsBefore_.clear();
389
397
  }
390
398
 
391
399
  switch (token.type_) {
@@ -451,7 +459,6 @@ bool Reader::readValue() {
451
459
  lastValue_ = &currentValue();
452
460
  }
453
461
 
454
- --stackDepth_g;
455
462
  return successful;
456
463
  }
457
464
 
@@ -684,7 +691,7 @@ bool Reader::readObject(Token& tokenStart) {
684
691
  break;
685
692
  if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
686
693
  return true;
687
- name = "";
694
+ name.clear();
688
695
  if (tokenName.type_ == tokenString) {
689
696
  if (!decodeString(tokenName, name))
690
697
  return recoverFromError(tokenObjectEnd);
@@ -1239,7 +1246,6 @@ private:
1239
1246
  Location lastValueEnd_;
1240
1247
  Value* lastValue_;
1241
1248
  JSONCPP_STRING commentsBefore_;
1242
- int stackDepth_;
1243
1249
 
1244
1250
  OurFeatures const features_;
1245
1251
  bool collectComments_;
@@ -1250,7 +1256,6 @@ private:
1250
1256
  OurReader::OurReader(OurFeatures const& features)
1251
1257
  : errors_(), document_(), begin_(), end_(), current_(), lastValueEnd_(),
1252
1258
  lastValue_(), commentsBefore_(),
1253
- stackDepth_(0),
1254
1259
  features_(features), collectComments_() {
1255
1260
  }
1256
1261
 
@@ -1268,13 +1273,12 @@ bool OurReader::parse(const char* beginDoc,
1268
1273
  current_ = begin_;
1269
1274
  lastValueEnd_ = 0;
1270
1275
  lastValue_ = 0;
1271
- commentsBefore_ = "";
1276
+ commentsBefore_.clear();
1272
1277
  errors_.clear();
1273
1278
  while (!nodes_.empty())
1274
1279
  nodes_.pop();
1275
1280
  nodes_.push(&root);
1276
1281
 
1277
- stackDepth_ = 0;
1278
1282
  bool successful = readValue();
1279
1283
  Token token;
1280
1284
  skipCommentTokens(token);
@@ -1303,15 +1307,15 @@ bool OurReader::parse(const char* beginDoc,
1303
1307
  }
1304
1308
 
1305
1309
  bool OurReader::readValue() {
1306
- if (stackDepth_ >= features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
1307
- ++stackDepth_;
1310
+ // To preserve the old behaviour we cast size_t to int.
1311
+ if (static_cast<int>(nodes_.size()) > features_.stackLimit_) throwRuntimeError("Exceeded stackLimit in readValue().");
1308
1312
  Token token;
1309
1313
  skipCommentTokens(token);
1310
1314
  bool successful = true;
1311
1315
 
1312
1316
  if (collectComments_ && !commentsBefore_.empty()) {
1313
1317
  currentValue().setComment(commentsBefore_, commentBefore);
1314
- commentsBefore_ = "";
1318
+ commentsBefore_.clear();
1315
1319
  }
1316
1320
 
1317
1321
  switch (token.type_) {
@@ -1401,7 +1405,6 @@ bool OurReader::readValue() {
1401
1405
  lastValue_ = &currentValue();
1402
1406
  }
1403
1407
 
1404
- --stackDepth_;
1405
1408
  return successful;
1406
1409
  }
1407
1410
 
@@ -1661,7 +1664,7 @@ bool OurReader::readObject(Token& tokenStart) {
1661
1664
  break;
1662
1665
  if (tokenName.type_ == tokenObjectEnd && name.empty()) // empty object
1663
1666
  return true;
1664
- name = "";
1667
+ name.clear();
1665
1668
  if (tokenName.type_ == tokenString) {
1666
1669
  if (!decodeString(tokenName, name))
1667
1670
  return recoverFromError(tokenObjectEnd);
@@ -2638,9 +2641,9 @@ namespace Json {
2638
2641
  Exception::Exception(JSONCPP_STRING const& msg)
2639
2642
  : msg_(msg)
2640
2643
  {}
2641
- Exception::~Exception() throw()
2644
+ Exception::~Exception() JSONCPP_NOEXCEPT
2642
2645
  {}
2643
- char const* Exception::what() const throw()
2646
+ char const* Exception::what() const JSONCPP_NOEXCEPT
2644
2647
  {
2645
2648
  return msg_.c_str();
2646
2649
  }
@@ -2748,7 +2751,7 @@ bool Value::CZString::operator<(const CZString& other) const {
2748
2751
  // Assume both are strings.
2749
2752
  unsigned this_len = this->storage_.length_;
2750
2753
  unsigned other_len = other.storage_.length_;
2751
- unsigned min_len = std::min(this_len, other_len);
2754
+ unsigned min_len = std::min<unsigned>(this_len, other_len);
2752
2755
  JSON_ASSERT(this->cstr_ && other.cstr_);
2753
2756
  int comp = memcmp(this->cstr_, other.cstr_, min_len);
2754
2757
  if (comp < 0) return true;
@@ -2788,7 +2791,7 @@ bool Value::CZString::isStaticString() const { return storage_.policy_ == noDupl
2788
2791
  * This optimization is used in ValueInternalMap fast allocator.
2789
2792
  */
2790
2793
  Value::Value(ValueType vtype) {
2791
- static char const empty[] = "";
2794
+ static char const emptyString[] = "";
2792
2795
  initBasic(vtype);
2793
2796
  switch (vtype) {
2794
2797
  case nullValue:
@@ -2802,7 +2805,7 @@ Value::Value(ValueType vtype) {
2802
2805
  break;
2803
2806
  case stringValue:
2804
2807
  // allocated_ == false, so this is safe.
2805
- value_.string_ = const_cast<char*>(static_cast<char const*>(empty));
2808
+ value_.string_ = const_cast<char*>(static_cast<char const*>(emptyString));
2806
2809
  break;
2807
2810
  case arrayValue:
2808
2811
  case objectValue:
@@ -2843,6 +2846,7 @@ Value::Value(double value) {
2843
2846
 
2844
2847
  Value::Value(const char* value) {
2845
2848
  initBasic(stringValue, true);
2849
+ JSON_ASSERT_MESSAGE(value != NULL, "Null Value Passed to Value Constructor");
2846
2850
  value_.string_ = duplicateAndPrefixStringValue(value, static_cast<unsigned>(strlen(value)));
2847
2851
  }
2848
2852
 
@@ -3011,7 +3015,7 @@ bool Value::operator<(const Value& other) const {
3011
3015
  char const* other_str;
3012
3016
  decodePrefixedString(this->allocated_, this->value_.string_, &this_len, &this_str);
3013
3017
  decodePrefixedString(other.allocated_, other.value_.string_, &other_len, &other_str);
3014
- unsigned min_len = std::min(this_len, other_len);
3018
+ unsigned min_len = std::min<unsigned>(this_len, other_len);
3015
3019
  JSON_ASSERT(this_str && other_str);
3016
3020
  int comp = memcmp(this_str, other_str, min_len);
3017
3021
  if (comp < 0) return true;
@@ -3324,7 +3328,7 @@ bool Value::isConvertibleTo(ValueType other) const {
3324
3328
  case nullValue:
3325
3329
  return (isNumeric() && asDouble() == 0.0) ||
3326
3330
  (type_ == booleanValue && value_.bool_ == false) ||
3327
- (type_ == stringValue && asString() == "") ||
3331
+ (type_ == stringValue && asString().empty()) ||
3328
3332
  (type_ == arrayValue && value_.map_->size() == 0) ||
3329
3333
  (type_ == objectValue && value_.map_->size() == 0) ||
3330
3334
  type_ == nullValue;
@@ -3724,7 +3728,11 @@ bool Value::isBool() const { return type_ == booleanValue; }
3724
3728
  bool Value::isInt() const {
3725
3729
  switch (type_) {
3726
3730
  case intValue:
3731
+ #if defined(JSON_HAS_INT64)
3727
3732
  return value_.int_ >= minInt && value_.int_ <= maxInt;
3733
+ #else
3734
+ return true;
3735
+ #endif
3728
3736
  case uintValue:
3729
3737
  return value_.uint_ <= UInt(maxInt);
3730
3738
  case realValue:
@@ -3739,9 +3747,17 @@ bool Value::isInt() const {
3739
3747
  bool Value::isUInt() const {
3740
3748
  switch (type_) {
3741
3749
  case intValue:
3750
+ #if defined(JSON_HAS_INT64)
3742
3751
  return value_.int_ >= 0 && LargestUInt(value_.int_) <= LargestUInt(maxUInt);
3752
+ #else
3753
+ return value_.int_ >= 0;
3754
+ #endif
3743
3755
  case uintValue:
3756
+ #if defined(JSON_HAS_INT64)
3744
3757
  return value_.uint_ <= maxUInt;
3758
+ #else
3759
+ return true;
3760
+ #endif
3745
3761
  case realValue:
3746
3762
  return value_.real_ >= 0 && value_.real_ <= maxUInt &&
3747
3763
  IsIntegral(value_.real_);
@@ -3792,16 +3808,28 @@ bool Value::isUInt64() const {
3792
3808
  }
3793
3809
 
3794
3810
  bool Value::isIntegral() const {
3811
+ switch (type_) {
3812
+ case intValue:
3813
+ case uintValue:
3814
+ return true;
3815
+ case realValue:
3795
3816
  #if defined(JSON_HAS_INT64)
3796
- return isInt64() || isUInt64();
3817
+ // Note that maxUInt64 (= 2^64 - 1) is not exactly representable as a
3818
+ // double, so double(maxUInt64) will be rounded up to 2^64. Therefore we
3819
+ // require the value to be strictly less than the limit.
3820
+ return value_.real_ >= double(minInt64) && value_.real_ < maxUInt64AsDouble && IsIntegral(value_.real_);
3797
3821
  #else
3798
- return isInt() || isUInt();
3799
- #endif
3822
+ return value_.real_ >= minInt && value_.real_ <= maxUInt && IsIntegral(value_.real_);
3823
+ #endif // JSON_HAS_INT64
3824
+ default:
3825
+ break;
3826
+ }
3827
+ return false;
3800
3828
  }
3801
3829
 
3802
- bool Value::isDouble() const { return type_ == realValue || isIntegral(); }
3830
+ bool Value::isDouble() const { return type_ == intValue || type_ == uintValue || type_ == realValue; }
3803
3831
 
3804
- bool Value::isNumeric() const { return isIntegral() || isDouble(); }
3832
+ bool Value::isNumeric() const { return isDouble(); }
3805
3833
 
3806
3834
  bool Value::isString() const { return type_ == stringValue; }
3807
3835
 
@@ -3926,6 +3954,7 @@ Path::Path(const JSONCPP_STRING& path,
3926
3954
  const PathArgument& a4,
3927
3955
  const PathArgument& a5) {
3928
3956
  InArgs in;
3957
+ in.reserve(5);
3929
3958
  in.push_back(&a1);
3930
3959
  in.push_back(&a2);
3931
3960
  in.push_back(&a3);
@@ -4202,17 +4231,24 @@ namespace {
4202
4231
  JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int precision) {
4203
4232
  // Allocate a buffer that is more than large enough to store the 16 digits of
4204
4233
  // precision requested below.
4205
- char buffer[32];
4234
+ char buffer[36];
4206
4235
  int len = -1;
4207
4236
 
4208
- char formatString[6];
4209
- sprintf(formatString, "%%.%dg", precision);
4237
+ char formatString[15];
4238
+ snprintf(formatString, sizeof(formatString), "%%.%dg", precision);
4210
4239
 
4211
4240
  // Print into the buffer. We need not request the alternative representation
4212
4241
  // that always has a decimal point because JSON doesn't distingish the
4213
4242
  // concepts of reals and integers.
4214
4243
  if (isfinite(value)) {
4215
4244
  len = snprintf(buffer, sizeof(buffer), formatString, value);
4245
+ fixNumericLocale(buffer, buffer + len);
4246
+
4247
+ // try to ensure we preserve the fact that this was given to us as a double on input
4248
+ if (!strstr(buffer, ".") && !strstr(buffer, "e")) {
4249
+ strcat(buffer, ".0");
4250
+ }
4251
+
4216
4252
  } else {
4217
4253
  // IEEE standard states that NaN values will not compare to themselves
4218
4254
  if (value != value) {
@@ -4222,10 +4258,8 @@ JSONCPP_STRING valueToString(double value, bool useSpecialFloats, unsigned int p
4222
4258
  } else {
4223
4259
  len = snprintf(buffer, sizeof(buffer), useSpecialFloats ? "Infinity" : "1e+9999");
4224
4260
  }
4225
- // For those, we do not need to call fixNumLoc, but it is fast.
4226
4261
  }
4227
4262
  assert(len >= 0);
4228
- fixNumericLocale(buffer, buffer + len);
4229
4263
  return buffer;
4230
4264
  }
4231
4265
  }
@@ -4392,7 +4426,7 @@ void FastWriter::dropNullPlaceholders() { dropNullPlaceholders_ = true; }
4392
4426
  void FastWriter::omitEndingLineFeed() { omitEndingLineFeed_ = true; }
4393
4427
 
4394
4428
  JSONCPP_STRING FastWriter::write(const Value& root) {
4395
- document_ = "";
4429
+ document_.clear();
4396
4430
  writeValue(root);
4397
4431
  if (!omitEndingLineFeed_)
4398
4432
  document_ += "\n";
@@ -4460,9 +4494,9 @@ StyledWriter::StyledWriter()
4460
4494
  : rightMargin_(74), indentSize_(3), addChildValues_() {}
4461
4495
 
4462
4496
  JSONCPP_STRING StyledWriter::write(const Value& root) {
4463
- document_ = "";
4497
+ document_.clear();
4464
4498
  addChildValues_ = false;
4465
- indentString_ = "";
4499
+ indentString_.clear();
4466
4500
  writeCommentBeforeValue(root);
4467
4501
  writeValue(root);
4468
4502
  writeCommentAfterValueOnSameLine(root);
@@ -4676,7 +4710,7 @@ StyledStreamWriter::StyledStreamWriter(JSONCPP_STRING indentation)
4676
4710
  void StyledStreamWriter::write(JSONCPP_OSTREAM& out, const Value& root) {
4677
4711
  document_ = &out;
4678
4712
  addChildValues_ = false;
4679
- indentString_ = "";
4713
+ indentString_.clear();
4680
4714
  indented_ = true;
4681
4715
  writeCommentBeforeValue(root);
4682
4716
  if (!indented_) writeIndent();
@@ -4958,7 +4992,7 @@ int BuiltStyledStreamWriter::write(Value const& root, JSONCPP_OSTREAM* sout)
4958
4992
  sout_ = sout;
4959
4993
  addChildValues_ = false;
4960
4994
  indented_ = true;
4961
- indentString_ = "";
4995
+ indentString_.clear();
4962
4996
  writeCommentBeforeValue(root);
4963
4997
  if (!indented_) writeIndent();
4964
4998
  indented_ = true;
@@ -5212,10 +5246,10 @@ StreamWriter* StreamWriterBuilder::newStreamWriter() const
5212
5246
  }
5213
5247
  JSONCPP_STRING nullSymbol = "null";
5214
5248
  if (dnp) {
5215
- nullSymbol = "";
5249
+ nullSymbol.clear();
5216
5250
  }
5217
5251
  if (pre > 17) pre = 17;
5218
- JSONCPP_STRING endingLineFeedSymbol = "";
5252
+ JSONCPP_STRING endingLineFeedSymbol;
5219
5253
  return new BuiltStyledStreamWriter(
5220
5254
  indentation, cs,
5221
5255
  colonSymbol, nullSymbol, endingLineFeedSymbol, usf, pre);