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
c8a140dc
Commit
c8a140dc
authored
Jul 08, 2009
by
Jonathan Beck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a deep copy function and value setters for nodes.
parent
e925e6f6
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
211 additions
and
21 deletions
+211
-21
plist.h
include/plist/plist.h
+80
-0
bplist.c
src/bplist.c
+11
-12
plist.c
src/plist.c
+116
-3
xplist.c
src/xplist.c
+4
-6
No files found.
include/plist/plist.h
View file @
c8a140dc
...
...
@@ -109,6 +109,15 @@ extern "C" {
*/
PLIST_API
void
plist_free
(
plist_t
plist
);
/**
* Return a copy of passed node and it's children
*
* @param plist the plist to copy
* @return copied plist
*/
PLIST_API
plist_t
plist_copy
(
plist_t
node
);
/********************************************
* *
* Tree navigation *
...
...
@@ -321,6 +330,77 @@ extern "C" {
PLIST_API
void
plist_get_date_val
(
plist_t
node
,
int32_t
*
sec
,
int32_t
*
usec
);
/********************************************
* *
* Setters *
* *
********************************************/
/**
* Set the value of a node.
* Forces type of node to #PLIST_KEY
*
* @param node the node
* @param val the key value
*/
PLIST_API
void
plist_set_key_val
(
plist_t
node
,
const
char
*
val
);
/**
* Set the value of a node.
* Forces type of node to #PLIST_STRING
*
* @param node the node
* @param val the string value
*/
PLIST_API
void
plist_set_string_val
(
plist_t
node
,
const
char
*
val
);
/**
* Set the value of a node.
* Forces type of node to #PLIST_BOOLEAN
*
* @param node the node
* @param val the boolean value
*/
PLIST_API
void
plist_set_bool_val
(
plist_t
node
,
uint8_t
val
);
/**
* Set the value of a node.
* Forces type of node to #PLIST_UINT
*
* @param node the node
* @param val the unsigned integer value
*/
PLIST_API
void
plist_set_uint_val
(
plist_t
node
,
uint64_t
val
);
/**
* Set the value of a node.
* Forces type of node to #PLIST_REAL
*
* @param node the node
* @param val the real value
*/
PLIST_API
void
plist_set_real_val
(
plist_t
node
,
double
val
);
/**
* Set the value of a node.
* Forces type of node to #PLIST_DATA
*
* @param node the node
* @param val the binary buffer
* @param length the length of the buffer
*/
PLIST_API
void
plist_set_data_val
(
plist_t
node
,
const
char
*
val
,
uint64_t
length
);
/**
* Set the value of a node.
* Forces type of node to #PLIST_DATE
*
* @param node the node
* @param sec the number of seconds since 01/01/2001
* @param usec the number of microseconds
*/
PLIST_API
void
plist_set_date_val
(
plist_t
node
,
int32_t
sec
,
int32_t
usec
);
/********************************************
* *
...
...
src/bplist.c
View file @
c8a140dc
...
...
@@ -80,7 +80,7 @@ static void byte_convert(uint8_t * address, size_t size)
static
uint32_t
uint24_from_be
(
char
*
buff
)
{
uint32_t
ret
=
0
;
char
*
tmp
=
(
char
*
)
&
ret
;
char
*
tmp
=
(
char
*
)
&
ret
;
memcpy
(
tmp
+
1
,
buff
,
3
*
sizeof
(
char
));
byte_convert
(
tmp
,
sizeof
(
uint32_t
));
return
ret
;
...
...
@@ -137,13 +137,13 @@ static plist_t parse_real_node(char *bnode, uint8_t size)
size
=
1
<<
size
;
// make length less misleading
switch
(
size
)
{
case
sizeof
(
float
):
floatval
=
*
(
float
*
)
bnode
;
byte_convert
((
uint8_t
*
)
&
floatval
,
sizeof
(
float
));
floatval
=
*
(
float
*
)
bnode
;
byte_convert
((
uint8_t
*
)
&
floatval
,
sizeof
(
float
));
data
->
realval
=
floatval
;
break
;
case
sizeof
(
double
):
data
->
realval
=
*
(
double
*
)
bnode
;
byte_convert
((
uint8_t
*
)
&
(
data
->
realval
),
sizeof
(
double
));
data
->
realval
=
*
(
double
*
)
bnode
;
byte_convert
((
uint8_t
*
)
&
(
data
->
realval
),
sizeof
(
double
));
break
;
default:
free
(
data
);
...
...
@@ -197,7 +197,7 @@ static plist_t parse_unicode_node(char *bnode, uint64_t size)
unicodestr
=
(
gunichar2
*
)
malloc
(
sizeof
(
gunichar2
)
*
size
);
memcpy
(
unicodestr
,
bnode
,
sizeof
(
gunichar2
)
*
size
);
for
(
i
=
0
;
i
<
size
;
i
++
)
byte_convert
((
uint8_t
*
)
(
unicodestr
+
i
),
sizeof
(
gunichar2
));
byte_convert
((
uint8_t
*
)
(
unicodestr
+
i
),
sizeof
(
gunichar2
));
tmpstr
=
g_utf16_to_utf8
(
unicodestr
,
size
,
&
items_read
,
&
items_written
,
&
error
);
free
(
unicodestr
);
...
...
@@ -426,7 +426,7 @@ void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist)
return
;
//now parse trailer
trailer
=
(
char
*
)
(
plist_bin
+
(
length
-
BPLIST_TRL_SIZE
));
trailer
=
(
char
*
)
(
plist_bin
+
(
length
-
BPLIST_TRL_SIZE
));
offset_size
=
trailer
[
BPLIST_TRL_OFFSIZE_IDX
];
dict_param_size
=
trailer
[
BPLIST_TRL_PARMSIZE_IDX
];
...
...
@@ -444,12 +444,12 @@ void plist_from_bin(const char *plist_bin, uint32_t length, plist_t * plist)
return
;
//parse serialized nodes
offset_table
=
(
char
*
)
(
plist_bin
+
offset_table_index
);
offset_table
=
(
char
*
)
(
plist_bin
+
offset_table_index
);
for
(
i
=
0
;
i
<
num_objects
;
i
++
)
{
char
*
obj
=
NULL
;
current_offset
=
UINT_TO_HOST
(
offset_table
+
i
*
offset_size
,
offset_size
);
obj
=
(
char
*
)
(
plist_bin
+
current_offset
);
obj
=
(
char
*
)
(
plist_bin
+
current_offset
);
nodeslist
[
i
]
=
parse_bin_node
(
obj
,
dict_param_size
,
&
obj
);
}
...
...
@@ -734,7 +734,7 @@ static void write_dict(GByteArray * bplist, GNode * node, GHashTable * ref_table
memcpy
(
buff
+
i
*
dict_param_size
,
&
idx1
,
dict_param_size
);
byte_convert
(
buff
+
i
*
dict_param_size
,
dict_param_size
);
idx2
=
*
(
uint64_t
*
)(
g_hash_table_lookup
(
ref_table
,
cur
->
next
));
idx2
=
*
(
uint64_t
*
)
(
g_hash_table_lookup
(
ref_table
,
cur
->
next
));
memcpy
(
buff
+
(
i
+
size
)
*
dict_param_size
,
&
idx2
,
dict_param_size
);
byte_convert
(
buff
+
(
i
+
size
)
*
dict_param_size
,
dict_param_size
);
}
...
...
@@ -828,8 +828,7 @@ void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)
unicodestr
=
g_utf8_to_utf16
(
data
->
strval
,
len
,
&
items_read
,
&
items_written
,
&
error
);
write_unicode
(
bplist_buff
,
unicodestr
,
items_written
);
g_free
(
unicodestr
);
}
else
if
(
XML_CHAR_ENCODING_ASCII
==
type
||
XML_CHAR_ENCODING_NONE
==
type
)
{
}
else
if
(
XML_CHAR_ENCODING_ASCII
==
type
||
XML_CHAR_ENCODING_NONE
==
type
)
{
write_string
(
bplist_buff
,
data
->
strval
);
}
break
;
...
...
src/plist.c
View file @
c8a140dc
...
...
@@ -109,7 +109,7 @@ static plist_t plist_add_sub_element(plist_t node, plist_type type, const void *
data
->
strval
=
strdup
((
char
*
)
value
);
break
;
case
PLIST_DATA
:
data
->
buff
=
(
uint8_t
*
)
malloc
(
length
);
data
->
buff
=
(
uint8_t
*
)
malloc
(
length
);
memcpy
(
data
->
buff
,
value
,
length
);
break
;
case
PLIST_DATE
:
...
...
@@ -138,6 +138,28 @@ void plist_free(plist_t plist)
g_node_destroy
(
plist
);
}
static
void
plist_copy_node
(
GNode
*
node
,
gpointer
parent_node
)
{
plist_t
newnode
=
NULL
;
plist_data_t
data
=
plist_get_data
(
node
);
plist_data_t
newdata
=
plist_new_plist_data
();
assert
(
data
);
// plist should always have data
memcpy
(
newdata
,
data
,
sizeof
(
struct
plist_data_s
));
newnode
=
plist_new_node
(
newdata
);
if
(
parent_node
)
{
g_node_append
(
parent_node
,
newnode
);
}
g_node_children_foreach
(
node
,
G_TRAVERSE_ALL
,
plist_copy_node
,
newnode
);
}
plist_t
plist_copy
(
plist_t
node
)
{
plist_copy_node
(
node
,
NULL
);
}
plist_t
plist_get_first_child
(
plist_t
node
)
{
return
(
plist_t
)
g_node_first_child
((
GNode
*
)
node
);
...
...
@@ -160,7 +182,7 @@ plist_t plist_get_array_nth_el(plist_t node, uint32_t n)
uint32_t
i
=
0
;
plist_t
temp
=
plist_get_first_child
(
node
);
while
(
i
<=
n
&&
temp
)
{
while
(
i
<=
n
&&
temp
)
{
if
(
i
==
n
)
ret
=
temp
;
temp
=
plist_get_next_sibling
(
temp
);
...
...
@@ -465,5 +487,96 @@ gboolean plist_data_compare(gconstpointer a, gconstpointer b)
char
plist_compare_node_value
(
plist_t
node_l
,
plist_t
node_r
)
{
return
plist_data_compare
(
node_l
,
node_r
);
return
plist_data_compare
(
node_l
,
node_r
);
}
static
plist_t
plist_set_element_val
(
plist_t
node
,
plist_type
type
,
const
void
*
value
,
uint64_t
length
)
{
//free previous allocated buffer
plist_data_t
data
=
plist_get_data
(
node
);
assert
(
data
);
// a node should always have data attached
switch
(
data
->
type
)
{
case
PLIST_KEY
:
case
PLIST_STRING
:
free
(
data
->
strval
);
data
->
strval
=
NULL
;
break
;
case
PLIST_DATA
:
free
(
data
->
buff
);
data
->
buff
=
NULL
;
break
;
default:
break
;
}
//now handle value
data
->
type
=
type
;
data
->
length
=
length
;
switch
(
type
)
{
case
PLIST_BOOLEAN
:
data
->
boolval
=
*
((
char
*
)
value
);
break
;
case
PLIST_UINT
:
data
->
intval
=
*
((
uint64_t
*
)
value
);
break
;
case
PLIST_REAL
:
data
->
realval
=
*
((
double
*
)
value
);
break
;
case
PLIST_KEY
:
case
PLIST_STRING
:
data
->
strval
=
strdup
((
char
*
)
value
);
break
;
case
PLIST_DATA
:
data
->
buff
=
(
uint8_t
*
)
malloc
(
length
);
memcpy
(
data
->
buff
,
value
,
length
);
break
;
case
PLIST_DATE
:
data
->
timeval
.
tv_sec
=
((
GTimeVal
*
)
value
)
->
tv_sec
;
data
->
timeval
.
tv_usec
=
((
GTimeVal
*
)
value
)
->
tv_usec
;
break
;
case
PLIST_ARRAY
:
case
PLIST_DICT
:
default:
break
;
}
}
void
plist_set_key_val
(
plist_t
node
,
const
char
*
val
)
{
plist_set_element_val
(
node
,
PLIST_KEY
,
val
,
strlen
(
val
));
}
void
plist_set_string_val
(
plist_t
node
,
const
char
*
val
)
{
plist_set_element_val
(
node
,
PLIST_STRING
,
val
,
strlen
(
val
));
}
void
plist_set_bool_val
(
plist_t
node
,
uint8_t
val
)
{
plist_set_element_val
(
node
,
PLIST_BOOLEAN
,
&
val
,
sizeof
(
uint8_t
));
}
void
plist_set_uint_val
(
plist_t
node
,
uint64_t
val
)
{
plist_set_element_val
(
node
,
PLIST_UINT
,
&
val
,
sizeof
(
uint64_t
));
}
void
plist_set_real_val
(
plist_t
node
,
double
val
)
{
plist_set_element_val
(
node
,
PLIST_REAL
,
&
val
,
sizeof
(
double
));
}
void
plist_set_data_val
(
plist_t
node
,
const
char
*
val
,
uint64_t
length
)
{
plist_set_element_val
(
node
,
PLIST_DATA
,
val
,
length
);
}
void
plist_set_date_val
(
plist_t
node
,
int32_t
sec
,
int32_t
usec
)
{
GTimeVal
val
=
{
sec
,
usec
};
plist_set_element_val
(
node
,
PLIST_DATE
,
&
val
,
sizeof
(
GTimeVal
));
}
src/xplist.c
View file @
c8a140dc
...
...
@@ -257,7 +257,7 @@ static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node)
if
(
!
xmlStrcmp
(
node
->
name
,
XPLIST_INT
))
{
xmlChar
*
strval
=
xmlNodeGetContent
(
node
);
data
->
intval
=
g_ascii_strtoull
((
char
*
)
strval
,
NULL
,
0
);
data
->
intval
=
g_ascii_strtoull
((
char
*
)
strval
,
NULL
,
0
);
data
->
type
=
PLIST_UINT
;
data
->
length
=
8
;
xmlFree
(
strval
);
...
...
@@ -266,7 +266,7 @@ static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node)
if
(
!
xmlStrcmp
(
node
->
name
,
XPLIST_REAL
))
{
xmlChar
*
strval
=
xmlNodeGetContent
(
node
);
data
->
realval
=
atof
((
char
*
)
strval
);
data
->
realval
=
atof
((
char
*
)
strval
);
data
->
type
=
PLIST_REAL
;
data
->
length
=
8
;
xmlFree
(
strval
);
...
...
@@ -287,9 +287,7 @@ static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node)
len
=
strlen
((
char
*
)
strval
);
type
=
xmlDetectCharEncoding
(
strval
,
len
);
if
(
XML_CHAR_ENCODING_UTF8
==
type
||
XML_CHAR_ENCODING_ASCII
==
type
||
XML_CHAR_ENCODING_NONE
==
type
)
{
if
(
XML_CHAR_ENCODING_UTF8
==
type
||
XML_CHAR_ENCODING_ASCII
==
type
||
XML_CHAR_ENCODING_NONE
==
type
)
{
data
->
strval
=
strdup
((
char
*
)
strval
);
data
->
type
=
PLIST_STRING
;
data
->
length
=
strlen
(
data
->
strval
);
...
...
@@ -311,7 +309,7 @@ static void xml_to_node(xmlNodePtr xml_node, plist_t * plist_node)
xmlChar
*
strval
=
xmlNodeGetContent
(
node
);
gsize
size
=
0
;
guchar
*
dec
=
g_base64_decode
((
char
*
)
strval
,
&
size
);
data
->
buff
=
(
uint8_t
*
)
malloc
(
size
*
sizeof
(
uint8_t
));
data
->
buff
=
(
uint8_t
*
)
malloc
(
size
*
sizeof
(
uint8_t
));
memcpy
(
data
->
buff
,
dec
,
size
*
sizeof
(
uint8_t
));
g_free
(
dec
);
data
->
length
=
size
;
...
...
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