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
bb3097cb
Commit
bb3097cb
authored
Feb 15, 2009
by
Jonathan Beck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add more regression test and fix Integer and Real type handling.
parent
8e9eb83c
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
246 additions
and
72 deletions
+246
-72
plist.h
include/plist/plist.h
+8
-0
bplist.c
src/bplist.c
+16
-64
plist.c
src/plist.c
+67
-0
plist.h
src/plist.h
+1
-1
xplist.c
src/xplist.c
+2
-2
CMakeLists.txt
test/CMakeLists.txt
+10
-1
2.plist
test/data/2.plist
+1
-1
3.plist
test/data/3.plist
+1
-1
4.plist
test/data/4.plist
+1
-1
5.plist
test/data/5.plist
+1
-1
plist_cmp.c
test/plist_cmp.c
+138
-0
No files found.
include/plist/plist.h
View file @
bb3097cb
...
...
@@ -394,6 +394,14 @@ extern "C" {
*/
PLIST_API
plist_t
plist_find_node_by_string
(
plist_t
plist
,
const
char
*
value
);
/**
* Compare two node values
*
* @param node_l left node to compare
* @param node_r rigth node to compare
* @return TRUE is type and value match, FALSE otherwise.
*/
PLIST_API
char
plist_compare_node_value
(
plist_t
node_l
,
plist_t
node_r
);
/*@}*/
...
...
src/bplist.c
View file @
bb3097cb
...
...
@@ -87,7 +87,7 @@ static uint32_t uint24_from_be(char *buff)
#define UINT_TO_HOST(x, n) \
(n == 8 ? GUINT64_FROM_BE( *(uint64_t *)(x) ) : \
(n == 4 ? GUINT32_FROM_BE( *(uint32_t *)(x) ) : \
(n == 3 ? uint24_from_be( x ) : \
(n == 3 ? uint24_from_be(
(char*)
x ) : \
(n == 2 ? GUINT16_FROM_BE( *(uint16_t *)(x) ) : \
*(uint8_t *)(x) ))))
...
...
@@ -99,10 +99,7 @@ static uint32_t uint24_from_be(char *buff)
( ((uint64_t)x) < (1ULL << 24) ? 3 : \
( ((uint64_t)x) < (1ULL << 32) ? 4 : 8))))
#define get_real_bytes(x) (x >> 32 ? 4 : 8)
#define get_real_bytes(x) (x == (float) x ? 4 : 8)
static
plist_t
parse_uint_node
(
char
*
bnode
,
uint8_t
size
,
char
**
next_object
)
...
...
@@ -133,12 +130,18 @@ static plist_t parse_uint_node(char *bnode, uint8_t size, char **next_object)
static
plist_t
parse_real_node
(
char
*
bnode
,
uint8_t
size
)
{
plist_data_t
data
=
plist_new_plist_data
();
float
floatval
=
0
.
0
;
size
=
1
<<
size
;
// make length less misleading
switch
(
size
)
{
case
sizeof
(
float
):
floatval
=
*
(
float
*
)
bnode
;
byte_convert
((
uint8_t
*
)
&
floatval
,
sizeof
(
float
));
data
->
realval
=
floatval
;
break
;
case
sizeof
(
double
):
data
->
intval
=
UINT_TO_HOST
(
bnode
,
size
);
//use the fact that we have an union to cheat byte swapping
data
->
realval
=
*
(
double
*
)
bnode
;
byte_convert
((
uint8_t
*
)
&
(
data
->
realval
),
sizeof
(
double
));
break
;
default:
free
(
data
);
...
...
@@ -187,7 +190,7 @@ static plist_t parse_unicode_node(char *bnode, uint64_t size)
data
->
unicodeval
[
sizeof
(
gunichar2
)
*
size
]
=
'\0'
;
data
->
length
=
size
;
for
(
i
=
0
;
i
<=
size
;
i
++
)
byte_convert
(
data
->
unicodeval
+
i
,
sizeof
(
gunichar2
));
byte_convert
(
(
uint8_t
*
)(
data
->
unicodeval
+
i
)
,
sizeof
(
gunichar2
));
return
g_node_new
(
data
);
}
...
...
@@ -543,63 +546,7 @@ static guint plist_data_hash(gconstpointer key)
return
hash
;
}
static
gboolean
plist_data_compare
(
gconstpointer
a
,
gconstpointer
b
)
{
plist_data_t
val_a
=
NULL
;
plist_data_t
val_b
=
NULL
;
if
(
!
a
||
!
b
)
return
FALSE
;
if
(
!
((
GNode
*
)
a
)
->
data
||
!
((
GNode
*
)
b
)
->
data
)
return
FALSE
;
val_a
=
plist_get_data
((
plist_t
)
a
);
val_b
=
plist_get_data
((
plist_t
)
b
);
if
(
val_a
->
type
!=
val_b
->
type
)
return
FALSE
;
switch
(
val_a
->
type
)
{
case
PLIST_BOOLEAN
:
case
PLIST_UINT
:
case
PLIST_REAL
:
if
(
val_a
->
intval
==
val_b
->
intval
)
//it is an union so this is sufficient
return
TRUE
;
else
return
FALSE
;
case
PLIST_KEY
:
case
PLIST_STRING
:
if
(
!
strcmp
(
val_a
->
strval
,
val_b
->
strval
))
return
TRUE
;
else
return
FALSE
;
case
PLIST_UNICODE
:
if
(
!
memcmp
(
val_a
->
unicodeval
,
val_b
->
unicodeval
,
val_a
->
length
))
return
TRUE
;
else
return
FALSE
;
case
PLIST_DATA
:
case
PLIST_ARRAY
:
case
PLIST_DICT
:
//compare pointer
if
(
a
==
b
)
return
TRUE
;
else
return
FALSE
;
break
;
case
PLIST_DATE
:
if
(
!
memcmp
(
&
(
val_a
->
timeval
),
&
(
val_b
->
timeval
),
sizeof
(
GTimeVal
)))
return
TRUE
;
else
return
FALSE
;
default:
break
;
}
return
FALSE
;
}
struct
serialize_s
{
GPtrArray
*
objects
;
...
...
@@ -655,7 +602,12 @@ static void write_real(GByteArray * bplist, double val)
uint64_t
size
=
get_real_bytes
(
*
((
uint64_t
*
)
&
val
));
//cheat to know used space
uint8_t
*
buff
=
(
uint8_t
*
)
malloc
(
sizeof
(
uint8_t
)
+
size
);
buff
[
0
]
=
BPLIST_REAL
|
Log2
(
size
);
memcpy
(
buff
+
1
,
&
val
,
size
);
if
(
size
==
sizeof
(
double
))
{
memcpy
(
buff
+
1
,
&
val
,
size
);
}
else
if
(
size
==
sizeof
(
float
))
{
float
tmpval
=
(
float
)
val
;
memcpy
(
buff
+
1
,
&
tmpval
,
size
);
}
byte_convert
(
buff
+
1
,
size
);
g_byte_array_append
(
bplist
,
buff
,
sizeof
(
uint8_t
)
+
size
);
free
(
buff
);
...
...
src/plist.c
View file @
bb3097cb
...
...
@@ -414,3 +414,70 @@ void plist_get_date_val(plist_t node, int32_t * sec, int32_t * usec)
*
sec
=
val
.
tv_sec
;
*
usec
=
val
.
tv_usec
;
}
gboolean
plist_data_compare
(
gconstpointer
a
,
gconstpointer
b
)
{
plist_data_t
val_a
=
NULL
;
plist_data_t
val_b
=
NULL
;
if
(
!
a
||
!
b
)
return
FALSE
;
if
(
!
((
GNode
*
)
a
)
->
data
||
!
((
GNode
*
)
b
)
->
data
)
return
FALSE
;
val_a
=
plist_get_data
((
plist_t
)
a
);
val_b
=
plist_get_data
((
plist_t
)
b
);
if
(
val_a
->
type
!=
val_b
->
type
)
return
FALSE
;
switch
(
val_a
->
type
)
{
case
PLIST_BOOLEAN
:
case
PLIST_UINT
:
case
PLIST_REAL
:
if
(
val_a
->
intval
==
val_b
->
intval
)
//it is an union so this is sufficient
return
TRUE
;
else
return
FALSE
;
case
PLIST_KEY
:
case
PLIST_STRING
:
if
(
!
strcmp
(
val_a
->
strval
,
val_b
->
strval
))
return
TRUE
;
else
return
FALSE
;
case
PLIST_UNICODE
:
if
(
!
memcmp
(
val_a
->
unicodeval
,
val_b
->
unicodeval
,
val_a
->
length
))
return
TRUE
;
else
return
FALSE
;
case
PLIST_DATA
:
if
(
!
memcmp
(
val_a
->
buff
,
val_b
->
buff
,
val_a
->
length
))
return
TRUE
;
else
return
FALSE
;
case
PLIST_ARRAY
:
case
PLIST_DICT
:
//compare pointer
if
(
a
==
b
)
return
TRUE
;
else
return
FALSE
;
break
;
case
PLIST_DATE
:
if
(
!
memcmp
(
&
(
val_a
->
timeval
),
&
(
val_b
->
timeval
),
sizeof
(
GTimeVal
)))
return
TRUE
;
else
return
FALSE
;
default:
break
;
}
return
FALSE
;
}
char
plist_compare_node_value
(
plist_t
node_l
,
plist_t
node_r
)
{
return
plist_data_compare
(
node_l
,
node_r
);
}
src/plist.h
View file @
bb3097cb
...
...
@@ -49,7 +49,7 @@ typedef struct plist_data_s *plist_data_t;
plist_t
plist_new_node
(
plist_data_t
data
);
plist_data_t
plist_get_data
(
const
plist_t
node
);
plist_data_t
plist_new_plist_data
();
gboolean
plist_data_compare
(
gconstpointer
a
,
gconstpointer
b
);
#endif
src/xplist.c
View file @
bb3097cb
...
...
@@ -152,12 +152,12 @@ static void node_to_xml(GNode * node, gpointer xml_struct)
case
PLIST_UINT
:
tag
=
XPLIST_INT
;
val
=
g_strdup_printf
(
"%l
u"
,
(
long
unsigned
int
)
node_data
->
intval
);
val
=
g_strdup_printf
(
"%l
lu"
,
node_data
->
intval
);
break
;
case
PLIST_REAL
:
tag
=
XPLIST_REAL
;
val
=
g_strdup_printf
(
"%
Lf"
,
(
long
double
)
node_data
->
realval
);
val
=
g_strdup_printf
(
"%
f"
,
node_data
->
realval
);
break
;
case
PLIST_STRING
:
...
...
test/CMakeLists.txt
View file @
bb3097cb
...
...
@@ -3,9 +3,12 @@
SET
(
plist_test_SRC
plist_test.c
)
SET
(
plist_cmp_SRC
plist_cmp.c
)
ADD_EXECUTABLE
(
plist_test
${
plist_test_SRC
}
)
TARGET_LINK_LIBRARIES
(
plist_test plist
)
ADD_EXECUTABLE
(
plist_cmp
${
plist_cmp_SRC
}
)
TARGET_LINK_LIBRARIES
(
plist_cmp plist
)
INCLUDE
(
CTest
)
...
...
@@ -16,3 +19,9 @@ ADD_TEST(Large plist_test data/4.plist)
ADD_TEST
(
Huge plist_test data/5.plist
)
ADD_TEST
(
Big_Array plist_test data/6.plist
)
ADD_TEST
(
EmptyCmp plist_cmp data/1.plist data/1.plist.out
)
ADD_TEST
(
SmallCmp plist_cmp data/2.plist data/2.plist.out
)
ADD_TEST
(
MediumCmp plist_cmp data/3.plist data/3.plist.out
)
ADD_TEST
(
LargeCmp plist_cmp data/4.plist data/4.plist.out
)
ADD_TEST
(
HugeCmp plist_cmp data/5.plist data/5.plist.out
)
ADD_TEST
(
Big_ArrayCmp plist_cmp data/6.plist data/6.plist.out
)
test/data/2.plist
View file @
bb3097cb
...
...
@@ -23,7 +23,7 @@
<
k
e
y
>
Some
Int
<
/k
e
y
>
<
int
e
g
e
r
>
32434543632
<
/int
e
g
e
r
>
<
k
e
y
>
Some
Real
<
/k
e
y
>
<
r
ea
l
>
58654.347656
3
<
/r
ea
l
>
<
r
ea
l
>
58654.347656
<
/r
ea
l
>
<
k
e
y
>
Some
Date
<
/k
e
y
>
<
da
t
e
>
2009-02-12T22:23:00Z
<
/
da
t
e
>
<
k
e
y
>
Some
Data
<
/k
e
y
>
...
...
test/data/3.plist
View file @
bb3097cb
...
...
@@ -23,7 +23,7 @@
<
k
e
y
>
Some
Int
<
/k
e
y
>
<
int
e
g
e
r
>
32434543632
<
/int
e
g
e
r
>
<
k
e
y
>
Some
Real
<
/k
e
y
>
<
r
ea
l
>
58654.347656
3
<
/r
ea
l
>
<
r
ea
l
>
58654.347656
<
/r
ea
l
>
<
k
e
y
>
Some
Date
<
/k
e
y
>
<
da
t
e
>
2009-02-12T22:23:00Z
<
/
da
t
e
>
<
k
e
y
>
Some
Data
<
/k
e
y
>
...
...
test/data/4.plist
View file @
bb3097cb
...
...
@@ -23,7 +23,7 @@
<
k
e
y
>
Some
Int
<
/k
e
y
>
<
int
e
g
e
r
>
32434543632
<
/int
e
g
e
r
>
<
k
e
y
>
Some
Real
<
/k
e
y
>
<
r
ea
l
>
58654.347656
3
<
/r
ea
l
>
<
r
ea
l
>
58654.347656
<
/r
ea
l
>
<
k
e
y
>
Some
Date
<
/k
e
y
>
<
da
t
e
>
2009-02-12T22:23:00Z
<
/
da
t
e
>
<
k
e
y
>
Some
Data
<
/k
e
y
>
...
...
test/data/5.plist
View file @
bb3097cb
...
...
@@ -23,7 +23,7 @@
<key>Some Int</key>
<integer>32434543632</integer>
<key>Some Real</key>
<real>58654.347656
3
</real>
<real>58654.347656</real>
<key>Some Date</key>
<date>2009-02-12T22:23:00Z</date>
<key>Some Data</key>
test/plist_cmp.c
0 → 100644
View file @
bb3097cb
/*
* backup_test.c
* source libplist regression test
*
* Copyright (c) 2009 Jonathan Beck All Rights Reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "plist/plist.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
char
compare_plist
(
plist_t
node_l
,
plist_t
node_r
)
{
plist_t
cur_l
=
NULL
;
plist_t
cur_r
=
NULL
;
int
res
=
1
;
cur_l
=
plist_get_first_child
(
node_l
);
cur_r
=
plist_get_first_child
(
node_r
);
if
(
(
!
cur_l
&&
cur_r
)
||
(
cur_l
&&
!
cur_r
))
return
0
;
if
(
!
cur_l
&&
!
cur_r
)
return
plist_compare_node_value
(
node_l
,
node_r
);
while
(
cur_l
&&
cur_r
&&
res
)
{
if
(
!
(
res
=
compare_plist
(
cur_l
,
cur_r
)))
return
res
;
cur_l
=
plist_get_next_sibling
(
cur_l
);
cur_r
=
plist_get_next_sibling
(
cur_r
);
if
(
(
!
cur_l
&&
cur_r
)
||
(
cur_l
&&
!
cur_r
))
return
0
;
}
return
res
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
FILE
*
iplist1
=
NULL
;
FILE
*
iplist2
=
NULL
;
plist_t
root_node1
=
NULL
;
plist_t
root_node2
=
NULL
;
char
*
plist_1
=
NULL
;
char
*
plist_2
=
NULL
;
int
size_in1
=
0
;
int
size_in2
=
0
;
char
*
file_in1
=
NULL
;
char
*
file_in2
=
NULL
;
int
res
=
0
;
struct
stat
*
filestats1
=
(
struct
stat
*
)
malloc
(
sizeof
(
struct
stat
));
struct
stat
*
filestats2
=
(
struct
stat
*
)
malloc
(
sizeof
(
struct
stat
));
if
(
argc
!=
3
)
{
printf
(
"Wrong input
\n
"
);
return
1
;
}
file_in1
=
argv
[
1
];
file_in2
=
argv
[
2
];
//read input file
iplist1
=
fopen
(
file_in1
,
"rb"
);
iplist2
=
fopen
(
file_in2
,
"rb"
);
if
(
!
iplist1
||
!
iplist2
)
{
printf
(
"File does not exists
\n
"
);
return
2
;
}
stat
(
file_in1
,
filestats1
);
stat
(
file_in2
,
filestats2
);
size_in1
=
filestats1
->
st_size
;
size_in2
=
filestats2
->
st_size
;
plist_1
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
size_in1
+
1
));
plist_2
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
size_in2
+
1
));
fread
(
plist_1
,
sizeof
(
char
),
size_in1
,
iplist1
);
fread
(
plist_2
,
sizeof
(
char
),
size_in2
,
iplist2
);
fclose
(
iplist1
);
fclose
(
iplist2
);
if
(
memcmp
(
plist_1
,
"bplist00"
,
8
)
==
0
)
plist_from_bin
(
plist_1
,
size_in1
,
&
root_node1
);
else
plist_from_xml
(
plist_1
,
size_in1
,
&
root_node1
);
if
(
memcmp
(
plist_2
,
"bplist00"
,
8
)
==
0
)
plist_from_bin
(
plist_2
,
size_in2
,
&
root_node2
);
else
plist_from_xml
(
plist_2
,
size_in2
,
&
root_node2
);
if
(
!
root_node1
||
!
root_node2
)
{
printf
(
"PList parsing failed
\n
"
);
return
3
;
}
else
printf
(
"PList parsing succeeded
\n
"
);
res
=
compare_plist
(
root_node1
,
root_node2
);
plist_free
(
root_node1
);
plist_free
(
root_node2
);
free
(
plist_1
);
free
(
plist_2
);
free
(
filestats1
);
free
(
filestats2
);
return
!
res
;
}
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