Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
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
capnproto
Commits
4bfcf573
Commit
4bfcf573
authored
Dec 13, 2016
by
Kenton Varda
Committed by
GitHub
Dec 13, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #395 from dwrensha/canonicalize-empty-struct
handle empty structs in isCanonical()
parents
9046dc1a
ab23cf42
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
6 deletions
+61
-6
Makefile.am
c++/Makefile.am
+1
-0
canonicalize-test.c++
c++/src/capnp/canonicalize-test.c++
+51
-3
layout.c++
c++/src/capnp/layout.c++
+9
-3
No files found.
c++/Makefile.am
View file @
4bfcf573
...
...
@@ -394,6 +394,7 @@ heavy_tests = \
src/kj/parse/common-test.c++
\
src/kj/parse/char-test.c++
\
src/kj/std/iostream-test.c++
\
src/capnp/canonicalize-test.c++
\
src/capnp/capability-test.c++
\
src/capnp/membrane-test.c++
\
src/capnp/schema-test.c++
\
...
...
c++/src/capnp/canonicalize-test.c++
View file @
4bfcf573
...
...
@@ -31,7 +31,7 @@ using test::TestLists;
namespace
{
KJ_TEST
(
"canonicalize yields can
n
onical message"
)
{
KJ_TEST
(
"canonicalize yields canonical message"
)
{
MallocMessageBuilder
builder
;
auto
root
=
builder
.
initRoot
<
TestAllTypes
>
();
...
...
@@ -41,12 +41,60 @@ KJ_TEST("canonicalize yields cannonical message") {
//Will assert if canonicalize failed to do so
}
KJ_TEST
(
"canonicalize succeeds on empty struct"
)
{
MallocMessageBuilder
builder
;
auto
root
=
builder
.
initRoot
<
TestAllTypes
>
();
canonicalize
(
root
.
asReader
());
// Throws an exception on canoncalization failure.
}
KJ_TEST
(
"canonical non-null empty struct field"
)
{
AlignedData
<
4
>
nonNullEmptyStruct
=
{{
// Struct pointer, body immediately follows, two pointer fields, no data.
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0x00
,
// First pointer field, struct, offset of 1, data size 1, no pointers.
0x04
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
// Non-null pointer to empty struct.
0xfc
,
0xff
,
0xff
,
0xff
,
0x00
,
0x00
,
0x00
,
0x00
,
// Body of struct filled with non-zero data.
0xee
,
0xee
,
0xee
,
0xee
,
0xee
,
0xee
,
0xee
,
0xee
,
}};
kj
::
ArrayPtr
<
const
word
>
segments
[
1
]
=
{
kj
::
arrayPtr
(
nonNullEmptyStruct
.
words
,
4
)};
SegmentArrayMessageReader
messageReader
(
kj
::
arrayPtr
(
segments
,
1
));
KJ_ASSERT
(
messageReader
.
isCanonical
());
}
KJ_TEST
(
"for pointers to empty structs, preorder is not canonical"
)
{
AlignedData
<
4
>
nonNullEmptyStruct
=
{{
// Struct pointer, body immediately follows, two pointer fields, no data.
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0x00
,
// First pointer field, struct, offset of 1, data size 1, no pointers.
0x04
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
// Non-null pointer to empty struct. Offset puts it in "preorder". Would need to have
// an offset of -1 to be canonical.
0x04
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
// Body of struct filled with non-zero data.
0xee
,
0xee
,
0xee
,
0xee
,
0xee
,
0xee
,
0xee
,
0xee
,
}};
kj
::
ArrayPtr
<
const
word
>
segments
[
1
]
=
{
kj
::
arrayPtr
(
nonNullEmptyStruct
.
words
,
4
)};
SegmentArrayMessageReader
messageReader
(
kj
::
arrayPtr
(
segments
,
1
));
KJ_ASSERT
(
!
messageReader
.
isCanonical
());
}
KJ_TEST
(
"isCanonical requires pointer preorder"
)
{
AlignedData
<
5
>
misorderedSegment
=
{{
//Struct pointer, data immediately follows, two pointer fields, no data
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
0x00
,
//Pointer field 1, pointing to the last entry, data size 1, no pointer
0x0
2
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x0
8
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
//Pointer field 2, pointing to the next entry, data size 2, no pointer
0x00
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
//Data for field 2
...
...
@@ -55,7 +103,7 @@ KJ_TEST("isCanonical requires pointer preorder") {
0x07
,
0x06
,
0x05
,
0x04
,
0x03
,
0x02
,
0x01
,
0x00
}};
kj
::
ArrayPtr
<
const
word
>
segments
[
1
]
=
{
kj
::
arrayPtr
(
misorderedSegment
.
words
,
3
)};
5
)};
SegmentArrayMessageReader
outOfOrder
(
kj
::
arrayPtr
(
segments
,
1
));
KJ_ASSERT
(
!
outOfOrder
.
isCanonical
());
...
...
c++/src/capnp/layout.c++
View file @
4bfcf573
...
...
@@ -2589,10 +2589,16 @@ bool PointerReader::isCanonical(const word **readHead) {
case
PointerType
:
:
NULL_
:
// The pointer is null, we are canonical and do not read
return
true
;
case
PointerType
:
:
STRUCT
:
case
PointerType
:
:
STRUCT
:
{
bool
dataTrunc
,
ptrTrunc
;
return
(
this
->
getStruct
(
nullptr
).
isCanonical
(
readHead
,
readHead
,
&
dataTrunc
,
&
ptrTrunc
)
&&
dataTrunc
&&
ptrTrunc
);
auto
structReader
=
this
->
getStruct
(
nullptr
);
if
(
structReader
.
getDataSectionSize
()
==
0
*
BITS
&&
structReader
.
getPointerSectionSize
()
==
0
*
POINTERS
)
{
return
reinterpret_cast
<
const
word
*>
(
this
->
pointer
)
==
structReader
.
getLocation
();
}
else
{
return
structReader
.
isCanonical
(
readHead
,
readHead
,
&
dataTrunc
,
&
ptrTrunc
)
&&
dataTrunc
&&
ptrTrunc
;
}
}
case
PointerType
:
:
LIST
:
return
this
->
getListAnySize
(
nullptr
).
isCanonical
(
readHead
);
case
PointerType
:
:
CAPABILITY
:
...
...
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