Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
R
rapidjson
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
rapidjson
Commits
8f4e99b2
Commit
8f4e99b2
authored
9 years ago
by
Milo Yip
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #604 from miloyip/coverage
Improve coverage to 100%
parents
105c92ee
d7ee0862
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
341 additions
and
98 deletions
+341
-98
CHANGELOG.md
CHANGELOG.md
+2
-1
regex.h
include/rapidjson/internal/regex.h
+7
-11
reader.h
include/rapidjson/reader.h
+2
-4
schema.h
include/rapidjson/schema.h
+10
-7
encodingstest.cpp
test/unittest/encodingstest.cpp
+25
-0
regextest.cpp
test/unittest/regextest.cpp
+11
-0
schematest.cpp
test/unittest/schematest.cpp
+130
-1
simdtest.cpp
test/unittest/simdtest.cpp
+92
-58
valuetest.cpp
test/unittest/valuetest.cpp
+4
-0
writertest.cpp
test/unittest/writertest.cpp
+58
-16
No files found.
CHANGELOG.md
View file @
8f4e99b2
...
...
@@ -51,7 +51,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
*
Fix Document::Parse(const Ch
*
) for transcoding (#478)
*
encodings.h: fix typo in preprocessor condition (#495)
*
Custom Microsoft headers are necessary only for Visual Studio 2012 and lower (#559)
*
*
Fix memory leak for invalid regex (26e69ffde95ba4773ab06db6457b78f308716f4b)
*
Fix a bug in schema minimum/maximum keywords for 64-bit integer (e7149d665941068ccf8c565e77495521331cf390)
### Changed
*
Clarify problematic JSON license (#392)
...
...
This diff is collapsed.
Click to expand it.
include/rapidjson/internal/regex.h
View file @
8f4e99b2
...
...
@@ -375,14 +375,14 @@ private:
bool
Eval
(
Stack
<
Allocator
>&
operandStack
,
Operator
op
)
{
switch
(
op
)
{
case
kConcatenation
:
if
(
operandStack
.
GetSize
()
>=
sizeof
(
Frag
)
*
2
)
{
RAPIDJSON_ASSERT
(
operandStack
.
GetSize
()
>=
sizeof
(
Frag
)
*
2
);
{
Frag
e2
=
*
operandStack
.
template
Pop
<
Frag
>
(
1
);
Frag
e1
=
*
operandStack
.
template
Pop
<
Frag
>
(
1
);
Patch
(
e1
.
out
,
e2
.
start
);
*
operandStack
.
template
Push
<
Frag
>
()
=
Frag
(
e1
.
start
,
e2
.
out
,
Min
(
e1
.
minIndex
,
e2
.
minIndex
));
return
true
;
}
return
fals
e
;
return
tru
e
;
case
kAlternation
:
if
(
operandStack
.
GetSize
()
>=
sizeof
(
Frag
)
*
2
)
{
...
...
@@ -413,7 +413,8 @@ private:
}
return
false
;
case
kOneOrMore
:
default
:
RAPIDJSON_ASSERT
(
op
==
kOneOrMore
);
if
(
operandStack
.
GetSize
()
>=
sizeof
(
Frag
))
{
Frag
e
=
*
operandStack
.
template
Pop
<
Frag
>
(
1
);
SizeType
s
=
NewState
(
kRegexInvalidState
,
e
.
start
,
0
);
...
...
@@ -422,16 +423,12 @@ private:
return
true
;
}
return
false
;
default
:
return
false
;
}
}
bool
EvalQuantifier
(
Stack
<
Allocator
>&
operandStack
,
unsigned
n
,
unsigned
m
)
{
RAPIDJSON_ASSERT
(
n
<=
m
);
if
(
operandStack
.
GetSize
()
<
sizeof
(
Frag
))
return
false
;
RAPIDJSON_ASSERT
(
operandStack
.
GetSize
()
>=
sizeof
(
Frag
));
if
(
n
==
0
)
{
if
(
m
==
0
)
// a{0} not support
...
...
@@ -647,8 +644,7 @@ private:
// Return whether the added states is a match state
bool
AddState
(
Stack
<
Allocator
>&
l
,
SizeType
index
)
const
{
if
(
index
==
kRegexInvalidState
)
return
true
;
RAPIDJSON_ASSERT
(
index
!=
kRegexInvalidState
);
const
State
&
s
=
GetState
(
index
);
if
(
s
.
out1
!=
kRegexInvalidState
)
{
// Split
...
...
This diff is collapsed.
Click to expand it.
include/rapidjson/reader.h
View file @
8f4e99b2
...
...
@@ -635,8 +635,7 @@ private:
RAPIDJSON_PARSE_ERROR
(
kParseErrorTermination
,
is
.
Tell
());
return
;
default
:
RAPIDJSON_PARSE_ERROR
(
kParseErrorObjectMissCommaOrCurlyBracket
,
is
.
Tell
());
break
;
RAPIDJSON_PARSE_ERROR
(
kParseErrorObjectMissCommaOrCurlyBracket
,
is
.
Tell
());
break
;
// This useless break is only for making warning and coverage happy
}
if
(
parseFlags
&
kParseTrailingCommasFlag
)
{
...
...
@@ -1793,8 +1792,7 @@ private:
case
IterativeParsingKeyValueDelimiterState
:
case
IterativeParsingArrayInitialState
:
case
IterativeParsingElementDelimiterState
:
RAPIDJSON_PARSE_ERROR
(
kParseErrorValueInvalid
,
is
.
Tell
());
return
;
case
IterativeParsingElementState
:
RAPIDJSON_PARSE_ERROR
(
kParseErrorArrayMissCommaOrSquareBracket
,
is
.
Tell
());
return
;
default
:
RAPIDJSON_PARSE_ERROR
(
kParseErrorUnspecificSyntaxError
,
is
.
Tell
());
return
;
default
:
RAPIDJSON_ASSERT
(
src
==
IterativeParsingElementState
);
RAPIDJSON_PARSE_ERROR
(
kParseErrorArrayMissCommaOrSquareBracket
,
is
.
Tell
());
return
;
}
}
...
...
This diff is collapsed.
Click to expand it.
include/rapidjson/schema.h
View file @
8f4e99b2
...
...
@@ -159,7 +159,6 @@ public:
virtual
uint64_t
GetHashCode
(
void
*
hasher
)
=
0
;
virtual
void
DestroryHasher
(
void
*
hasher
)
=
0
;
virtual
void
*
MallocState
(
size_t
size
)
=
0
;
virtual
void
*
ReallocState
(
void
*
originalPtr
,
size_t
originalSize
,
size_t
newSize
)
=
0
;
virtual
void
FreeState
(
void
*
p
)
=
0
;
};
...
...
@@ -1006,6 +1005,7 @@ private:
RegexType
*
r
=
new
(
allocator_
->
Malloc
(
sizeof
(
RegexType
)))
RegexType
(
value
.
GetString
());
if
(
!
r
->
IsValid
())
{
r
->~
RegexType
();
AllocatorType
::
Free
(
r
);
r
=
0
;
}
return
r
;
...
...
@@ -1108,6 +1108,9 @@ private:
if
(
exclusiveMinimum_
?
i
<=
minimum_
.
GetInt64
()
:
i
<
minimum_
.
GetInt64
())
RAPIDJSON_INVALID_KEYWORD_RETURN
(
GetMinimumString
());
}
else
if
(
minimum_
.
IsUint64
())
{
RAPIDJSON_INVALID_KEYWORD_RETURN
(
GetMinimumString
());
// i <= max(int64_t) < minimum.GetUint64()
}
else
if
(
!
CheckDoubleMinimum
(
context
,
static_cast
<
double
>
(
i
)))
return
false
;
}
...
...
@@ -1117,6 +1120,8 @@ private:
if
(
exclusiveMaximum_
?
i
>=
maximum_
.
GetInt64
()
:
i
>
maximum_
.
GetInt64
())
RAPIDJSON_INVALID_KEYWORD_RETURN
(
GetMaximumString
());
}
else
if
(
maximum_
.
IsUint64
())
/* do nothing */
;
// i <= max(int64_t) < maximum_.GetUint64()
else
if
(
!
CheckDoubleMaximum
(
context
,
static_cast
<
double
>
(
i
)))
return
false
;
}
...
...
@@ -1142,6 +1147,8 @@ private:
if
(
exclusiveMinimum_
?
i
<=
minimum_
.
GetUint64
()
:
i
<
minimum_
.
GetUint64
())
RAPIDJSON_INVALID_KEYWORD_RETURN
(
GetMinimumString
());
}
else
if
(
minimum_
.
IsInt64
())
/* do nothing */
;
// i >= 0 > minimum.Getint64()
else
if
(
!
CheckDoubleMinimum
(
context
,
static_cast
<
double
>
(
i
)))
return
false
;
}
...
...
@@ -1151,6 +1158,8 @@ private:
if
(
exclusiveMaximum_
?
i
>=
maximum_
.
GetUint64
()
:
i
>
maximum_
.
GetUint64
())
RAPIDJSON_INVALID_KEYWORD_RETURN
(
GetMaximumString
());
}
else
if
(
maximum_
.
IsInt64
())
RAPIDJSON_INVALID_KEYWORD_RETURN
(
GetMaximumString
());
// i >= 0 > maximum_
else
if
(
!
CheckDoubleMaximum
(
context
,
static_cast
<
double
>
(
i
)))
return
false
;
}
...
...
@@ -1428,8 +1437,6 @@ private:
const
SchemaType
*
s
=
GetSchema
(
pointer
);
if
(
!
s
)
CreateSchema
(
schema
,
pointer
,
v
,
document
);
else
if
(
schema
)
*
schema
=
s
;
for
(
typename
ValueType
::
ConstMemberIterator
itr
=
v
.
MemberBegin
();
itr
!=
v
.
MemberEnd
();
++
itr
)
CreateSchemaRecursive
(
0
,
pointer
.
Append
(
itr
->
name
,
allocator_
),
itr
->
value
,
document
);
...
...
@@ -1766,10 +1773,6 @@ RAPIDJSON_MULTILINEMACRO_END
return
GetStateAllocator
().
Malloc
(
size
);
}
virtual
void
*
ReallocState
(
void
*
originalPtr
,
size_t
originalSize
,
size_t
newSize
)
{
return
GetStateAllocator
().
Realloc
(
originalPtr
,
originalSize
,
newSize
);
}
virtual
void
FreeState
(
void
*
p
)
{
return
StateAllocator
::
Free
(
p
);
}
...
...
This diff is collapsed.
Click to expand it.
test/unittest/encodingstest.cpp
View file @
8f4e99b2
...
...
@@ -423,3 +423,28 @@ TEST(EncodingsTest, UTF32) {
}
}
}
TEST
(
EncodingsTest
,
ASCII
)
{
StringBuffer
os
,
os2
;
for
(
unsigned
codepoint
=
0
;
codepoint
<
128
;
codepoint
++
)
{
os
.
Clear
();
ASCII
<>::
Encode
(
os
,
codepoint
);
const
ASCII
<>::
Ch
*
encodedStr
=
os
.
GetString
();
{
StringStream
is
(
encodedStr
);
unsigned
decodedCodepoint
;
bool
result
=
ASCII
<>::
Decode
(
is
,
&
decodedCodepoint
);
if
(
!
result
||
codepoint
!=
decodedCodepoint
)
std
::
cout
<<
std
::
hex
<<
codepoint
<<
" "
<<
decodedCodepoint
<<
std
::
endl
;
}
// Validate
{
StringStream
is
(
encodedStr
);
os2
.
Clear
();
bool
result
=
ASCII
<>::
Validate
(
is
,
os2
);
EXPECT_TRUE
(
result
);
EXPECT_EQ
(
0
,
StrCmp
(
encodedStr
,
os2
.
GetString
()));
}
}
}
This diff is collapsed.
Click to expand it.
test/unittest/regextest.cpp
View file @
8f4e99b2
...
...
@@ -17,6 +17,14 @@
using
namespace
rapidjson
::
internal
;
TEST
(
Regex
,
Single
)
{
Regex
re
(
"a"
);
ASSERT_TRUE
(
re
.
IsValid
());
EXPECT_TRUE
(
re
.
Match
(
"a"
));
EXPECT_FALSE
(
re
.
Match
(
""
));
EXPECT_FALSE
(
re
.
Match
(
"b"
));
}
TEST
(
Regex
,
Concatenation
)
{
Regex
re
(
"abc"
);
ASSERT_TRUE
(
re
.
IsValid
());
...
...
@@ -560,6 +568,9 @@ TEST(Regex, Invalid) {
TEST_INVALID
(
"a{1,0}"
);
TEST_INVALID
(
"a{-1,0}"
);
TEST_INVALID
(
"a{-1,1}"
);
TEST_INVALID
(
"a{4294967296}"
);
// overflow of unsigned
TEST_INVALID
(
"a{1a}"
);
TEST_INVALID
(
"["
);
TEST_INVALID
(
"[]"
);
TEST_INVALID
(
"[^]"
);
TEST_INVALID
(
"[
\\
a]"
);
...
...
This diff is collapsed.
Click to expand it.
test/unittest/schematest.cpp
View file @
8f4e99b2
...
...
@@ -51,6 +51,11 @@ TEST(SchemaValidator, Hasher) {
TEST_HASHER
(
"false"
,
"null"
,
false
);
TEST_HASHER
(
"1"
,
"1"
,
true
);
TEST_HASHER
(
"2147483648"
,
"2147483648"
,
true
);
// 2^31 can only be fit in unsigned
TEST_HASHER
(
"-2147483649"
,
"-2147483649"
,
true
);
// -2^31 - 1 can only be fit in int64_t
TEST_HASHER
(
"2147483648"
,
"2147483648"
,
true
);
// 2^31 can only be fit in unsigned
TEST_HASHER
(
"4294967296"
,
"4294967296"
,
true
);
// 2^32 can only be fit in int64_t
TEST_HASHER
(
"9223372036854775808"
,
"9223372036854775808"
,
true
);
// 2^63 can only be fit in uint64_t
TEST_HASHER
(
"1.5"
,
"1.5"
,
true
);
TEST_HASHER
(
"1"
,
"1.0"
,
true
);
TEST_HASHER
(
"1"
,
"-1"
,
false
);
...
...
@@ -316,6 +321,10 @@ TEST(SchemaValidator, String) {
VALIDATE
(
s
,
"
\"
I'm a string
\"
"
,
true
);
INVALIDATE
(
s
,
"42"
,
""
,
"type"
,
""
);
INVALIDATE
(
s
,
"2147483648"
,
""
,
"type"
,
""
);
// 2^31 can only be fit in unsigned
INVALIDATE
(
s
,
"-2147483649"
,
""
,
"type"
,
""
);
// -2^31 - 1 can only be fit in int64_t
INVALIDATE
(
s
,
"4294967296"
,
""
,
"type"
,
""
);
// 2^32 can only be fit in int64_t
INVALIDATE
(
s
,
"3.1415926"
,
""
,
"type"
,
""
);
}
TEST
(
SchemaValidator
,
String_LengthRange
)
{
...
...
@@ -340,6 +349,16 @@ TEST(SchemaValidator, String_Pattern) {
INVALIDATE
(
s
,
"
\"
(888)555-1212 ext. 532
\"
"
,
""
,
"pattern"
,
""
);
INVALIDATE
(
s
,
"
\"
(800)FLOWERS
\"
"
,
""
,
"pattern"
,
""
);
}
TEST
(
SchemaValidator
,
String_Pattern_Invalid
)
{
Document
sd
;
sd
.
Parse
(
"{
\"
type
\"
:
\"
string
\"
,
\"
pattern
\"
:
\"
a{0}
\"
}"
);
// TODO: report regex is invalid somehow
SchemaDocument
s
(
sd
);
VALIDATE
(
s
,
"
\"\"
"
,
true
);
VALIDATE
(
s
,
"
\"
a
\"
"
,
true
);
VALIDATE
(
s
,
"
\"
aa
\"
"
,
true
);
}
#endif
TEST
(
SchemaValidator
,
Integer
)
{
...
...
@@ -349,6 +368,10 @@ TEST(SchemaValidator, Integer) {
VALIDATE
(
s
,
"42"
,
true
);
VALIDATE
(
s
,
"-1"
,
true
);
VALIDATE
(
s
,
"2147483648"
,
true
);
// 2^31 can only be fit in unsigned
VALIDATE
(
s
,
"-2147483649"
,
true
);
// -2^31 - 1 can only be fit in int64_t
VALIDATE
(
s
,
"2147483648"
,
true
);
// 2^31 can only be fit in unsigned
VALIDATE
(
s
,
"4294967296"
,
true
);
// 2^32 can only be fit in int64_t
INVALIDATE
(
s
,
"3.1415926"
,
""
,
"type"
,
""
);
INVALIDATE
(
s
,
"
\"
42
\"
"
,
""
,
"type"
,
""
);
}
...
...
@@ -368,11 +391,34 @@ TEST(SchemaValidator, Integer_Range) {
TEST
(
SchemaValidator
,
Integer_Range64Boundary
)
{
Document
sd
;
sd
.
Parse
(
"{
\"
type
\"
:
\"
integer
\"
,
\"
minimum
\"
:-9223372036854775807,
\"
maximum
\"
:
18446744073709551614
}"
);
sd
.
Parse
(
"{
\"
type
\"
:
\"
integer
\"
,
\"
minimum
\"
:-9223372036854775807,
\"
maximum
\"
:
9223372036854775806
}"
);
SchemaDocument
s
(
sd
);
INVALIDATE
(
s
,
"-9223372036854775808"
,
""
,
"minimum"
,
""
);
VALIDATE
(
s
,
"-9223372036854775807"
,
true
);
VALIDATE
(
s
,
"-2147483648"
,
true
);
// int min
VALIDATE
(
s
,
"0"
,
true
);
VALIDATE
(
s
,
"2147483647"
,
true
);
// int max
VALIDATE
(
s
,
"2147483648"
,
true
);
// unsigned first
VALIDATE
(
s
,
"4294967295"
,
true
);
// unsigned max
VALIDATE
(
s
,
"9223372036854775806"
,
true
);
INVALIDATE
(
s
,
"9223372036854775807"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"18446744073709551615"
,
""
,
"maximum"
,
""
);
// uint64_t max
}
TEST
(
SchemaValidator
,
Integer_RangeU64Boundary
)
{
Document
sd
;
sd
.
Parse
(
"{
\"
type
\"
:
\"
integer
\"
,
\"
minimum
\"
:9223372036854775808,
\"
maximum
\"
:18446744073709551614}"
);
SchemaDocument
s
(
sd
);
INVALIDATE
(
s
,
"-9223372036854775808"
,
""
,
"minimum"
,
""
);
INVALIDATE
(
s
,
"9223372036854775807"
,
""
,
"minimum"
,
""
);
INVALIDATE
(
s
,
"-2147483648"
,
""
,
"minimum"
,
""
);
// int min
INVALIDATE
(
s
,
"0"
,
""
,
"minimum"
,
""
);
INVALIDATE
(
s
,
"2147483647"
,
""
,
"minimum"
,
""
);
// int max
INVALIDATE
(
s
,
"2147483648"
,
""
,
"minimum"
,
""
);
// unsigned first
INVALIDATE
(
s
,
"4294967295"
,
""
,
"minimum"
,
""
);
// unsigned max
VALIDATE
(
s
,
"9223372036854775808"
,
true
);
VALIDATE
(
s
,
"18446744073709551614"
,
true
);
INVALIDATE
(
s
,
"18446744073709551615"
,
""
,
"maximum"
,
""
);
}
...
...
@@ -418,10 +464,73 @@ TEST(SchemaValidator, Number_Range) {
INVALIDATE
(
s
,
"-1"
,
""
,
"minimum"
,
""
);
VALIDATE
(
s
,
"0"
,
true
);
VALIDATE
(
s
,
"0.1"
,
true
);
VALIDATE
(
s
,
"10"
,
true
);
VALIDATE
(
s
,
"99"
,
true
);
VALIDATE
(
s
,
"99.9"
,
true
);
INVALIDATE
(
s
,
"100"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"100.0"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"101.5"
,
""
,
"maximum"
,
""
);
}
TEST
(
SchemaValidator
,
Number_RangeInt
)
{
Document
sd
;
sd
.
Parse
(
"{
\"
type
\"
:
\"
number
\"
,
\"
minimum
\"
:-100,
\"
maximum
\"
:-1,
\"
exclusiveMaximum
\"
:true}"
);
SchemaDocument
s
(
sd
);
INVALIDATE
(
s
,
"-101"
,
""
,
"minimum"
,
""
);
INVALIDATE
(
s
,
"-100.1"
,
""
,
"minimum"
,
""
);
VALIDATE
(
s
,
"-100"
,
true
);
VALIDATE
(
s
,
"-2"
,
true
);
INVALIDATE
(
s
,
"-1"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"-0.9"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"0"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"2147483647"
,
""
,
"maximum"
,
""
);
// int max
INVALIDATE
(
s
,
"2147483648"
,
""
,
"maximum"
,
""
);
// unsigned first
INVALIDATE
(
s
,
"4294967295"
,
""
,
"maximum"
,
""
);
// unsigned max
INVALIDATE
(
s
,
"9223372036854775808"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"18446744073709551614"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"18446744073709551615"
,
""
,
"maximum"
,
""
);
}
TEST
(
SchemaValidator
,
Number_RangeDouble
)
{
Document
sd
;
sd
.
Parse
(
"{
\"
type
\"
:
\"
number
\"
,
\"
minimum
\"
:0.1,
\"
maximum
\"
:100.1,
\"
exclusiveMaximum
\"
:true}"
);
SchemaDocument
s
(
sd
);
INVALIDATE
(
s
,
"-9223372036854775808"
,
""
,
"minimum"
,
""
);
INVALIDATE
(
s
,
"-2147483648"
,
""
,
"minimum"
,
""
);
// int min
INVALIDATE
(
s
,
"-1"
,
""
,
"minimum"
,
""
);
VALIDATE
(
s
,
"0.1"
,
true
);
VALIDATE
(
s
,
"10"
,
true
);
VALIDATE
(
s
,
"99"
,
true
);
VALIDATE
(
s
,
"100"
,
true
);
INVALIDATE
(
s
,
"101"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"101.5"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"18446744073709551614"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"18446744073709551615"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"2147483647"
,
""
,
"maximum"
,
""
);
// int max
INVALIDATE
(
s
,
"2147483648"
,
""
,
"maximum"
,
""
);
// unsigned first
INVALIDATE
(
s
,
"4294967295"
,
""
,
"maximum"
,
""
);
// unsigned max
INVALIDATE
(
s
,
"9223372036854775808"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"18446744073709551614"
,
""
,
"maximum"
,
""
);
INVALIDATE
(
s
,
"18446744073709551615"
,
""
,
"maximum"
,
""
);
}
TEST
(
SchemaValidator
,
Number_RangeDoubleU64Boundary
)
{
Document
sd
;
sd
.
Parse
(
"{
\"
type
\"
:
\"
number
\"
,
\"
minimum
\"
:9223372036854775808.0,
\"
maximum
\"
:18446744073709550000.0}"
);
SchemaDocument
s
(
sd
);
INVALIDATE
(
s
,
"-9223372036854775808"
,
""
,
"minimum"
,
""
);
INVALIDATE
(
s
,
"-2147483648"
,
""
,
"minimum"
,
""
);
// int min
INVALIDATE
(
s
,
"0"
,
""
,
"minimum"
,
""
);
INVALIDATE
(
s
,
"2147483647"
,
""
,
"minimum"
,
""
);
// int max
INVALIDATE
(
s
,
"2147483648"
,
""
,
"minimum"
,
""
);
// unsigned first
INVALIDATE
(
s
,
"4294967295"
,
""
,
"minimum"
,
""
);
// unsigned max
VALIDATE
(
s
,
"9223372036854775808"
,
true
);
VALIDATE
(
s
,
"18446744073709540000"
,
true
);
INVALIDATE
(
s
,
"18446744073709551615"
,
""
,
"maximum"
,
""
);
}
TEST
(
SchemaValidator
,
Number_MultipleOf
)
{
...
...
@@ -434,6 +543,13 @@ TEST(SchemaValidator, Number_MultipleOf) {
VALIDATE
(
s
,
"-10"
,
true
);
VALIDATE
(
s
,
"20"
,
true
);
INVALIDATE
(
s
,
"23"
,
""
,
"multipleOf"
,
""
);
INVALIDATE
(
s
,
"-2147483648"
,
""
,
"multipleOf"
,
""
);
// int min
VALIDATE
(
s
,
"-2147483640"
,
true
);
INVALIDATE
(
s
,
"2147483647"
,
""
,
"multipleOf"
,
""
);
// int max
INVALIDATE
(
s
,
"2147483648"
,
""
,
"multipleOf"
,
""
);
// unsigned first
VALIDATE
(
s
,
"2147483650"
,
true
);
INVALIDATE
(
s
,
"4294967295"
,
""
,
"multipleOf"
,
""
);
// unsigned max
VALIDATE
(
s
,
"4294967300"
,
true
);
}
TEST
(
SchemaValidator
,
Number_MultipleOfOne
)
{
...
...
@@ -844,6 +960,19 @@ TEST(SchemaValidator, AllOf_Nested) {
INVALIDATE
(
s
,
"123"
,
""
,
"allOf"
,
""
);
}
TEST
(
SchemaValidator
,
EscapedPointer
)
{
Document
sd
;
sd
.
Parse
(
"{"
"
\"
type
\"
:
\"
object
\"
,"
"
\"
properties
\"
: {"
"
\"
~/
\"
: {
\"
type
\"
:
\"
number
\"
}"
" }"
"}"
);
SchemaDocument
s
(
sd
);
INVALIDATE
(
s
,
"{
\"
~/
\"
:true}"
,
"/properties/~0~1"
,
"type"
,
"/~0~1"
);
}
template
<
typename
Allocator
>
static
char
*
ReadFile
(
const
char
*
filename
,
Allocator
&
allocator
)
{
const
char
*
paths
[]
=
{
...
...
This diff is collapsed.
Click to expand it.
test/unittest/simdtest.cpp
View file @
8f4e99b2
...
...
@@ -100,29 +100,60 @@ struct ScanCopyUnescapedStringHandler : BaseReaderHandler<UTF8<>, ScanCopyUnesca
memcpy
(
buffer
,
str
,
length
+
1
);
return
true
;
}
char
buffer
[
1024
+
5
];
char
buffer
[
1024
+
5
+
32
];
};
template
<
unsigned
parseFlags
,
typename
StreamType
>
void
TestScanCopyUnescapedString
()
{
for
(
size_t
step
=
0
;
step
<
1024
;
step
++
)
{
char
json
[
1024
+
5
];
char
*
p
=
json
;
*
p
++=
'\"'
;
for
(
size_t
i
=
0
;
i
<
step
;
i
++
)
*
p
++=
"ABCD"
[
i
%
4
];
*
p
++
=
'\\'
;
*
p
++
=
'\\'
;
*
p
++
=
'\"'
;
*
p
++
=
'\0'
;
StreamType
s
(
json
);
Reader
reader
;
ScanCopyUnescapedStringHandler
h
;
reader
.
Parse
<
parseFlags
>
(
s
,
h
);
EXPECT_TRUE
(
memcmp
(
h
.
buffer
,
json
+
1
,
step
)
==
0
);
EXPECT_EQ
(
'\\'
,
h
.
buffer
[
step
]);
// escaped
EXPECT_EQ
(
'\0'
,
h
.
buffer
[
step
+
1
]);
char
buffer
[
1024
+
5
+
32
];
char
backup
[
1024
+
5
+
32
];
// Test "ABCDABCD...\\"
for
(
size_t
offset
=
0
;
offset
<
32
;
offset
++
)
{
for
(
size_t
step
=
0
;
step
<
1024
;
step
++
)
{
char
*
json
=
buffer
+
offset
;
char
*
p
=
json
;
*
p
++
=
'\"'
;
for
(
size_t
i
=
0
;
i
<
step
;
i
++
)
*
p
++
=
"ABCD"
[
i
%
4
];
*
p
++
=
'\\'
;
*
p
++
=
'\\'
;
*
p
++
=
'\"'
;
*
p
++
=
'\0'
;
strcpy
(
backup
,
json
);
// insitu parsing will overwrite buffer, so need to backup first
StreamType
s
(
json
);
Reader
reader
;
ScanCopyUnescapedStringHandler
h
;
reader
.
Parse
<
parseFlags
>
(
s
,
h
);
EXPECT_TRUE
(
memcmp
(
h
.
buffer
,
backup
+
1
,
step
)
==
0
);
EXPECT_EQ
(
'\\'
,
h
.
buffer
[
step
]);
// escaped
EXPECT_EQ
(
'\0'
,
h
.
buffer
[
step
+
1
]);
}
}
// Test "\\ABCDABCD..."
for
(
size_t
offset
=
0
;
offset
<
32
;
offset
++
)
{
for
(
size_t
step
=
0
;
step
<
1024
;
step
++
)
{
char
*
json
=
buffer
+
offset
;
char
*
p
=
json
;
*
p
++
=
'\"'
;
*
p
++
=
'\\'
;
*
p
++
=
'\\'
;
for
(
size_t
i
=
0
;
i
<
step
;
i
++
)
*
p
++
=
"ABCD"
[
i
%
4
];
*
p
++
=
'\"'
;
*
p
++
=
'\0'
;
strcpy
(
backup
,
json
);
// insitu parsing will overwrite buffer, so need to backup first
StreamType
s
(
json
);
Reader
reader
;
ScanCopyUnescapedStringHandler
h
;
reader
.
Parse
<
parseFlags
>
(
s
,
h
);
EXPECT_TRUE
(
memcmp
(
h
.
buffer
+
1
,
backup
+
3
,
step
)
==
0
);
EXPECT_EQ
(
'\\'
,
h
.
buffer
[
0
]);
// escaped
EXPECT_EQ
(
'\0'
,
h
.
buffer
[
step
+
1
]);
}
}
}
...
...
@@ -132,47 +163,50 @@ TEST(SIMD, SIMD_SUFFIX(ScanCopyUnescapedString)) {
}
TEST
(
SIMD
,
SIMD_SUFFIX
(
ScanWriteUnescapedString
))
{
for
(
size_t
step
=
0
;
step
<
1024
;
step
++
)
{
char
s
[
2048
+
1
];
char
*
p
=
s
;
for
(
size_t
i
=
0
;
i
<
step
;
i
++
)
*
p
++=
"ABCD"
[
i
%
4
];
char
escape
=
"
\0\n\\\"
"
[
step
%
4
];
*
p
++
=
escape
;
for
(
size_t
i
=
0
;
i
<
step
;
i
++
)
*
p
++=
"ABCD"
[
i
%
4
];
StringBuffer
sb
;
Writer
<
StringBuffer
>
writer
(
sb
);
writer
.
String
(
s
,
SizeType
(
step
*
2
+
1
));
const
char
*
q
=
sb
.
GetString
();
EXPECT_EQ
(
'\"'
,
*
q
++
);
for
(
size_t
i
=
0
;
i
<
step
;
i
++
)
EXPECT_EQ
(
"ABCD"
[
i
%
4
],
*
q
++
);
if
(
escape
==
'\0'
)
{
EXPECT_EQ
(
'\\'
,
*
q
++
);
EXPECT_EQ
(
'u'
,
*
q
++
);
EXPECT_EQ
(
'0'
,
*
q
++
);
EXPECT_EQ
(
'0'
,
*
q
++
);
EXPECT_EQ
(
'0'
,
*
q
++
);
EXPECT_EQ
(
'0'
,
*
q
++
);
}
else
if
(
escape
==
'\n'
)
{
EXPECT_EQ
(
'\\'
,
*
q
++
);
EXPECT_EQ
(
'n'
,
*
q
++
);
}
else
if
(
escape
==
'\\'
)
{
EXPECT_EQ
(
'\\'
,
*
q
++
);
EXPECT_EQ
(
'\\'
,
*
q
++
);
}
else
if
(
escape
==
'\"'
)
{
EXPECT_EQ
(
'\\'
,
*
q
++
);
char
buffer
[
2048
+
1
+
32
];
for
(
size_t
offset
=
0
;
offset
<
32
;
offset
++
)
{
for
(
size_t
step
=
0
;
step
<
1024
;
step
++
)
{
char
*
s
=
buffer
+
offset
;
char
*
p
=
s
;
for
(
size_t
i
=
0
;
i
<
step
;
i
++
)
*
p
++
=
"ABCD"
[
i
%
4
];
char
escape
=
"
\0\n\\\"
"
[
step
%
4
];
*
p
++
=
escape
;
for
(
size_t
i
=
0
;
i
<
step
;
i
++
)
*
p
++
=
"ABCD"
[
i
%
4
];
StringBuffer
sb
;
Writer
<
StringBuffer
>
writer
(
sb
);
writer
.
String
(
s
,
SizeType
(
step
*
2
+
1
));
const
char
*
q
=
sb
.
GetString
();
EXPECT_EQ
(
'\"'
,
*
q
++
);
for
(
size_t
i
=
0
;
i
<
step
;
i
++
)
EXPECT_EQ
(
"ABCD"
[
i
%
4
],
*
q
++
);
if
(
escape
==
'\0'
)
{
EXPECT_EQ
(
'\\'
,
*
q
++
);
EXPECT_EQ
(
'u'
,
*
q
++
);
EXPECT_EQ
(
'0'
,
*
q
++
);
EXPECT_EQ
(
'0'
,
*
q
++
);
EXPECT_EQ
(
'0'
,
*
q
++
);
EXPECT_EQ
(
'0'
,
*
q
++
);
}
else
if
(
escape
==
'\n'
)
{
EXPECT_EQ
(
'\\'
,
*
q
++
);
EXPECT_EQ
(
'n'
,
*
q
++
);
}
else
if
(
escape
==
'\\'
)
{
EXPECT_EQ
(
'\\'
,
*
q
++
);
EXPECT_EQ
(
'\\'
,
*
q
++
);
}
else
if
(
escape
==
'\"'
)
{
EXPECT_EQ
(
'\\'
,
*
q
++
);
EXPECT_EQ
(
'\"'
,
*
q
++
);
}
for
(
size_t
i
=
0
;
i
<
step
;
i
++
)
EXPECT_EQ
(
"ABCD"
[
i
%
4
],
*
q
++
);
EXPECT_EQ
(
'\"'
,
*
q
++
);
EXPECT_EQ
(
'\0'
,
*
q
++
);
}
for
(
size_t
i
=
0
;
i
<
step
;
i
++
)
EXPECT_EQ
(
"ABCD"
[
i
%
4
],
*
q
++
);
EXPECT_EQ
(
'\"'
,
*
q
++
);
EXPECT_EQ
(
'\0'
,
*
q
++
);
}
}
...
...
This diff is collapsed.
Click to expand it.
test/unittest/valuetest.cpp
View file @
8f4e99b2
...
...
@@ -402,6 +402,7 @@ TEST(Value, Int) {
EXPECT_TRUE
(
x
.
IsUint64
());
EXPECT_FALSE
(
x
.
IsDouble
());
EXPECT_FALSE
(
x
.
IsFloat
());
EXPECT_FALSE
(
x
.
IsNull
());
EXPECT_FALSE
(
x
.
IsBool
());
EXPECT_FALSE
(
x
.
IsFalse
());
...
...
@@ -456,6 +457,7 @@ TEST(Value, Uint) {
EXPECT_NEAR
(
1234.0
,
x
.
GetDouble
(),
0.0
);
// Number can always be cast as double but !IsDouble().
EXPECT_FALSE
(
x
.
IsDouble
());
EXPECT_FALSE
(
x
.
IsFloat
());
EXPECT_FALSE
(
x
.
IsNull
());
EXPECT_FALSE
(
x
.
IsBool
());
EXPECT_FALSE
(
x
.
IsFalse
());
...
...
@@ -500,6 +502,7 @@ TEST(Value, Int64) {
EXPECT_TRUE
(
x
.
IsUint64
());
EXPECT_FALSE
(
x
.
IsDouble
());
EXPECT_FALSE
(
x
.
IsFloat
());
EXPECT_FALSE
(
x
.
IsNull
());
EXPECT_FALSE
(
x
.
IsBool
());
EXPECT_FALSE
(
x
.
IsFalse
());
...
...
@@ -561,6 +564,7 @@ TEST(Value, Uint64) {
EXPECT_TRUE
(
x
.
IsUint64
());
EXPECT_FALSE
(
x
.
IsDouble
());
EXPECT_FALSE
(
x
.
IsFloat
());
EXPECT_FALSE
(
x
.
IsNull
());
EXPECT_FALSE
(
x
.
IsBool
());
EXPECT_FALSE
(
x
.
IsFalse
());
...
...
This diff is collapsed.
Click to expand it.
test/unittest/writertest.cpp
View file @
8f4e99b2
...
...
@@ -18,6 +18,7 @@
#include "rapidjson/reader.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/memorybuffer.h"
using
namespace
rapidjson
;
...
...
@@ -94,6 +95,19 @@ TEST(Writer, String) {
#endif
}
TEST
(
Writer
,
ScanWriteUnescapedString
)
{
const
char
json
[]
=
"[
\"
\\\"
0123456789ABCDEF
\"
]"
;
// ^ scanning stops here.
char
buffer2
[
sizeof
(
json
)
+
32
];
// Use different offset to test different alignments
for
(
int
i
=
0
;
i
<
32
;
i
++
)
{
char
*
p
=
buffer2
+
i
;
memcpy
(
p
,
json
,
sizeof
(
json
));
TEST_ROUNDTRIP
(
p
);
}
}
TEST
(
Writer
,
Double
)
{
TEST_ROUNDTRIP
(
"[1.2345,1.2345678,0.123456789012,1234567.8]"
);
TEST_ROUNDTRIP
(
"0.0"
);
...
...
@@ -107,35 +121,59 @@ TEST(Writer, Double) {
}
// UTF8 -> TargetEncoding -> UTF8
template
<
typename
TargetEncoding
>
void
TestTranscode
(
const
char
*
json
)
{
StringStream
s
(
json
);
GenericStringBuffer
<
TargetEncoding
>
buffer
;
Writer
<
GenericStringBuffer
<
TargetEncoding
>
,
UTF8
<>
,
TargetEncoding
>
writer
(
buffer
);
Reader
reader
;
reader
.
Parse
(
s
,
writer
);
StringBuffer
buffer2
;
Writer
<
StringBuffer
>
writer2
(
buffer2
);
GenericReader
<
TargetEncoding
,
UTF8
<>
>
reader2
;
GenericStringStream
<
TargetEncoding
>
s2
(
buffer
.
GetString
());
reader2
.
Parse
(
s2
,
writer2
);
EXPECT_STREQ
(
json
,
buffer2
.
GetString
());
}
TEST
(
Writer
,
Transcode
)
{
const
char
json
[]
=
"{
\"
hello
\"
:
\"
world
\"
,
\"
t
\"
:true,
\"
f
\"
:false,
\"
n
\"
:null,
\"
i
\"
:123,
\"
pi
\"
:3.1416,
\"
a
\"
:[1,2,3],
\"
dollar
\"
:
\"\x24\"
,
\"
cents
\"
:
\"\xC2\xA2\"
,
\"
euro
\"
:
\"\xE2\x82\xAC\"
,
\"
gclef
\"
:
\"\xF0\x9D\x84\x9E\"
}"
;
// UTF8 -> UTF16 -> UTF8
{
StringStream
s
(
json
);
StringBuffer
buffer
;
Writer
<
StringBuffer
,
UTF16
<>
,
UTF8
<>
>
writer
(
buffer
);
GenericReader
<
UTF8
<>
,
UTF16
<>
>
reader
;
reader
.
Parse
(
s
,
writer
);
EXPECT_STREQ
(
json
,
buffer
.
GetString
());
}
TestTranscode
<
UTF8
<>
>
(
json
);
// UTF8 -> UTF8 -> ASCII -> UTF8 -> UTF8
{
// UTF8 -> ASCII -> UTF8
TestTranscode
<
ASCII
<>
>
(
json
);
// UTF8 -> UTF16 -> UTF8
TestTranscode
<
UTF16
<>
>
(
json
);
// UTF8 -> UTF32 -> UTF8
TestTranscode
<
UTF32
<>
>
(
json
);
// UTF8 -> AutoUTF -> UTF8
UTFType
types
[]
=
{
kUTF8
,
kUTF16LE
,
kUTF16BE
,
kUTF32LE
,
kUTF32BE
};
for
(
size_t
i
=
0
;
i
<
5
;
i
++
)
{
StringStream
s
(
json
);
StringBuffer
buffer
;
Writer
<
StringBuffer
,
UTF8
<>
,
ASCII
<>
>
writer
(
buffer
);
MemoryBuffer
buffer
;
AutoUTFOutputStream
<
unsigned
,
MemoryBuffer
>
os
(
buffer
,
types
[
i
],
true
);
Writer
<
AutoUTFOutputStream
<
unsigned
,
MemoryBuffer
>
,
UTF8
<>
,
AutoUTF
<
unsigned
>
>
writer
(
os
);
Reader
reader
;
reader
.
Parse
(
s
,
writer
);
StringBuffer
buffer2
;
Writer
<
StringBuffer
>
writer2
(
buffer2
);
GenericReader
<
ASCII
<>
,
UTF8
<>
>
reader2
;
StringStream
s2
(
buffer
.
GetString
());
reader2
.
Parse
(
s2
,
writer2
);
GenericReader
<
AutoUTF
<
unsigned
>
,
UTF8
<>
>
reader2
;
MemoryStream
s2
(
buffer
.
GetBuffer
(),
buffer
.
GetSize
());
AutoUTFInputStream
<
unsigned
,
MemoryStream
>
is
(
s2
);
reader2
.
Parse
(
is
,
writer2
);
EXPECT_STREQ
(
json
,
buffer2
.
GetString
());
}
}
#include <sstream>
...
...
@@ -410,6 +448,10 @@ TEST(Writer, NaN) {
StringBuffer
buffer
;
Writer
<
StringBuffer
>
writer
(
buffer
);
EXPECT_FALSE
(
writer
.
Double
(
nan
));
GenericStringBuffer
<
UTF16
<>
>
buffer2
;
Writer
<
GenericStringBuffer
<
UTF16
<>
>
>
writer2
(
buffer2
);
EXPECT_FALSE
(
writer2
.
Double
(
nan
));
}
TEST
(
Writer
,
Inf
)
{
...
...
@@ -418,7 +460,7 @@ TEST(Writer, Inf) {
StringBuffer
buffer
;
{
Writer
<
StringBuffer
>
writer
(
buffer
);
EXPECT_FALSE
(
writer
.
Double
(
inf
));
EXPECT_FALSE
(
writer
.
Double
(
inf
));
}
{
Writer
<
StringBuffer
>
writer
(
buffer
);
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment