Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
f59807c5
Commit
f59807c5
authored
Jun 23, 2023
by
Fabian Maurer
Committed by
Alexandre Julliard
Nov 29, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
widl: Prevent infinite loop when structure contains array of itself.
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=55115
parent
e83ca9b7
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
70 additions
and
7 deletions
+70
-7
typegen.c
tools/widl/typegen.c
+70
-7
No files found.
tools/widl/typegen.c
View file @
f59807c5
...
@@ -745,8 +745,41 @@ static int type_has_pointers(const type_t *type)
...
@@ -745,8 +745,41 @@ static int type_has_pointers(const type_t *type)
return
FALSE
;
return
FALSE
;
}
}
static
int
type_has_full_pointer
(
const
type_t
*
type
,
const
attr_list_t
*
attrs
,
struct
visited_struct_array
int
toplevel_param
)
{
const
type_t
**
structs
;
size_t
count
;
size_t
capacity
;
};
static
inline
int
array_reserve
(
void
**
elements
,
size_t
*
capacity
,
size_t
count
,
size_t
size
)
{
size_t
new_capacity
,
max_capacity
;
void
*
new_elements
;
if
(
count
<=
*
capacity
)
return
TRUE
;
max_capacity
=
~
(
size_t
)
0
/
size
;
if
(
count
>
max_capacity
)
return
FALSE
;
new_capacity
=
max
(
4
,
*
capacity
);
while
(
new_capacity
<
count
&&
new_capacity
<=
max_capacity
/
2
)
new_capacity
*=
2
;
if
(
new_capacity
<
count
)
new_capacity
=
max_capacity
;
if
(
!
(
new_elements
=
realloc
(
*
elements
,
new_capacity
*
size
)))
return
FALSE
;
*
elements
=
new_elements
;
*
capacity
=
new_capacity
;
return
TRUE
;
}
static
int
type_has_full_pointer_recurse
(
const
type_t
*
type
,
const
attr_list_t
*
attrs
,
int
toplevel_param
,
struct
visited_struct_array
*
visited_structs
)
{
{
switch
(
typegen_detect_type
(
type
,
NULL
,
TDT_IGNORE_STRINGS
))
switch
(
typegen_detect_type
(
type
,
NULL
,
TDT_IGNORE_STRINGS
))
{
{
...
@@ -761,18 +794,39 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
...
@@ -761,18 +794,39 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
if
(
get_pointer_fc
(
type
,
attrs
,
toplevel_param
)
==
FC_FP
)
if
(
get_pointer_fc
(
type
,
attrs
,
toplevel_param
)
==
FC_FP
)
return
TRUE
;
return
TRUE
;
else
else
return
type_has_full_pointer
(
type_array_get_element_type
(
type
),
NULL
,
FALSE
);
return
type_has_full_pointer
_recurse
(
type_array_get_element_type
(
type
),
NULL
,
FALSE
,
visited_structs
);
case
TGT_STRUCT
:
case
TGT_STRUCT
:
{
{
unsigned
int
i
;
int
ret
=
FALSE
;
var_list_t
*
fields
=
type_struct_get_fields
(
type
);
var_list_t
*
fields
=
type_struct_get_fields
(
type
);
const
var_t
*
field
;
const
var_t
*
field
;
if
(
fields
)
LIST_FOR_EACH_ENTRY
(
field
,
fields
,
const
var_t
,
entry
)
for
(
i
=
0
;
i
<
visited_structs
->
count
;
i
++
)
{
{
if
(
type_has_full_pointer
(
field
->
declspec
.
type
,
field
->
attrs
,
FALSE
))
if
(
visited_structs
->
structs
[
i
]
==
type
)
return
TRUE
;
{
/* Found struct we visited already, abort to prevent infinite loop.
* Can't be at the first struct we visit, so we can skip cleanup and just return */
return
FALSE
;
}
}
}
array_reserve
((
void
**
)
&
visited_structs
->
structs
,
&
visited_structs
->
capacity
,
visited_structs
->
count
+
1
,
sizeof
(
struct
type_t
*
));
visited_structs
->
structs
[
visited_structs
->
count
]
=
type
;
visited_structs
->
count
++
;
if
(
fields
)
LIST_FOR_EACH_ENTRY
(
field
,
fields
,
const
var_t
,
entry
)
{
if
(
type_has_full_pointer_recurse
(
field
->
declspec
.
type
,
field
->
attrs
,
FALSE
,
visited_structs
))
{
ret
=
TRUE
;
break
;
break
;
}
}
}
visited_structs
->
count
--
;
return
ret
;
}
case
TGT_UNION
:
case
TGT_UNION
:
{
{
var_list_t
*
fields
;
var_list_t
*
fields
;
...
@@ -780,7 +834,7 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
...
@@ -780,7 +834,7 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
fields
=
type_union_get_cases
(
type
);
fields
=
type_union_get_cases
(
type
);
if
(
fields
)
LIST_FOR_EACH_ENTRY
(
field
,
fields
,
const
var_t
,
entry
)
if
(
fields
)
LIST_FOR_EACH_ENTRY
(
field
,
fields
,
const
var_t
,
entry
)
{
{
if
(
field
->
declspec
.
type
&&
type_has_full_pointer
(
field
->
declspec
.
type
,
field
->
attrs
,
FALSE
))
if
(
field
->
declspec
.
type
&&
type_has_full_pointer
_recurse
(
field
->
declspec
.
type
,
field
->
attrs
,
FALSE
,
visited_structs
))
return
TRUE
;
return
TRUE
;
}
}
break
;
break
;
...
@@ -799,6 +853,15 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
...
@@ -799,6 +853,15 @@ static int type_has_full_pointer(const type_t *type, const attr_list_t *attrs,
return
FALSE
;
return
FALSE
;
}
}
static
int
type_has_full_pointer
(
const
type_t
*
type
,
const
attr_list_t
*
attrs
,
int
toplevel_param
)
{
int
ret
;
struct
visited_struct_array
visited_structs
=
{
0
};
ret
=
type_has_full_pointer_recurse
(
type
,
attrs
,
toplevel_param
,
&
visited_structs
);
free
(
visited_structs
.
structs
);
return
ret
;
}
static
unsigned
short
user_type_offset
(
const
char
*
name
)
static
unsigned
short
user_type_offset
(
const
char
*
name
)
{
{
user_type_t
*
ut
;
user_type_t
*
ut
;
...
...
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