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
1a06347d
Commit
1a06347d
authored
Dec 08, 2008
by
Jonathan Beck
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cleanup binary parsing and move stuff around.
parent
75639177
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
489 additions
and
385 deletions
+489
-385
lockdown.c
src/lockdown.c
+1
-1
plist.c
src/plist.c
+471
-383
plist.h
src/plist.h
+17
-1
No files found.
src/lockdown.c
View file @
1a06347d
...
@@ -963,7 +963,7 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char
...
@@ -963,7 +963,7 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char
if
(
result_key_type
==
PLIST_KEY
&&
if
(
result_key_type
==
PLIST_KEY
&&
result_value_type
==
PLIST_STRING
&&
result_value_type
==
PLIST_STRING
&&
port_key_type
==
PLIST_KEY
&&
port_key_type
==
PLIST_KEY
&&
port_value_type
==
PLIST_UINT
64
&&
port_value_type
==
PLIST_UINT
&&
!
strcmp
(
result_key
,
"Result"
)
&&
!
strcmp
(
result_value
,
"Success"
)
&&
!
strcmp
(
port_key
,
"Port"
))
{
!
strcmp
(
result_key
,
"Result"
)
&&
!
strcmp
(
result_value
,
"Success"
)
&&
!
strcmp
(
port_key
,
"Port"
))
{
port_loc
=
port_value
;
port_loc
=
port_value
;
ret
=
IPHONE_E_SUCCESS
;
ret
=
IPHONE_E_SUCCESS
;
...
...
src/plist.c
View file @
1a06347d
...
@@ -19,19 +19,24 @@
...
@@ -19,19 +19,24 @@
* 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 <libxml/parser.h>
#include <libxml/tree.h>
#include <string.h>
#include <string.h>
#include <assert.h>
#include <assert.h>
#include "utils.h"
#include "utils.h"
#include "plist.h"
#include "plist.h"
#include <wchar.h>
#include <wchar.h>
/**********************************************
* *
* Abstract Plist stuff *
* *
**********************************************/
const
char
*
plist_base
=
"<?xml version=
\"
1.0
\"
encoding=
\"
UTF-8
\"
?>
\n
\
<!DOCTYPE plist PUBLIC
\"
-//Apple Computer//DTD PLIST 1.0//EN
\"
\"
http://www.apple.com/DTDs/PropertyList-1.0.dtd
\"
>
\n
\
<plist version=
\"
1.0
\"
>
\n
\
</plist>
\0
"
;
/** Formats a block of text to be a given indentation and width.
/** Formats a block of text to be a given indentation and width.
*
*
...
@@ -72,34 +77,7 @@ char *format_string(const char *buf, int cols, int depth)
...
@@ -72,34 +77,7 @@ char *format_string(const char *buf, int cols, int depth)
return
new_buf
;
return
new_buf
;
}
}
/** Creates a new plist XML document.
*
* @return The plist XML document.
*/
xmlDocPtr
new_plist
()
{
char
*
plist
=
strdup
(
plist_base
);
xmlDocPtr
plist_xml
=
xmlReadMemory
(
plist
,
strlen
(
plist
),
NULL
,
NULL
,
0
);
if
(
!
plist_xml
)
return
NULL
;
free
(
plist
);
return
plist_xml
;
}
/** Destroys a previously created XML document.
*
* @param plist The XML document to destroy.
*/
void
free_plist
(
xmlDocPtr
plist
)
{
if
(
!
plist
)
return
;
xmlFreeDoc
(
plist
);
}
/*
/*
...
@@ -117,29 +95,7 @@ void free_plist(xmlDocPtr plist)
...
@@ -117,29 +95,7 @@ void free_plist(xmlDocPtr plist)
* - parse_nodes() will return the first node it encounters, which is usually the "root" node.
* - parse_nodes() will return the first node it encounters, which is usually the "root" node.
*/
*/
uint32_t
uipow
(
uint32_t
value
,
uint32_t
power
)
{
if
(
!
power
)
return
1
;
int
i
=
0
,
oVal
=
value
;
for
(
i
=
1
;
i
<
power
;
i
++
)
{
value
*=
oVal
;
}
return
value
;
}
void
byte_convert
(
char
*
address
,
size_t
size
)
{
int
i
=
0
,
j
=
0
;
char
tmp
=
'\0'
;
for
(
i
=
0
;
i
<
(
size
/
2
);
i
++
)
{
tmp
=
address
[
i
];
j
=
((
size
-
1
)
+
0
)
-
i
;
address
[
i
]
=
address
[
j
];
address
[
j
]
=
tmp
;
}
}
void
print_bytes
(
char
*
val
,
size_t
size
)
void
print_bytes
(
char
*
val
,
size_t
size
)
{
{
...
@@ -154,39 +110,17 @@ void print_bytes(char *val, size_t size)
...
@@ -154,39 +110,17 @@ void print_bytes(char *val, size_t size)
struct
plist_data
{
struct
plist_data
{
union
{
union
{
char
boolval
;
char
boolval
;
uint8_t
intval8
;
uint64_t
intval
;
uint16_t
intval16
;
double
realval
;
uint32_t
intval32
;
uint64_t
intval64
;
float
realval32
;
double
realval64
;
char
*
strval
;
char
*
strval
;
wchar_t
*
unicodeval
;
wchar_t
*
unicodeval
;
struct
{
char
*
buff
;
char
*
buff
;
uint8_t
ref_size
;
};
};
};
uint64_t
length
;
uint64_t
length
;
plist_type
type
;
plist_type
type
;
};
};
enum
{
BPLIST_TRUE
=
0x08
,
BPLIST_FALSE
=
0x09
,
BPLIST_FILL
=
0x0F
,
/* will be used for length grabbing */
BPLIST_INT
=
0x10
,
BPLIST_REAL
=
0x20
,
BPLIST_DATE
=
0x33
,
BPLIST_DATA
=
0x40
,
BPLIST_STRING
=
0x50
,
BPLIST_UNICODE
=
0x60
,
BPLIST_UID
=
0x70
,
BPLIST_ARRAY
=
0xA0
,
BPLIST_SET
=
0xC0
,
BPLIST_DICT
=
0xD0
,
BPLIST_MASK
=
0xF0
};
void
plist_new_plist
(
plist_t
*
plist
)
void
plist_new_plist
(
plist_t
*
plist
)
{
{
...
@@ -239,23 +173,11 @@ void plist_add_dict_element(dict_t dict, char *key, plist_type type, void *value
...
@@ -239,23 +173,11 @@ void plist_add_dict_element(dict_t dict, char *key, plist_type type, void *value
case
PLIST_BOOLEAN
:
case
PLIST_BOOLEAN
:
val
->
boolval
=
*
((
char
*
)
value
);
val
->
boolval
=
*
((
char
*
)
value
);
break
;
break
;
case
PLIST_UINT8
:
case
PLIST_UINT
:
val
->
intval8
=
*
((
uint8_t
*
)
value
);
val
->
intval
=
*
((
uint64_t
*
)
value
);
break
;
case
PLIST_UINT16
:
val
->
intval16
=
*
((
uint16_t
*
)
value
);
break
;
case
PLIST_UINT32
:
val
->
intval32
=
*
((
uint32_t
*
)
value
);
break
;
break
;
case
PLIST_UINT64
:
case
PLIST_REAL
:
val
->
intval64
=
*
((
uint64_t
*
)
value
);
val
->
realval
=
*
((
double
*
)
value
);
break
;
case
PLIST_FLOAT32
:
val
->
realval32
=
*
((
float
*
)
value
);
break
;
case
PLIST_FLOAT64
:
val
->
realval64
=
*
((
double
*
)
value
);
break
;
break
;
case
PLIST_STRING
:
case
PLIST_STRING
:
val
->
strval
=
strdup
((
char
*
)
value
);
val
->
strval
=
strdup
((
char
*
)
value
);
...
@@ -282,11 +204,55 @@ void plist_free(plist_t plist)
...
@@ -282,11 +204,55 @@ void plist_free(plist_t plist)
g_node_destroy
(
plist
);
g_node_destroy
(
plist
);
}
}
/**********************************************
* *
* Xml Plist stuff *
* *
**********************************************/
#include <libxml/parser.h>
#include <libxml/tree.h>
const
char
*
plist_base
=
"<?xml version=
\"
1.0
\"
encoding=
\"
UTF-8
\"
?>
\n
\
<!DOCTYPE plist PUBLIC
\"
-//Apple Computer//DTD PLIST 1.0//EN
\"
\"
http://www.apple.com/DTDs/PropertyList-1.0.dtd
\"
>
\n
\
<plist version=
\"
1.0
\"
>
\n
\
</plist>
\0
"
;
struct
xml_node
{
struct
xml_node
{
xmlNodePtr
xml
;
xmlNodePtr
xml
;
uint32_t
depth
;
uint32_t
depth
;
};
};
/** Creates a new plist XML document.
*
* @return The plist XML document.
*/
xmlDocPtr
new_plist
()
{
char
*
plist
=
strdup
(
plist_base
);
xmlDocPtr
plist_xml
=
xmlReadMemory
(
plist
,
strlen
(
plist
),
NULL
,
NULL
,
0
);
if
(
!
plist_xml
)
return
NULL
;
free
(
plist
);
return
plist_xml
;
}
/** Destroys a previously created XML document.
*
* @param plist The XML document to destroy.
*/
void
free_plist
(
xmlDocPtr
plist
)
{
if
(
!
plist
)
return
;
xmlFreeDoc
(
plist
);
}
void
node_to_xml
(
GNode
*
node
,
gpointer
xml_struct
)
void
node_to_xml
(
GNode
*
node
,
gpointer
xml_struct
)
{
{
if
(
!
node
)
if
(
!
node
)
...
@@ -311,34 +277,14 @@ void node_to_xml(GNode * node, gpointer xml_struct)
...
@@ -311,34 +277,14 @@ void node_to_xml(GNode * node, gpointer xml_struct)
}
}
break
;
break
;
case
PLIST_UINT8
:
case
PLIST_UINT
:
tag
=
"integer"
;
val
=
g_strdup_printf
(
"%u"
,
node_data
->
intval8
);
break
;
case
PLIST_UINT16
:
tag
=
"integer"
;
val
=
g_strdup_printf
(
"%u"
,
node_data
->
intval16
);
break
;
case
PLIST_UINT32
:
tag
=
"integer"
;
val
=
g_strdup_printf
(
"%u"
,
node_data
->
intval32
);
break
;
case
PLIST_UINT64
:
tag
=
"integer"
;
tag
=
"integer"
;
val
=
g_strdup_printf
(
"%lu"
,
(
long
unsigned
int
)
node_data
->
intval64
);
val
=
g_strdup_printf
(
"%lu"
,
(
long
unsigned
int
)
node_data
->
intval
);
break
;
case
PLIST_FLOAT32
:
tag
=
"real"
;
val
=
g_strdup_printf
(
"%f"
,
node_data
->
realval32
);
break
;
break
;
case
PLIST_
FLOAT64
:
case
PLIST_
REAL
:
tag
=
"real"
;
tag
=
"real"
;
val
=
g_strdup_printf
(
"%Lf"
,
(
long
double
)
node_data
->
intval64
);
val
=
g_strdup_printf
(
"%Lf"
,
(
long
double
)
node_data
->
realval
);
break
;
break
;
case
PLIST_STRING
:
case
PLIST_STRING
:
...
@@ -358,7 +304,7 @@ void node_to_xml(GNode * node, gpointer xml_struct)
...
@@ -358,7 +304,7 @@ void node_to_xml(GNode * node, gpointer xml_struct)
case
PLIST_DATA
:
case
PLIST_DATA
:
tag
=
"data"
;
tag
=
"data"
;
val
=
format_string
(
node_data
->
buff
,
60
,
0
);
val
=
format_string
(
node_data
->
buff
,
60
,
xstruct
->
depth
);
break
;
break
;
case
PLIST_ARRAY
:
case
PLIST_ARRAY
:
tag
=
"array"
;
tag
=
"array"
;
...
@@ -435,15 +381,15 @@ void xml_to_node(xmlNodePtr xml_node, GNode * plist_node)
...
@@ -435,15 +381,15 @@ void xml_to_node(xmlNodePtr xml_node, GNode * plist_node)
if
(
!
xmlStrcmp
(
node
->
name
,
"integer"
))
{
if
(
!
xmlStrcmp
(
node
->
name
,
"integer"
))
{
char
*
strval
=
xmlNodeGetContent
(
node
);
char
*
strval
=
xmlNodeGetContent
(
node
);
data
->
intval
64
=
atoi
(
strval
);
data
->
intval
=
atoi
(
strval
);
data
->
type
=
PLIST_UINT
64
;
data
->
type
=
PLIST_UINT
;
continue
;
continue
;
}
}
if
(
!
xmlStrcmp
(
node
->
name
,
"real"
))
{
if
(
!
xmlStrcmp
(
node
->
name
,
"real"
))
{
char
*
strval
=
xmlNodeGetContent
(
node
);
char
*
strval
=
xmlNodeGetContent
(
node
);
data
->
realval
64
=
atof
(
strval
);
data
->
realval
=
atof
(
strval
);
data
->
type
=
PLIST_
FLOAT64
;
data
->
type
=
PLIST_
REAL
;
continue
;
continue
;
}
}
...
@@ -493,294 +439,460 @@ void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length)
...
@@ -493,294 +439,460 @@ void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length)
xmlDocDumpMemory
(
plist_doc
,
(
xmlChar
**
)
plist_xml
,
length
);
xmlDocDumpMemory
(
plist_doc
,
(
xmlChar
**
)
plist_xml
,
length
);
}
}
GNode
*
parse_raw_node
(
const
char
*
bpbuffer
,
uint32_t
bplength
,
uint32_t
*
position
,
uint8_t
ref_size
)
void
xml_to_plist
(
const
char
*
plist_xml
,
uint32_t
length
,
plist_t
*
plist
)
{
{
if
(
!
position
||
!
bpbuffer
||
!
bplength
)
xmlDocPtr
plist_doc
=
xmlReadMemory
(
plist_xml
,
length
,
NULL
,
NULL
,
0
);
return
NULL
;
xmlNodePtr
root_node
=
xmlDocGetRootElement
(
plist_doc
)
;
uint8_t
modifier
=
0
;
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
GNode
*
new_node
=
g_node_new
(
data
);
*
plist
=
g_node_new
(
data
);
GNode
*
length_stupidity
=
NULL
;
data
->
type
=
PLIST_PLIST
;
xml_to_node
(
root_node
,
*
plist
);
}
int
myPos
=
*
position
;
if
(
myPos
==
bplength
||
(
myPos
+
1
)
==
bplength
)
{
g_node_destroy
(
new_node
);
return
NULL
;
}
// end of string
uint32_t
length
=
0
;
if
(
!
myPos
)
{
if
(
strncmp
(
bpbuffer
,
"bplist00"
,
strlen
(
"bplist00"
)))
{
return
NULL
;
// badness!
}
myPos
+=
strlen
(
"bplist00"
);
}
// Get the node's type.
if
(
bpbuffer
[
myPos
]
==
BPLIST_DATE
)
{
// handle date separately, but do it as a real
// better handling of date; basically interpret as real or double
data
->
type
=
BPLIST_DATE
;
length
=
8
;
// always 8 for "date" (Apple intended it, not me)
myPos
++
;
memcpy
(
&
data
->
realval64
,
bpbuffer
+
myPos
,
sizeof
(
data
->
realval64
));
byte_convert
((
char
*
)
&
data
->
realval64
,
sizeof
(
data
->
realval64
));
myPos
+=
length
;
*
position
=
myPos
;
return
new_node
;
}
int
type
=
bpbuffer
[
myPos
]
&
BPLIST_MASK
;
data
->
length
=
bpbuffer
[
myPos
]
&
BPLIST_FILL
;
if
(
!
type
)
{
// what? check if it's a boolean.
if
(
bpbuffer
[
myPos
]
==
BPLIST_TRUE
||
bpbuffer
[
myPos
]
==
BPLIST_FALSE
)
{
// okay, so it is. Carry on.
data
->
type
=
PLIST_BOOLEAN
;
data
->
boolval
=
TRUE
;
data
->
length
=
0
;
}
else
{
// er, what? we have a bad type here. Return NULL.
g_node_destroy
(
new_node
);
//printf("parse_raw_node: lol type: type given %x\n", bpbuffer[myPos]);
return
NULL
;
}
}
myPos
++
;
// puts us in the data.
if
(
length
==
BPLIST_FILL
)
{
// Data happens to contain length...
/**********************************************
// what? you're going to make me parse an int for the length. You suck.
* *
*
position
=
myPos
;
* Binary Plist stuff *
length_stupidity
=
parse_raw_node
(
bpbuffer
,
bplength
,
&
myPos
,
ref_size
);
* *
switch
(((
struct
plist_data
*
)
length_stupidity
->
data
)
->
type
)
{
**********************************************/
case
PLIST_UINT8
:
data
->
length
=
((
struct
plist_data
*
)
length_stupidity
->
data
)
->
intval8
;
/* Magic marker and size. */
break
;
#define BPLIST_MAGIC "bplist"
case
PLIST_UINT16
:
#define BPLIST_MAGIC_SIZE 6
data
->
length
=
((
struct
plist_data
*
)
length_stupidity
->
data
)
->
intval16
;
break
;
#define BPLIST_VERSION "00"
case
PLIST_UINT32
:
#define BPLIST_VERSION_SIZE 2
data
->
length
=
((
struct
plist_data
*
)
length_stupidity
->
data
)
->
intval32
;
break
;
case
PLIST_UINT64
:
#define BPLIST_TRL_SIZE 26
data
->
length
=
((
struct
plist_data
*
)
length_stupidity
->
data
)
->
intval64
;
#define BPLIST_TRL_OFFSIZE_IDX 0
break
;
#define BPLIST_TRL_PARMSIZE_IDX 1
default:
#define BPLIST_TRL_NUMOBJ_IDX 2
g_node_destroy
(
new_node
);
#define BPLIST_TRL_ROOTOBJ_IDX 10
g_node_destroy
(
length_stupidity
);
#define BPLIST_TRL_OFFTAB_IDX 18
return
NULL
;
}
enum
{
// There, we have our fucking length now.
BPLIST_NULL
=
0x00
,
*
position
=
myPos
;
BPLIST_TRUE
=
0x08
,
g_node_destroy
(
length_stupidity
);
// cleanup
BPLIST_FALSE
=
0x09
,
}
BPLIST_FILL
=
0x0F
,
/* will be used for length grabbing */
// Now we're in the data.
BPLIST_UINT
=
0x10
,
// Error-checking sorta
BPLIST_REAL
=
0x20
,
if
((
myPos
+
data
->
length
)
>=
bplength
)
{
BPLIST_DATE
=
0x30
,
data
->
length
=
bplength
-
myPos
;
// truncate the object
BPLIST_DATA
=
0x40
,
BPLIST_STRING
=
0x50
,
BPLIST_UNICODE
=
0x60
,
BPLIST_UID
=
0x70
,
BPLIST_ARRAY
=
0xA0
,
BPLIST_SET
=
0xC0
,
BPLIST_DICT
=
0xD0
,
BPLIST_MASK
=
0xF0
};
void
byte_convert
(
char
*
address
,
size_t
size
)
{
int
i
=
0
,
j
=
0
;
char
tmp
=
'\0'
;
for
(
i
=
0
;
i
<
(
size
/
2
);
i
++
)
{
tmp
=
address
[
i
];
j
=
((
size
-
1
)
+
0
)
-
i
;
address
[
i
]
=
address
[
j
];
address
[
j
]
=
tmp
;
}
}
// And now for the greatest show on earth: the giant fucking switch statement.
}
switch
(
type
)
{
case
BPLIST_INT
:
#include <byteswap.h>
data
->
length
=
uipow
(
2
,
data
->
length
);
// make length less misleading
#define swap_n_bytes(x, n) \
switch
(
data
->
length
)
{
n == 8 ? bswap_64(*(uint64_t *)(x)) : \
(n == 4 ? bswap_32(*(uint32_t *)(x)) : \
(n == 2 ? bswap_16(*(uint16_t *)(x)) : *(x) ))
#define be64dec(x) bswap_64( *(uint64_t*)(x) )
GNode
*
parse_uint_node
(
char
*
bnode
,
uint8_t
size
,
char
**
next_object
)
{
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
size
=
1
<<
size
;
// make length less misleading
switch
(
size
)
{
case
sizeof
(
uint8_t
):
case
sizeof
(
uint8_t
):
data
->
type
=
PLIST_UINT8
;
data
->
intval
=
bnode
[
0
];
data
->
intval8
=
bpbuffer
[
myPos
];
break
;
break
;
case
sizeof
(
uint16_t
):
case
sizeof
(
uint16_t
):
data
->
type
=
PLIST_UINT16
;
memcpy
(
&
data
->
intval
,
bnode
,
size
);
memcpy
(
&
data
->
intval16
,
bpbuffer
+
myPos
,
sizeof
(
uint16_t
));
data
->
intval
=
ntohs
(
data
->
intval
);
data
->
intval16
=
ntohs
(
data
->
intval16
);
break
;
break
;
case
sizeof
(
uint32_t
):
case
sizeof
(
uint32_t
):
data
->
type
=
PLIST_UINT32
;
memcpy
(
&
data
->
intval
,
bnode
,
size
);
memcpy
(
&
data
->
intval32
,
bpbuffer
+
myPos
,
sizeof
(
uint32_t
));
data
->
intval
=
ntohl
(
data
->
intval
);
data
->
intval32
=
ntohl
(
data
->
intval32
);
break
;
break
;
case
sizeof
(
uint64_t
):
case
sizeof
(
uint64_t
):
data
->
type
=
PLIST_UINT64
;
memcpy
(
&
data
->
intval
,
bnode
,
size
);
memcpy
(
&
data
->
intval64
,
bpbuffer
+
myPos
,
sizeof
(
uint64_t
));
byte_convert
((
char
*
)
&
data
->
intval
,
size
);
byte_convert
((
char
*
)
&
data
->
intval64
,
sizeof
(
uint64_t
));
break
;
break
;
default:
default:
g_node_destroy
(
new_node
);
free
(
data
);
printf
(
"parse_raw_node: lol: invalid int: size given %lu
\n
"
,
(
long
unsigned
int
)
length
);
printf
(
"parse_raw_node: lol: by the way sizeof(uint64) = %i
\n
"
,
sizeof
(
uint64_t
));
return
NULL
;
return
NULL
;
}
};
break
;
case
BPLIST_REAL
:
*
next_object
=
bnode
+
size
;
data
->
length
=
uipow
(
2
,
data
->
length
);
data
->
type
=
PLIST_UINT
;
switch
(
data
->
length
)
{
return
g_node_new
(
data
);
}
GNode
*
parse_real_node
(
char
*
bnode
,
uint8_t
size
)
{
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
size
=
1
<<
size
;
// make length less misleading
switch
(
size
)
{
case
sizeof
(
float
):
case
sizeof
(
float
):
data
->
type
=
PLIST_FLOAT32
;
memcpy
(
&
data
->
realval
,
bnode
,
size
);
memcpy
(
&
data
->
realval32
,
bpbuffer
+
myPos
,
data
->
length
);
byte_convert
((
char
*
)
&
data
->
realval
,
size
);
byte_convert
((
char
*
)
&
data
->
realval32
,
sizeof
(
float
));
//necessary ??
break
;
break
;
case
sizeof
(
double
):
case
sizeof
(
double
):
data
->
type
=
PLIST_FLOAT64
;
memcpy
(
&
data
->
realval
,
bnode
,
size
);
memcpy
(
&
data
->
realval64
,
bpbuffer
+
myPos
,
data
->
length
);
byte_convert
((
char
*
)
&
data
->
realval
,
size
);
byte_convert
((
char
*
)
&
data
->
realval64
,
sizeof
(
double
));
break
;
break
;
default:
default:
g_node_destroy
(
new_node
);
free
(
data
);
printf
(
"parse_raw_node: lol: invalid real: size given %lu
\n
"
,
(
long
unsigned
int
)
length
);
printf
(
"parse_raw_node: lol: by the way sizeof(uint64) = %i
\n
"
,
sizeof
(
uint64_t
));
return
NULL
;
return
NULL
;
}
}
break
;
data
->
type
=
PLIST_REAL
;
return
g_node_new
(
data
);
}
GNode
*
parse_string_node
(
char
*
bnode
,
uint8_t
size
)
{
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
case
BPLIST_STRING
:
data
->
type
=
PLIST_STRING
;
data
->
type
=
PLIST_STRING
;
data
->
strval
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
data
->
length
);
data
->
strval
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
size
+
1
));
memcpy
(
data
->
strval
,
bpbuffer
+
myPos
,
data
->
length
);
memcpy
(
data
->
strval
,
bnode
,
size
);
break
;
data
->
strval
[
size
]
=
'\0'
;
return
g_node_new
(
data
);
}
GNode
*
parse_unicode_node
(
char
*
bnode
,
uint8_t
size
)
{
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
case
BPLIST_UNICODE
:
data
->
type
=
PLIST_UNICODE
;
data
->
type
=
PLIST_UNICODE
;
data
->
unicodeval
=
(
wchar_t
*
)
malloc
(
sizeof
(
wchar_t
)
*
data
->
length
);
data
->
unicodeval
=
(
wchar_t
*
)
malloc
(
sizeof
(
wchar_t
)
*
(
size
+
1
));
memcpy
(
data
->
unicodeval
,
bpbuffer
+
myPos
,
data
->
length
);
memcpy
(
data
->
unicodeval
,
bnode
,
size
);
break
;
data
->
unicodeval
[
size
]
=
'\0'
;
return
g_node_new
(
data
);
}
GNode
*
parse_data_node
(
char
*
bnode
,
uint64_t
size
,
uint32_t
ref_size
)
{
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
data
->
type
=
PLIST_DATA
;
data
->
length
=
size
;
data
->
buff
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
size
);
memcpy
(
data
->
buff
,
bnode
,
sizeof
(
char
)
*
size
);
return
g_node_new
(
data
);
}
GNode
*
parse_dict_node
(
char
*
bnode
,
uint64_t
size
,
uint32_t
ref_size
)
{
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
case
BPLIST_DICT
:
/* returning a raw dict, it forward-references, so. */
data
->
length
=
data
->
length
*
2
;
// dicts lie
data
->
type
=
PLIST_DICT
;
data
->
type
=
PLIST_DICT
;
data
->
length
=
size
;
data
->
buff
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
size
*
ref_size
*
2
);
memcpy
(
data
->
buff
,
bnode
,
sizeof
(
char
)
*
size
*
ref_size
*
2
);
return
g_node_new
(
data
);
}
GNode
*
parse_array_node
(
char
*
bnode
,
uint64_t
size
,
uint32_t
ref_size
)
{
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
case
BPLIST_ARRAY
:
/* returning a raw array, it forward-references, so. */
data
->
ref_size
=
ref_size
;
// in arrays and dicts, the "ref size" alluded to in the trailer applies, and should be stored in intval8 so as to save space.
if
(
data
->
type
==
0
)
data
->
type
=
PLIST_ARRAY
;
data
->
type
=
PLIST_ARRAY
;
data
->
length
=
size
;
data
->
buff
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
size
*
ref_size
);
memcpy
(
data
->
buff
,
bnode
,
sizeof
(
char
)
*
size
*
ref_size
);
return
g_node_new
(
data
);
}
plist_type
plist_get_node_type
(
plist_t
node
)
{
return
((
struct
plist_data
*
)
node
->
data
)
->
type
;
}
uint64_t
plist_get_node_uint_val
(
plist_t
node
)
{
if
(
PLIST_UINT
==
plist_get_node_type
(
node
))
return
((
struct
plist_data
*
)
node
->
data
)
->
intval
;
else
return
0
;
}
GNode
*
parse_bin_node
(
char
*
object
,
uint8_t
dict_size
,
char
**
next_object
)
{
if
(
!
object
)
return
NULL
;
uint16_t
type
=
*
object
&
0xF0
;
uint64_t
size
=
*
object
&
0x0F
;
object
++
;
switch
(
type
)
{
case
BPLIST_NULL
:
switch
(
size
)
{
case
BPLIST_TRUE
:
{
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
data
->
type
=
PLIST_BOOLEAN
;
data
->
boolval
=
TRUE
;
return
g_node_new
(
data
);
}
case
BPLIST_FALSE
:
{
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
data
->
type
=
PLIST_BOOLEAN
;
data
->
boolval
=
FALSE
;
return
g_node_new
(
data
);
}
case
BPLIST_NULL
:
default:
return
NULL
;
}
case
BPLIST_UINT
:
return
parse_uint_node
(
object
,
size
,
next_object
);
case
BPLIST_REAL
:
return
parse_real_node
(
object
,
size
);
case
BPLIST_DATE
:
if
(
3
!=
size
)
return
NULL
;
else
return
parse_real_node
(
object
,
size
);
case
BPLIST_DATA
:
case
BPLIST_DATA
:
if
(
data
->
type
==
0
)
if
(
0x0F
==
size
)
{
data
->
type
=
PLIST_DATA
;
plist_t
size_node
=
parse_bin_node
(
object
,
dict_size
,
&
object
);
default:
/* made to hold raw data. */
if
(
plist_get_node_type
(
size_node
)
!=
PLIST_UINT
)
modifier
=
(
data
->
ref_size
>
0
)
?
data
->
ref_size
:
1
;
return
NULL
;
data
->
buff
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
data
->
length
*
modifier
));
size
=
plist_get_node_uint_val
(
size_node
);
memcpy
(
data
->
buff
,
bpbuffer
+
myPos
,
(
data
->
length
*
modifier
));
}
return
parse_data_node
(
object
,
size
,
dict_size
);
case
BPLIST_STRING
:
if
(
0x0F
==
size
)
{
plist_t
size_node
=
parse_bin_node
(
object
,
dict_size
,
&
object
);
if
(
plist_get_node_type
(
size_node
)
!=
PLIST_UINT
)
return
NULL
;
size
=
plist_get_node_uint_val
(
size_node
);
}
return
parse_string_node
(
object
,
size
);
case
BPLIST_UNICODE
:
if
(
0x0F
==
size
)
{
plist_t
size_node
=
parse_bin_node
(
object
,
dict_size
,
&
object
);
if
(
plist_get_node_type
(
size_node
)
!=
PLIST_UINT
)
return
NULL
;
size
=
plist_get_node_uint_val
(
size_node
);
}
return
parse_unicode_node
(
object
,
size
);
case
BPLIST_UID
:
case
BPLIST_ARRAY
:
if
(
0x0F
==
size
)
{
plist_t
size_node
=
parse_bin_node
(
object
,
dict_size
,
&
object
);
if
(
plist_get_node_type
(
size_node
)
!=
PLIST_UINT
)
return
NULL
;
size
=
plist_get_node_uint_val
(
size_node
);
}
return
parse_array_node
(
object
,
size
,
dict_size
);
case
BPLIST_SET
:
case
BPLIST_DICT
:
if
(
0x0F
==
size
)
{
plist_t
size_node
=
parse_bin_node
(
object
,
dict_size
,
&
object
);
if
(
plist_get_node_type
(
size_node
)
!=
PLIST_UINT
)
return
NULL
;
object
++
;
size
=
plist_get_node_uint_val
(
size_node
);
}
return
parse_dict_node
(
object
,
size
,
dict_size
);
}
return
NULL
;
}
void
plist_to_bin
(
plist_t
plist
,
char
**
plist_bin
,
uint32_t
*
length
)
{
uint64_t
num_objects
=
g_node_n_nodes
(
plist
,
G_TRAVERSE_ALL
);
}
gpointer
copy_plist_data
(
gconstpointer
src
,
gpointer
data
)
{
struct
plist_data
*
srcdata
=
(
struct
plist_data
*
)
src
;
struct
plist_data
*
dstdata
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
dstdata
->
type
=
srcdata
->
type
;
dstdata
->
length
=
srcdata
->
length
;
switch
(
dstdata
->
type
)
{
case
PLIST_BOOLEAN
:
dstdata
->
boolval
=
srcdata
->
boolval
;
break
;
case
PLIST_UINT
:
dstdata
->
intval
=
srcdata
->
intval
;
break
;
case
PLIST_DATE
:
case
PLIST_REAL
:
dstdata
->
realval
=
srcdata
->
realval
;
break
;
case
PLIST_KEY
:
case
PLIST_STRING
:
dstdata
->
strval
=
strdup
(
srcdata
->
strval
);
break
;
case
PLIST_UNICODE
:
dstdata
->
unicodeval
=
wcsdup
(
srcdata
->
unicodeval
);
break
;
case
PLIST_PLIST
:
case
PLIST_DATA
:
case
PLIST_ARRAY
:
case
PLIST_DICT
:
dstdata
->
buff
=
(
char
*
)
malloc
(
sizeof
(
char
*
)
*
srcdata
->
length
);
memcpy
(
dstdata
->
buff
,
srcdata
->
buff
,
sizeof
(
char
*
)
*
srcdata
->
length
);
break
;
break
;
default:
break
;
}
}
myPos
+=
data
->
length
;
return
dstdata
;
*
position
=
myPos
;
return
new_node
;
}
}
plist_t
parse_nodes
(
const
char
*
bpbuffer
,
uint32_t
bplength
,
uint32_t
*
position
)
void
bin_to_plist
(
const
char
*
plist_bin
,
uint32_t
length
,
plist_t
*
plist
)
{
{
plist_t
*
nodeslist
=
NULL
,
*
newaddr
=
NULL
;
//first check we have enough data
plist_t
new_node
=
NULL
,
root_node
=
NULL
;
if
(
!
(
length
>=
BPLIST_MAGIC_SIZE
+
BPLIST_VERSION_SIZE
+
BPLIST_TRL_SIZE
))
return
;
//check that plist_bin in actually a plist
if
(
memcmp
(
plist_bin
,
BPLIST_MAGIC
,
BPLIST_MAGIC_SIZE
)
!=
0
)
return
;
//check for known version
if
(
memcmp
(
plist_bin
+
BPLIST_MAGIC_SIZE
,
BPLIST_VERSION
,
BPLIST_VERSION_SIZE
)
!=
0
)
return
;
uint32_t
nodeslength
=
0
;
//now parse trailer
uint8_t
offset_size
=
0
,
dict_param_size
=
0
;
const
char
*
trailer
=
plist_bin
+
(
length
-
BPLIST_TRL_SIZE
);
offset_size
=
bpbuffer
[
bplength
-
26
];
dict_param_size
=
bpbuffer
[
bplength
-
25
];
uint8_t
offset_size
=
trailer
[
BPLIST_TRL_OFFSIZE_IDX
];
uint64_t
current_offset
=
0
;
uint8_t
dict_param_size
=
trailer
[
BPLIST_TRL_PARMSIZE_IDX
];
uint64_t
num_objects
=
0
,
root_object
=
0
,
offset_table_index
=
0
;
uint64_t
num_objects
=
be64dec
(
trailer
+
BPLIST_TRL_NUMOBJ_IDX
);
memcpy
(
&
num_objects
,
bpbuffer
+
bplength
-
24
,
sizeof
(
uint64_t
));
uint64_t
root_object
=
be64dec
(
trailer
+
BPLIST_TRL_ROOTOBJ_IDX
);
memcpy
(
&
root_object
,
bpbuffer
+
bplength
-
16
,
sizeof
(
uint64_t
));
uint64_t
offset_table_index
=
be64dec
(
trailer
+
BPLIST_TRL_OFFTAB_IDX
);
memcpy
(
&
offset_table_index
,
bpbuffer
+
bplength
-
8
,
sizeof
(
uint64_t
));
byte_convert
((
char
*
)
&
num_objects
,
sizeof
(
uint64_t
));
byte_convert
((
char
*
)
&
root_object
,
sizeof
(
uint64_t
));
byte_convert
((
char
*
)
&
offset_table_index
,
sizeof
(
uint64_t
));
log_debug_msg
(
"Offset size: %i
\n
Given: %i
\n
"
,
offset_size
,
bpbuffer
[
bplength
-
26
]);
log_debug_msg
(
"Ref size: %i
\n
Given: %i
\n
"
,
dict_param_size
,
bpbuffer
[
bplength
-
25
]);
log_debug_msg
(
"Number of objects: %lli
\n
Given: %llu
\n
"
,
num_objects
,
*
(
bpbuffer
+
bplength
-
24
));
log_debug_msg
(
"Root object index: %lli
\n
Given: %llu
\n
"
,
root_object
,
*
(
bpbuffer
+
bplength
-
16
));
log_debug_msg
(
"Offset table index: %lli
\n
Given: %llu
\n
"
,
offset_table_index
,
*
(
bpbuffer
+
bplength
-
8
));
log_debug_msg
(
"Size of uint64: %i
\n
"
,
sizeof
(
uint64_t
));
int
i
=
0
,
j
=
0
,
k
=
0
,
str_i
=
0
,
str_j
=
0
;
uint32_t
index1
=
0
,
index2
=
0
;
log_debug_msg
(
"Offset size: %i
\n
"
,
offset_size
);
log_debug_msg
(
"Ref size: %i
\n
"
,
dict_param_size
);
log_debug_msg
(
"Number of objects: %lli
\n
"
,
num_objects
);
log_debug_msg
(
"Root object index: %lli
\n
"
,
root_object
);
log_debug_msg
(
"Offset table index: %lli
\n
"
,
offset_table_index
);
if
(
num_objects
==
0
)
return
;
//allocate serialized array of nodes
plist_t
*
nodeslist
=
NULL
;
nodeslist
=
(
plist_t
*
)
malloc
(
sizeof
(
plist_t
)
*
num_objects
);
nodeslist
=
(
plist_t
*
)
malloc
(
sizeof
(
plist_t
)
*
num_objects
);
if
(
!
nodeslist
)
if
(
!
nodeslist
)
return
NULL
;
return
;
//parse serialized nodes
uint64_t
i
=
0
;
uint64_t
current_offset
=
0
;
const
char
*
offset_table
=
plist_bin
+
offset_table_index
;
for
(
i
=
0
;
i
<
num_objects
;
i
++
)
{
for
(
i
=
0
;
i
<
num_objects
;
i
++
)
{
memcpy
(
&
current_offset
,
bpbuffer
+
(
offset_table_index
+
(
i
*
offset_size
))
,
offset_size
);
current_offset
=
swap_n_bytes
(
offset_table
+
i
*
offset_size
,
offset_size
);
byte_convert
((
char
*
)
&
current_offset
,
(
offset_size
<=
sizeof
(
current_offset
))
?
offset_size
:
sizeof
(
current_offset
)
);
log_debug_msg
(
"parse_nodes: current_offset = %i
\n
"
,
current_offset
);
log_debug_msg
(
"parse_nodes: current_offset = %x
\n
"
,
current_offset
)
;
char
*
obj
=
plist_bin
+
current_offset
;
nodeslist
[
i
]
=
parse_
raw_node
(
bpbuffer
,
bplength
,
(
uint32_t
*
)
&
current_offset
,
dict_param_size
);
nodeslist
[
i
]
=
parse_
bin_node
(
obj
,
dict_param_size
,
&
obj
);
log_debug_msg
(
"parse_nodes: parse_raw_node done
\n
"
);
log_debug_msg
(
"parse_nodes: parse_raw_node done
\n
"
);
}
}
//setup children for structured types
int
j
=
0
,
str_i
=
0
,
str_j
=
0
;
uint32_t
index1
=
0
,
index2
=
0
;
for
(
i
=
0
;
i
<
num_objects
;
i
++
)
{
for
(
i
=
0
;
i
<
num_objects
;
i
++
)
{
// set elements for dicts and arrays and leave the rest alone
log_debug_msg
(
"parse_nodes: on node %i
\n
"
,
i
);
log_debug_msg
(
"parse_nodes: on node %i
\n
"
,
i
);
struct
plist_data
*
data
=
(
struct
plist_data
*
)
nodeslist
[
i
]
->
data
;
struct
plist_data
*
data
=
(
struct
plist_data
*
)
nodeslist
[
i
]
->
data
;
switch
(
data
->
type
)
{
switch
(
data
->
type
)
{
case
PLIST_DICT
:
case
PLIST_DICT
:
log_debug_msg
(
"parse_nodes: dictionary found
\n
"
);
log_debug_msg
(
"parse_nodes: dictionary found
\n
"
);
for
(
j
=
0
;
j
<
(
data
->
length
/
2
)
;
j
++
)
{
for
(
j
=
0
;
j
<
data
->
length
;
j
++
)
{
str_i
=
j
*
d
ata
->
ref
_size
;
str_i
=
j
*
d
ict_param
_size
;
str_j
=
(
j
+
(
data
->
length
/
2
))
*
data
->
ref
_size
;
str_j
=
(
j
+
data
->
length
)
*
dict_param
_size
;
memcpy
(
&
index1
,
data
->
buff
+
str_i
,
data
->
ref
_size
);
index1
=
swap_n_bytes
(
data
->
buff
+
str_i
,
dict_param
_size
);
memcpy
(
&
index2
,
data
->
buff
+
str_j
,
data
->
ref
_size
);
index2
=
swap_n_bytes
(
data
->
buff
+
str_j
,
dict_param
_size
);
byte_convert
((
char
*
)
&
index1
,
(
dict_param_size
<=
sizeof
(
index1
))
?
dict_param_size
:
sizeof
(
index2
));
//first one is actually a key
byte_convert
((
char
*
)
&
index2
,
(
dict_param_size
<=
sizeof
(
index2
))
?
dict_param_size
:
sizeof
(
index2
));
((
struct
plist_data
*
)
nodeslist
[
index1
]
->
data
)
->
type
=
PLIST_KEY
;
//g_node_append(nodeslist[i], nodeslist[index1]);
//g_node_append(nodeslist[i], nodeslist[index2]);
if
(
G_NODE_IS_ROOT
(
nodeslist
[
index1
]))
g_node_append
(
nodeslist
[
i
],
nodeslist
[
index1
]);
g_node_append
(
nodeslist
[
i
],
nodeslist
[
index1
]);
else
g_node_append
(
nodeslist
[
i
],
g_node_copy_deep
(
nodeslist
[
index1
],
copy_plist_data
,
NULL
));
if
(
G_NODE_IS_ROOT
(
nodeslist
[
index2
]))
g_node_append
(
nodeslist
[
i
],
nodeslist
[
index2
]);
g_node_append
(
nodeslist
[
i
],
nodeslist
[
index2
]);
else
g_node_append
(
nodeslist
[
i
],
g_node_copy_deep
(
nodeslist
[
index2
],
copy_plist_data
,
NULL
));
}
}
data
->
length
=
data
->
length
/
2
;
free
(
data
->
buff
);
free
(
data
->
buff
);
k
=
0
;
break
;
break
;
case
PLIST_ARRAY
:
case
PLIST_ARRAY
:
log_debug_msg
(
"parse_nodes: array found
\n
"
);
log_debug_msg
(
"parse_nodes: array found
\n
"
);
for
(
j
=
0
;
j
<
data
->
length
;
j
++
)
{
for
(
j
=
0
;
j
<
data
->
length
;
j
++
)
{
log_debug_msg
(
"parse_nodes: array index %i
\n
"
,
j
);
str_j
=
j
*
dict_param_size
;
str_j
=
j
*
data
->
ref_size
;
index1
=
swap_n_bytes
(
data
->
buff
+
str_j
,
dict_param_size
);
memcpy
(
&
index1
,
data
->
buff
+
str_j
,
data
->
ref_size
);
log_debug_msg
(
"parse_nodes: post-memcpy
\n
"
);
//g_node_append(nodeslist[i], nodeslist[index1]);
byte_convert
((
char
*
)
&
index1
,
(
dict_param_size
<=
sizeof
(
index1
))
?
dict_param_size
:
sizeof
(
index1
));
if
(
G_NODE_IS_ROOT
(
nodeslist
[
index1
]))
log_debug_msg
(
"parse_nodes: post-ntohl
\n
index1 = %i
\n
"
,
index1
);
g_node_append
(
nodeslist
[
i
],
nodeslist
[
index1
]);
g_node_append
(
nodeslist
[
i
],
nodeslist
[
index1
]);
log_debug_msg
(
"parse_nodes: post-assignment
\n
"
);
else
g_node_append
(
nodeslist
[
i
],
g_node_copy_deep
(
nodeslist
[
index1
],
copy_plist_data
,
NULL
));
}
}
free
(
data
->
buff
);
free
(
data
->
buff
);
break
;
break
;
default:
default:
//printf("lol... type %x\n", nodeslist[i]->type);
break
;
break
;
}
// those are the only two we need to correct for.
}
}
}
root_node
=
nodeslist
[
root_object
];
*
plist
=
nodeslist
[
root_object
];
return
root_node
;
}
void
plist_to_bin
(
plist_t
plist
,
char
**
plist_bin
,
uint32_t
*
length
)
{
}
void
xml_to_plist
(
const
char
*
plist_xml
,
uint32_t
length
,
plist_t
*
plist
)
{
xmlDocPtr
plist_doc
=
xmlReadMemory
(
plist_xml
,
length
,
NULL
,
NULL
,
0
);
xmlNodePtr
root_node
=
xmlDocGetRootElement
(
plist_doc
);
struct
plist_data
*
data
=
(
struct
plist_data
*
)
calloc
(
sizeof
(
struct
plist_data
),
1
);
*
plist
=
g_node_new
(
data
);
data
->
type
=
PLIST_PLIST
;
xml_to_node
(
root_node
,
*
plist
);
}
void
bin_to_plist
(
const
char
*
plist_bin
,
uint32_t
length
,
plist_t
*
plist
)
{
uint32_t
pos
=
0
;
*
plist
=
parse_nodes
(
plist_bin
,
length
,
&
pos
);
}
}
...
@@ -816,23 +928,11 @@ char compare_node_value(plist_type type, struct plist_data *data, void *value)
...
@@ -816,23 +928,11 @@ char compare_node_value(plist_type type, struct plist_data *data, void *value)
case
PLIST_BOOLEAN
:
case
PLIST_BOOLEAN
:
res
=
data
->
boolval
==
*
((
char
*
)
value
)
?
TRUE
:
FALSE
;
res
=
data
->
boolval
==
*
((
char
*
)
value
)
?
TRUE
:
FALSE
;
break
;
break
;
case
PLIST_UINT8
:
case
PLIST_UINT
:
res
=
data
->
intval8
==
*
((
uint8_t
*
)
value
)
?
TRUE
:
FALSE
;
res
=
data
->
intval
==
*
((
uint64_t
*
)
value
)
?
TRUE
:
FALSE
;
break
;
case
PLIST_UINT16
:
res
=
data
->
intval16
==
*
((
uint16_t
*
)
value
)
?
TRUE
:
FALSE
;
break
;
case
PLIST_UINT32
:
res
=
data
->
intval32
==
*
((
uint32_t
*
)
value
)
?
TRUE
:
FALSE
;
break
;
case
PLIST_UINT64
:
res
=
data
->
intval64
==
*
((
uint64_t
*
)
value
)
?
TRUE
:
FALSE
;
break
;
break
;
case
PLIST_FLOAT32
:
case
PLIST_REAL
:
res
=
data
->
realval32
==
*
((
float
*
)
value
)
?
TRUE
:
FALSE
;
res
=
data
->
realval
==
*
((
double
*
)
value
)
?
TRUE
:
FALSE
;
break
;
case
PLIST_FLOAT64
:
res
=
data
->
realval64
==
*
((
double
*
)
value
)
?
TRUE
:
FALSE
;
break
;
break
;
case
PLIST_KEY
:
case
PLIST_KEY
:
case
PLIST_STRING
:
case
PLIST_STRING
:
...
@@ -889,23 +989,11 @@ void get_type_and_value(GNode * node, plist_type * type, void *value)
...
@@ -889,23 +989,11 @@ void get_type_and_value(GNode * node, plist_type * type, void *value)
case
PLIST_BOOLEAN
:
case
PLIST_BOOLEAN
:
*
((
char
*
)
value
)
=
data
->
boolval
;
*
((
char
*
)
value
)
=
data
->
boolval
;
break
;
break
;
case
PLIST_UINT8
:
case
PLIST_UINT
:
*
((
uint8_t
*
)
value
)
=
data
->
intval8
;
*
((
uint64_t
*
)
value
)
=
data
->
intval
;
break
;
case
PLIST_UINT16
:
*
((
uint16_t
*
)
value
)
=
data
->
intval16
;
break
;
case
PLIST_UINT32
:
*
((
uint32_t
*
)
value
)
=
data
->
intval32
;
break
;
case
PLIST_UINT64
:
*
((
uint64_t
*
)
value
)
=
data
->
intval64
;
break
;
case
PLIST_FLOAT32
:
*
((
float
*
)
value
)
=
data
->
realval32
;
break
;
break
;
case
PLIST_
FLOAT64
:
case
PLIST_
REAL
:
*
((
double
*
)
value
)
=
data
->
realval
64
;
*
((
double
*
)
value
)
=
data
->
realval
;
break
;
break
;
case
PLIST_STRING
:
case
PLIST_STRING
:
*
((
char
**
)
value
)
=
strdup
(
data
->
strval
);
*
((
char
**
)
value
)
=
strdup
(
data
->
strval
);
...
...
src/plist.h
View file @
1a06347d
...
@@ -35,7 +35,7 @@ char *format_string(const char *buf, int cols, int depth);
...
@@ -35,7 +35,7 @@ char *format_string(const char *buf, int cols, int depth);
/* Binary plist stuff */
/* Binary plist stuff */
/*
typedef enum {
typedef enum {
PLIST_BOOLEAN,
PLIST_BOOLEAN,
PLIST_UINT8,
PLIST_UINT8,
...
@@ -53,6 +53,22 @@ typedef enum {
...
@@ -53,6 +53,22 @@ typedef enum {
PLIST_PLIST,
PLIST_PLIST,
PLIST_KEY,
PLIST_KEY,
} plist_type;
} plist_type;
*/
typedef
enum
{
PLIST_BOOLEAN
,
PLIST_UINT
,
PLIST_REAL
,
PLIST_STRING
,
PLIST_UNICODE
,
PLIST_ARRAY
,
PLIST_DICT
,
PLIST_DATE
,
PLIST_DATA
,
PLIST_PLIST
,
PLIST_KEY
,
}
plist_type
;
typedef
GNode
*
plist_t
;
typedef
GNode
*
plist_t
;
...
...
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