Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
F
flatbuffers
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
flatbuffers
Commits
917687c7
Commit
917687c7
authored
Sep 17, 2019
by
Wouter van Oortmerssen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed Reflection Verifier not handling vectors of unions.
Change-Id: Ie94386ff8e10fd2a964bd9155139b50953746a37
parent
f9277e69
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
78 additions
and
38 deletions
+78
-38
flatbuffers.h
include/flatbuffers/flatbuffers.h
+5
-0
reflection.cpp
src/reflection.cpp
+64
-35
test.cpp
tests/test.cpp
+9
-3
No files found.
include/flatbuffers/flatbuffers.h
View file @
917687c7
...
@@ -2109,6 +2109,11 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
...
@@ -2109,6 +2109,11 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return
VerifyAlignment
<
T
>
(
elem
)
&&
Verify
(
elem
,
sizeof
(
T
));
return
VerifyAlignment
<
T
>
(
elem
)
&&
Verify
(
elem
,
sizeof
(
T
));
}
}
bool
VerifyFromPointer
(
const
uint8_t
*
p
,
size_t
len
)
{
auto
o
=
static_cast
<
size_t
>
(
p
-
buf_
);
return
Verify
(
o
,
len
);
}
// Verify relative to a known-good base pointer.
// Verify relative to a known-good base pointer.
bool
Verify
(
const
uint8_t
*
base
,
voffset_t
elem_off
,
size_t
elem_len
)
const
{
bool
Verify
(
const
uint8_t
*
base
,
voffset_t
elem_off
,
size_t
elem_len
)
const
{
return
Verify
(
static_cast
<
size_t
>
(
base
-
buf_
)
+
elem_off
,
elem_len
);
return
Verify
(
static_cast
<
size_t
>
(
base
-
buf_
)
+
elem_off
,
elem_len
);
...
...
src/reflection.cpp
View file @
917687c7
...
@@ -515,6 +515,32 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
...
@@ -515,6 +515,32 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
const
reflection
::
Object
&
obj
,
const
reflection
::
Object
&
obj
,
const
flatbuffers
::
Table
*
table
,
bool
required
);
const
flatbuffers
::
Table
*
table
,
bool
required
);
bool
VerifyUnion
(
flatbuffers
::
Verifier
&
v
,
const
reflection
::
Schema
&
schema
,
uint8_t
utype
,
const
uint8_t
*
elem
,
const
reflection
::
Field
&
union_field
)
{
if
(
!
utype
)
return
true
;
// Not present.
auto
fb_enum
=
schema
.
enums
()
->
Get
(
union_field
.
type
()
->
index
());
if
(
utype
>=
fb_enum
->
values
()
->
size
())
return
false
;
auto
elem_type
=
fb_enum
->
values
()
->
Get
(
utype
)
->
union_type
();
switch
(
elem_type
->
base_type
())
{
case
reflection
:
:
Obj
:
{
auto
elem_obj
=
schema
.
objects
()
->
Get
(
elem_type
->
index
());
if
(
elem_obj
->
is_struct
())
{
return
v
.
VerifyFromPointer
(
elem
,
elem_obj
->
bytesize
());
}
else
{
return
VerifyObject
(
v
,
schema
,
*
elem_obj
,
reinterpret_cast
<
const
flatbuffers
::
Table
*>
(
elem
),
true
);
}
}
case
reflection
:
:
String
:
return
v
.
VerifyString
(
reinterpret_cast
<
const
flatbuffers
::
String
*>
(
elem
));
default:
return
false
;
}
}
bool
VerifyVector
(
flatbuffers
::
Verifier
&
v
,
const
reflection
::
Schema
&
schema
,
bool
VerifyVector
(
flatbuffers
::
Verifier
&
v
,
const
reflection
::
Schema
&
schema
,
const
flatbuffers
::
Table
&
table
,
const
flatbuffers
::
Table
&
table
,
const
reflection
::
Field
&
vec_field
)
{
const
reflection
::
Field
&
vec_field
)
{
...
@@ -522,7 +548,6 @@ bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
...
@@ -522,7 +548,6 @@ bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
if
(
!
table
.
VerifyField
<
uoffset_t
>
(
v
,
vec_field
.
offset
()))
return
false
;
if
(
!
table
.
VerifyField
<
uoffset_t
>
(
v
,
vec_field
.
offset
()))
return
false
;
switch
(
vec_field
.
type
()
->
element
())
{
switch
(
vec_field
.
type
()
->
element
())
{
case
reflection
:
:
None
:
FLATBUFFERS_ASSERT
(
false
);
break
;
case
reflection
:
:
UType
:
case
reflection
:
:
UType
:
return
v
.
VerifyVector
(
flatbuffers
::
GetFieldV
<
uint8_t
>
(
table
,
vec_field
));
return
v
.
VerifyVector
(
flatbuffers
::
GetFieldV
<
uint8_t
>
(
table
,
vec_field
));
case
reflection
:
:
Bool
:
case
reflection
:
:
Bool
:
...
@@ -552,48 +577,55 @@ bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
...
@@ -552,48 +577,55 @@ bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
return
false
;
return
false
;
}
}
}
}
case
reflection
:
:
Vector
:
FLATBUFFERS_ASSERT
(
false
);
break
;
case
reflection
:
:
Obj
:
{
case
reflection
:
:
Obj
:
{
auto
obj
=
schema
.
objects
()
->
Get
(
vec_field
.
type
()
->
index
());
auto
obj
=
schema
.
objects
()
->
Get
(
vec_field
.
type
()
->
index
());
if
(
obj
->
is_struct
())
{
if
(
obj
->
is_struct
())
{
if
(
!
VerifyVectorOfStructs
(
v
,
table
,
vec_field
.
offset
(),
*
obj
,
return
VerifyVectorOfStructs
(
v
,
table
,
vec_field
.
offset
(),
*
obj
,
vec_field
.
required
()))
{
vec_field
.
required
());
return
false
;
}
}
else
{
}
else
{
auto
vec
=
auto
vec
=
flatbuffers
::
GetFieldV
<
flatbuffers
::
Offset
<
flatbuffers
::
Table
>>
(
flatbuffers
::
GetFieldV
<
flatbuffers
::
Offset
<
flatbuffers
::
Table
>>
(
table
,
vec_field
);
table
,
vec_field
);
if
(
!
v
.
VerifyVector
(
vec
))
return
false
;
if
(
!
v
.
VerifyVector
(
vec
))
return
false
;
if
(
vec
)
{
if
(
!
vec
)
return
true
;
for
(
uoffset_t
j
=
0
;
j
<
vec
->
size
();
j
++
)
{
for
(
uoffset_t
j
=
0
;
j
<
vec
->
size
();
j
++
)
{
if
(
!
VerifyObject
(
v
,
schema
,
*
obj
,
vec
->
Get
(
j
),
true
))
{
if
(
!
VerifyObject
(
v
,
schema
,
*
obj
,
vec
->
Get
(
j
),
true
))
{
return
false
;
return
false
;
}
}
}
}
}
return
true
;
}
}
case
reflection
:
:
Union
:
{
auto
vec
=
flatbuffers
::
GetFieldV
<
flatbuffers
::
Offset
<
uint8_t
>>
(
table
,
vec_field
);
if
(
!
v
.
VerifyVector
(
vec
))
return
false
;
if
(
!
vec
)
return
true
;
auto
type_vec
=
table
.
GetPointer
<
Vector
<
uint8_t
>
*>
(
vec_field
.
offset
()
-
sizeof
(
voffset_t
));
if
(
!
v
.
VerifyVector
(
type_vec
))
return
false
;
for
(
uoffset_t
j
=
0
;
j
<
vec
->
size
();
j
++
)
{
// get union type from the prev field
auto
utype
=
type_vec
->
Get
(
j
);
auto
elem
=
vec
->
Get
(
j
);
if
(
!
VerifyUnion
(
v
,
schema
,
utype
,
elem
,
vec_field
))
return
false
;
}
}
return
true
;
return
true
;
}
}
case
reflection
:
:
Union
:
FLATBUFFERS_ASSERT
(
false
);
break
;
case
reflection
:
:
Vector
:
default:
FLATBUFFERS_ASSERT
(
false
);
break
;
case
reflection
:
:
None
:
default:
FLATBUFFERS_ASSERT
(
false
);
return
false
;
}
}
return
false
;
}
}
bool
VerifyObject
(
flatbuffers
::
Verifier
&
v
,
const
reflection
::
Schema
&
schema
,
bool
VerifyObject
(
flatbuffers
::
Verifier
&
v
,
const
reflection
::
Schema
&
schema
,
const
reflection
::
Object
&
obj
,
const
reflection
::
Object
&
obj
,
const
flatbuffers
::
Table
*
table
,
bool
required
)
{
const
flatbuffers
::
Table
*
table
,
bool
required
)
{
if
(
!
table
)
{
if
(
!
table
)
return
!
required
;
if
(
!
required
)
return
true
;
else
return
false
;
}
if
(
!
table
->
VerifyTableStart
(
v
))
return
false
;
if
(
!
table
->
VerifyTableStart
(
v
))
return
false
;
for
(
uoffset_t
i
=
0
;
i
<
obj
.
fields
()
->
size
();
i
++
)
{
for
(
uoffset_t
i
=
0
;
i
<
obj
.
fields
()
->
size
();
i
++
)
{
auto
field_def
=
obj
.
fields
()
->
Get
(
i
);
auto
field_def
=
obj
.
fields
()
->
Get
(
i
);
switch
(
field_def
->
type
()
->
base_type
())
{
switch
(
field_def
->
type
()
->
base_type
())
{
...
@@ -631,7 +663,8 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
...
@@ -631,7 +663,8 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
}
}
break
;
break
;
case
reflection
:
:
Vector
:
case
reflection
:
:
Vector
:
if
(
!
VerifyVector
(
v
,
schema
,
*
table
,
*
field_def
))
return
false
;
if
(
!
VerifyVector
(
v
,
schema
,
*
table
,
*
field_def
))
return
false
;
break
;
break
;
case
reflection
:
:
Obj
:
{
case
reflection
:
:
Obj
:
{
auto
child_obj
=
schema
.
objects
()
->
Get
(
field_def
->
type
()
->
index
());
auto
child_obj
=
schema
.
objects
()
->
Get
(
field_def
->
type
()
->
index
());
...
@@ -653,20 +686,16 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
...
@@ -653,20 +686,16 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
// get union type from the prev field
// get union type from the prev field
voffset_t
utype_offset
=
field_def
->
offset
()
-
sizeof
(
voffset_t
);
voffset_t
utype_offset
=
field_def
->
offset
()
-
sizeof
(
voffset_t
);
auto
utype
=
table
->
GetField
<
uint8_t
>
(
utype_offset
,
0
);
auto
utype
=
table
->
GetField
<
uint8_t
>
(
utype_offset
,
0
);
if
(
utype
!=
0
)
{
auto
uval
=
reinterpret_cast
<
const
uint8_t
*>
(
// Means we have this union field present
flatbuffers
::
GetFieldT
(
*
table
,
*
field_def
));
auto
fb_enum
=
schema
.
enums
()
->
Get
(
field_def
->
type
()
->
index
());
if
(
!
VerifyUnion
(
v
,
schema
,
utype
,
uval
,
*
field_def
))
{
if
(
utype
>=
fb_enum
->
values
()
->
size
())
return
false
;
return
false
;
auto
child_obj
=
fb_enum
->
values
()
->
Get
(
utype
)
->
object
();
if
(
!
VerifyObject
(
v
,
schema
,
*
child_obj
,
flatbuffers
::
GetFieldT
(
*
table
,
*
field_def
),
field_def
->
required
()))
{
return
false
;
}
}
}
break
;
break
;
}
}
default:
FLATBUFFERS_ASSERT
(
false
);
break
;
default:
FLATBUFFERS_ASSERT
(
false
);
break
;
}
}
}
}
...
...
tests/test.cpp
View file @
917687c7
...
@@ -2348,12 +2348,11 @@ void UnionVectorTest() {
...
@@ -2348,12 +2348,11 @@ void UnionVectorTest() {
fbb
.
CreateStruct
(
Rapunzel
(
/*hair_length=*/
6
)).
Union
(),
fbb
.
CreateStruct
(
Rapunzel
(
/*hair_length=*/
6
)).
Union
(),
fbb
.
CreateVector
(
types
),
fbb
.
CreateVector
(
characters
));
fbb
.
CreateVector
(
types
),
fbb
.
CreateVector
(
characters
));
FinishMovieBuffer
(
fbb
,
movie_offset
);
FinishMovieBuffer
(
fbb
,
movie_offset
);
auto
buf
=
fbb
.
GetBufferPointer
();
flatbuffers
::
Verifier
verifier
(
buf
,
fbb
.
GetSize
());
flatbuffers
::
Verifier
verifier
(
fbb
.
GetBufferPointer
()
,
fbb
.
GetSize
());
TEST_EQ
(
VerifyMovieBuffer
(
verifier
),
true
);
TEST_EQ
(
VerifyMovieBuffer
(
verifier
),
true
);
auto
flat_movie
=
GetMovie
(
buf
);
auto
flat_movie
=
GetMovie
(
fbb
.
GetBufferPointer
()
);
auto
TestMovie
=
[](
const
Movie
*
movie
)
{
auto
TestMovie
=
[](
const
Movie
*
movie
)
{
TEST_EQ
(
movie
->
main_character_type
()
==
Character_Rapunzel
,
true
);
TEST_EQ
(
movie
->
main_character_type
()
==
Character_Rapunzel
,
true
);
...
@@ -2485,6 +2484,13 @@ void UnionVectorTest() {
...
@@ -2485,6 +2484,13 @@ void UnionVectorTest() {
" ]
\n
"
" ]
\n
"
"}
\n
"
);
"}
\n
"
);
// Simple test with reflection.
parser
.
Serialize
();
auto
schema
=
reflection
::
GetSchema
(
parser
.
builder_
.
GetBufferPointer
());
auto
ok
=
flatbuffers
::
Verify
(
*
schema
,
*
schema
->
root_table
(),
fbb
.
GetBufferPointer
(),
fbb
.
GetSize
());
TEST_EQ
(
ok
,
true
);
flatbuffers
::
Parser
parser2
(
idl_opts
);
flatbuffers
::
Parser
parser2
(
idl_opts
);
TEST_EQ
(
parser2
.
Parse
(
"struct Bool { b:bool; }"
TEST_EQ
(
parser2
.
Parse
(
"struct Bool { b:bool; }"
"union Any { Bool }"
"union Any { Bool }"
...
...
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