Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
L
libplist
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
pwn
libplist
Commits
08c6143b
Commit
08c6143b
authored
May 18, 2019
by
Nikias Bassen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add index lookup table for large PLIST_ARRAY nodes
parent
7e9ecf2f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
113 additions
and
22 deletions
+113
-22
plist.c
src/plist.c
+69
-11
ptrarray.c
src/ptrarray.c
+36
-6
ptrarray.h
src/ptrarray.h
+8
-5
No files found.
src/plist.c
View file @
08c6143b
...
@@ -28,6 +28,7 @@
...
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <stdio.h>
#include <math.h>
#include <math.h>
#include <assert.h>
#include <assert.h>
#include <limits.h>
#ifdef WIN32
#ifdef WIN32
#include <windows.h>
#include <windows.h>
...
@@ -37,6 +38,7 @@
...
@@ -37,6 +38,7 @@
#include <node.h>
#include <node.h>
#include <hashtable.h>
#include <hashtable.h>
#include <ptrarray.h>
extern
void
plist_xml_init
(
void
);
extern
void
plist_xml_init
(
void
);
extern
void
plist_xml_deinit
(
void
);
extern
void
plist_xml_deinit
(
void
);
...
@@ -190,6 +192,9 @@ void plist_free_data(plist_data_t data)
...
@@ -190,6 +192,9 @@ void plist_free_data(plist_data_t data)
case
PLIST_DATA
:
case
PLIST_DATA
:
free
(
data
->
buff
);
free
(
data
->
buff
);
break
;
break
;
case
PLIST_ARRAY
:
ptr_array_free
(
data
->
hashtable
);
break
;
case
PLIST_DICT
:
case
PLIST_DICT
:
hash_table_destroy
(
data
->
hashtable
);
hash_table_destroy
(
data
->
hashtable
);
break
;
break
;
...
@@ -338,6 +343,20 @@ static void plist_copy_node(node_t *node, void *parent_node_ptr)
...
@@ -338,6 +343,20 @@ static void plist_copy_node(node_t *node, void *parent_node_ptr)
case
PLIST_STRING
:
case
PLIST_STRING
:
newdata
->
strval
=
strdup
((
char
*
)
data
->
strval
);
newdata
->
strval
=
strdup
((
char
*
)
data
->
strval
);
break
;
break
;
case
PLIST_ARRAY
:
if
(
data
->
hashtable
)
{
ptrarray_t
*
pa
=
ptr_array_new
(((
ptrarray_t
*
)
data
->
hashtable
)
->
capacity
);
assert
(
pa
);
plist_t
current
=
NULL
;
for
(
current
=
(
plist_t
)
node_first_child
(
node
);
pa
&&
current
;
current
=
(
plist_t
)
node_next_sibling
(
current
))
{
ptr_array_add
(
pa
,
current
);
}
newdata
->
hashtable
=
pa
;
}
break
;
case
PLIST_DICT
:
case
PLIST_DICT
:
if
(
data
->
hashtable
)
{
if
(
data
->
hashtable
)
{
hashtable_t
*
ht
=
hash_table_new
(
dict_key_hash
,
dict_key_compare
,
NULL
);
hashtable_t
*
ht
=
hash_table_new
(
dict_key_hash
,
dict_key_compare
,
NULL
);
...
@@ -392,9 +411,14 @@ PLIST_API uint32_t plist_array_get_size(plist_t node)
...
@@ -392,9 +411,14 @@ PLIST_API uint32_t plist_array_get_size(plist_t node)
PLIST_API
plist_t
plist_array_get_item
(
plist_t
node
,
uint32_t
n
)
PLIST_API
plist_t
plist_array_get_item
(
plist_t
node
,
uint32_t
n
)
{
{
plist_t
ret
=
NULL
;
plist_t
ret
=
NULL
;
if
(
node
&&
PLIST_ARRAY
==
plist_get_node_type
(
node
))
if
(
node
&&
PLIST_ARRAY
==
plist_get_node_type
(
node
)
&&
n
<
INT_MAX
)
{
{
ret
=
(
plist_t
)
node_nth_child
(
node
,
n
);
ptrarray_t
*
pa
=
((
plist_data_t
)((
node_t
*
)
node
)
->
data
)
->
hashtable
;
if
(
pa
)
{
ret
=
(
plist_t
)
ptr_array_index
(
pa
,
n
);
}
else
{
ret
=
(
plist_t
)
node_nth_child
(
node
,
n
);
}
}
}
return
ret
;
return
ret
;
}
}
...
@@ -409,19 +433,46 @@ PLIST_API uint32_t plist_array_get_item_index(plist_t node)
...
@@ -409,19 +433,46 @@ PLIST_API uint32_t plist_array_get_item_index(plist_t node)
return
0
;
return
0
;
}
}
static
void
_plist_array_post_insert
(
plist_t
node
,
plist_t
item
,
long
n
)
{
ptrarray_t
*
pa
=
((
plist_data_t
)((
node_t
*
)
node
)
->
data
)
->
hashtable
;
if
(
pa
)
{
/* store pointer to item in array */
ptr_array_insert
(
pa
,
item
,
n
);
}
else
{
if
(((
node_t
*
)
node
)
->
count
>
100
)
{
/* make new lookup array */
pa
=
ptr_array_new
(
128
);
plist_t
current
=
NULL
;
for
(
current
=
(
plist_t
)
node_first_child
(
node
);
pa
&&
current
;
current
=
(
plist_t
)
node_next_sibling
(
current
))
{
ptr_array_add
(
pa
,
current
);
}
((
plist_data_t
)((
node_t
*
)
node
)
->
data
)
->
hashtable
=
pa
;
}
}
}
PLIST_API
void
plist_array_set_item
(
plist_t
node
,
plist_t
item
,
uint32_t
n
)
PLIST_API
void
plist_array_set_item
(
plist_t
node
,
plist_t
item
,
uint32_t
n
)
{
{
if
(
node
&&
PLIST_ARRAY
==
plist_get_node_type
(
node
))
if
(
node
&&
PLIST_ARRAY
==
plist_get_node_type
(
node
)
&&
n
<
INT_MAX
)
{
{
plist_t
old_item
=
plist_array_get_item
(
node
,
n
);
plist_t
old_item
=
plist_array_get_item
(
node
,
n
);
if
(
old_item
)
if
(
old_item
)
{
{
int
idx
=
plist_free_node
(
old_item
);
int
idx
=
plist_free_node
(
old_item
);
if
(
idx
<
0
)
{
assert
(
idx
>=
0
);
node_attach
(
node
,
item
);
if
(
idx
<
0
)
{
}
else
{
return
;
node_insert
(
node
,
idx
,
item
);
}
else
{
}
node_insert
(
node
,
idx
,
item
);
ptrarray_t
*
pa
=
((
plist_data_t
)((
node_t
*
)
node
)
->
data
)
->
hashtable
;
if
(
pa
)
{
ptr_array_set
(
pa
,
item
,
idx
);
}
}
}
}
}
}
return
;
return
;
...
@@ -432,26 +483,32 @@ PLIST_API void plist_array_append_item(plist_t node, plist_t item)
...
@@ -432,26 +483,32 @@ PLIST_API void plist_array_append_item(plist_t node, plist_t item)
if
(
node
&&
PLIST_ARRAY
==
plist_get_node_type
(
node
))
if
(
node
&&
PLIST_ARRAY
==
plist_get_node_type
(
node
))
{
{
node_attach
(
node
,
item
);
node_attach
(
node
,
item
);
_plist_array_post_insert
(
node
,
item
,
-
1
);
}
}
return
;
return
;
}
}
PLIST_API
void
plist_array_insert_item
(
plist_t
node
,
plist_t
item
,
uint32_t
n
)
PLIST_API
void
plist_array_insert_item
(
plist_t
node
,
plist_t
item
,
uint32_t
n
)
{
{
if
(
node
&&
PLIST_ARRAY
==
plist_get_node_type
(
node
))
if
(
node
&&
PLIST_ARRAY
==
plist_get_node_type
(
node
)
&&
n
<
INT_MAX
)
{
{
node_insert
(
node
,
n
,
item
);
node_insert
(
node
,
n
,
item
);
_plist_array_post_insert
(
node
,
item
,
(
long
)
n
);
}
}
return
;
return
;
}
}
PLIST_API
void
plist_array_remove_item
(
plist_t
node
,
uint32_t
n
)
PLIST_API
void
plist_array_remove_item
(
plist_t
node
,
uint32_t
n
)
{
{
if
(
node
&&
PLIST_ARRAY
==
plist_get_node_type
(
node
))
if
(
node
&&
PLIST_ARRAY
==
plist_get_node_type
(
node
)
&&
n
<
INT_MAX
)
{
{
plist_t
old_item
=
plist_array_get_item
(
node
,
n
);
plist_t
old_item
=
plist_array_get_item
(
node
,
n
);
if
(
old_item
)
if
(
old_item
)
{
{
ptrarray_t
*
pa
=
((
plist_data_t
)((
node_t
*
)
node
)
->
data
)
->
hashtable
;
if
(
pa
)
{
ptr_array_remove
(
pa
,
n
);
}
plist_free
(
old_item
);
plist_free
(
old_item
);
}
}
}
}
...
@@ -586,8 +643,9 @@ PLIST_API void plist_dict_set_item(plist_t node, const char* key, plist_t item)
...
@@ -586,8 +643,9 @@ PLIST_API void plist_dict_set_item(plist_t node, const char* key, plist_t item)
plist_t
key_node
=
NULL
;
plist_t
key_node
=
NULL
;
if
(
old_item
)
{
if
(
old_item
)
{
int
idx
=
plist_free_node
(
old_item
);
int
idx
=
plist_free_node
(
old_item
);
assert
(
idx
>=
0
);
if
(
idx
<
0
)
{
if
(
idx
<
0
)
{
node_attach
(
node
,
item
)
;
return
;
}
else
{
}
else
{
node_insert
(
node
,
idx
,
item
);
node_insert
(
node
,
idx
,
item
);
}
}
...
...
src/ptrarray.c
View file @
08c6143b
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* ptrarray.c
* ptrarray.c
* simple pointer array implementation
* simple pointer array implementation
*
*
* Copyright (c) 2011 Nikias Bassen, All Rights Reserved.
* Copyright (c) 2011
-2019
Nikias Bassen, All Rights Reserved.
*
*
* This library is free software; you can redistribute it and/or
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* modify it under the terms of the GNU Lesser General Public
...
@@ -19,6 +19,7 @@
...
@@ -19,6 +19,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
*/
#include "ptrarray.h"
#include "ptrarray.h"
#include <string.h>
ptrarray_t
*
ptr_array_new
(
int
capacity
)
ptrarray_t
*
ptr_array_new
(
int
capacity
)
{
{
...
@@ -39,22 +40,51 @@ void ptr_array_free(ptrarray_t *pa)
...
@@ -39,22 +40,51 @@ void ptr_array_free(ptrarray_t *pa)
free
(
pa
);
free
(
pa
);
}
}
void
ptr_array_
add
(
ptrarray_t
*
pa
,
void
*
data
)
void
ptr_array_
insert
(
ptrarray_t
*
pa
,
void
*
data
,
long
array_index
)
{
{
if
(
!
pa
||
!
pa
->
pdata
||
!
data
)
return
;
if
(
!
pa
||
!
pa
->
pdata
||
!
data
)
return
;
size_t
remaining
=
pa
->
capacity
-
pa
->
len
;
long
remaining
=
pa
->
capacity
-
pa
->
len
;
if
(
remaining
==
0
)
{
if
(
remaining
==
0
)
{
pa
->
pdata
=
realloc
(
pa
->
pdata
,
sizeof
(
void
*
)
*
(
pa
->
capacity
+
pa
->
capacity_step
));
pa
->
pdata
=
realloc
(
pa
->
pdata
,
sizeof
(
void
*
)
*
(
pa
->
capacity
+
pa
->
capacity_step
));
pa
->
capacity
+=
pa
->
capacity_step
;
pa
->
capacity
+=
pa
->
capacity_step
;
}
}
pa
->
pdata
[
pa
->
len
]
=
data
;
if
(
array_index
<
0
||
array_index
>=
pa
->
len
)
{
pa
->
pdata
[
pa
->
len
]
=
data
;
}
else
{
memmove
(
&
pa
->
pdata
[
array_index
+
1
],
&
pa
->
pdata
[
array_index
],
(
pa
->
len
-
array_index
)
*
sizeof
(
void
*
));
pa
->
pdata
[
array_index
]
=
data
;
}
pa
->
len
++
;
pa
->
len
++
;
}
}
void
*
ptr_array_index
(
ptrarray_t
*
pa
,
size_t
array_index
)
void
ptr_array_add
(
ptrarray_t
*
pa
,
void
*
data
)
{
ptr_array_insert
(
pa
,
data
,
-
1
);
}
void
ptr_array_remove
(
ptrarray_t
*
pa
,
long
array_index
)
{
if
(
!
pa
||
!
pa
->
pdata
||
array_index
<
0
)
return
;
if
(
pa
->
len
==
0
||
array_index
>=
pa
->
len
)
return
;
if
(
pa
->
len
==
1
)
{
pa
->
pdata
[
0
]
=
NULL
;
}
else
{
memmove
(
&
pa
->
pdata
[
array_index
],
&
pa
->
pdata
[
array_index
+
1
],
(
pa
->
len
-
array_index
-
1
)
*
sizeof
(
void
*
));
}
pa
->
len
--
;
}
void
ptr_array_set
(
ptrarray_t
*
pa
,
void
*
data
,
long
array_index
)
{
if
(
!
pa
||
!
pa
->
pdata
||
array_index
<
0
)
return
;
if
(
pa
->
len
==
0
||
array_index
>=
pa
->
len
)
return
;
pa
->
pdata
[
array_index
]
=
data
;
}
void
*
ptr_array_index
(
ptrarray_t
*
pa
,
long
array_index
)
{
{
if
(
!
pa
)
return
NULL
;
if
(
!
pa
)
return
NULL
;
if
(
array_index
>=
pa
->
len
)
{
if
(
array_index
<
0
||
array_index
>=
pa
->
len
)
{
return
NULL
;
return
NULL
;
}
}
return
pa
->
pdata
[
array_index
];
return
pa
->
pdata
[
array_index
];
...
...
src/ptrarray.h
View file @
08c6143b
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* ptrarray.h
* ptrarray.h
* header file for simple pointer array implementation
* header file for simple pointer array implementation
*
*
* Copyright (c) 2011 Nikias Bassen, All Rights Reserved.
* Copyright (c) 2011
-2019
Nikias Bassen, All Rights Reserved.
*
*
* This library is free software; you can redistribute it and/or
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* modify it under the terms of the GNU Lesser General Public
...
@@ -24,13 +24,16 @@
...
@@ -24,13 +24,16 @@
typedef
struct
ptrarray_t
{
typedef
struct
ptrarray_t
{
void
**
pdata
;
void
**
pdata
;
size_t
len
;
long
len
;
size_t
capacity
;
long
capacity
;
size_t
capacity_step
;
long
capacity_step
;
}
ptrarray_t
;
}
ptrarray_t
;
ptrarray_t
*
ptr_array_new
(
int
capacity
);
ptrarray_t
*
ptr_array_new
(
int
capacity
);
void
ptr_array_free
(
ptrarray_t
*
pa
);
void
ptr_array_free
(
ptrarray_t
*
pa
);
void
ptr_array_add
(
ptrarray_t
*
pa
,
void
*
data
);
void
ptr_array_add
(
ptrarray_t
*
pa
,
void
*
data
);
void
*
ptr_array_index
(
ptrarray_t
*
pa
,
size_t
index
);
void
ptr_array_insert
(
ptrarray_t
*
pa
,
void
*
data
,
long
index
);
void
ptr_array_remove
(
ptrarray_t
*
pa
,
long
index
);
void
ptr_array_set
(
ptrarray_t
*
pa
,
void
*
data
,
long
index
);
void
*
ptr_array_index
(
ptrarray_t
*
pa
,
long
index
);
#endif
#endif
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