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
ac3be565
Commit
ac3be565
authored
Dec 14, 2018
by
Nikias Bassen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
xplist: Improve memory usage by estimating output buffer size
parent
3007c970
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
128 additions
and
3 deletions
+128
-3
strbuf.h
src/strbuf.h
+1
-1
xplist.c
src/xplist.c
+127
-2
No files found.
src/strbuf.h
View file @
ac3be565
...
@@ -26,7 +26,7 @@
...
@@ -26,7 +26,7 @@
typedef
struct
bytearray_t
strbuf_t
;
typedef
struct
bytearray_t
strbuf_t
;
#define str_buf_new(
) byte_array_new(32768
)
#define str_buf_new(
__sz) byte_array_new(__sz
)
#define str_buf_free(__ba) byte_array_free(__ba)
#define str_buf_free(__ba) byte_array_free(__ba)
#define str_buf_grow(__ba, __am) byte_array_grow(__ba, __am)
#define str_buf_grow(__ba, __am) byte_array_grow(__ba, __am)
#define str_buf_append(__ba, __str, __len) byte_array_append(__ba, (void*)(__str), __len)
#define str_buf_append(__ba, __str, __len) byte_array_append(__ba, (void*)(__str), __len)
...
...
src/xplist.c
View file @
ac3be565
...
@@ -37,6 +37,7 @@
...
@@ -37,6 +37,7 @@
#include <inttypes.h>
#include <inttypes.h>
#include <math.h>
#include <math.h>
#include <limits.h>
#include <node.h>
#include <node.h>
#include <node_list.h>
#include <node_list.h>
...
@@ -69,6 +70,8 @@
...
@@ -69,6 +70,8 @@
#define MAC_EPOCH 978307200
#define MAC_EPOCH 978307200
#define MAX_DATA_BYTES_PER_LINE(__i) (((76 - (__i << 3)) >> 2) * 3)
static
const
char
XML_PLIST_PROLOG
[]
=
"<?xml version=
\"
1.0
\"
encoding=
\"
UTF-8
\"
?>
\n
\
static
const
char
XML_PLIST_PROLOG
[]
=
"<?xml version=
\"
1.0
\"
encoding=
\"
UTF-8
\"
?>
\n
\
<!DOCTYPE plist PUBLIC
\"
-//Apple//DTD PLIST 1.0//EN
\"
\"
http://www.apple.com/DTDs/PropertyList-1.0.dtd
\"
>
\n
\
<!DOCTYPE plist PUBLIC
\"
-//Apple//DTD PLIST 1.0//EN
\"
\"
http://www.apple.com/DTDs/PropertyList-1.0.dtd
\"
>
\n
\
<plist version=
\"
1.0
\"
>
\n
"
;
<plist version=
\"
1.0
\"
>
\n
"
;
...
@@ -290,7 +293,7 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
...
@@ -290,7 +293,7 @@ static void node_to_xml(node_t* node, bytearray_t **outbuf, uint32_t depth)
char
*
buf
=
malloc
(
80
);
char
*
buf
=
malloc
(
80
);
uint32_t
j
=
0
;
uint32_t
j
=
0
;
uint32_t
indent
=
(
depth
>
8
)
?
8
:
depth
;
uint32_t
indent
=
(
depth
>
8
)
?
8
:
depth
;
uint32_t
maxread
=
((
76
-
indent
*
8
)
/
4
)
*
3
;
uint32_t
maxread
=
MAX_DATA_BYTES_PER_LINE
(
indent
)
;
size_t
count
=
0
;
size_t
count
=
0
;
size_t
b64count
=
0
;
size_t
b64count
=
0
;
size_t
amount
=
(
node_data
->
length
/
3
*
4
)
+
4
+
(((
node_data
->
length
/
maxread
)
+
1
)
*
(
indent
+
1
));
size_t
amount
=
(
node_data
->
length
/
3
*
4
)
+
4
+
(((
node_data
->
length
/
maxread
)
+
1
)
*
(
indent
+
1
));
...
@@ -400,9 +403,131 @@ static void parse_date(const char *strval, struct TM *btime)
...
@@ -400,9 +403,131 @@ static void parse_date(const char *strval, struct TM *btime)
btime
->
tm_isdst
=
0
;
btime
->
tm_isdst
=
0
;
}
}
#define PO10i_LIMIT (INT64_MAX/10)
/* based on https://stackoverflow.com/a/4143288 */
static
int
num_digits_i
(
int64_t
i
)
{
int
n
;
int64_t
po10
;
n
=
1
;
if
(
i
<
0
)
{
i
=
-
i
;
n
++
;
}
po10
=
10
;
while
(
i
>=
po10
)
{
n
++
;
if
(
po10
>
PO10i_LIMIT
)
break
;
po10
*=
10
;
}
return
n
;
}
#define PO10u_LIMIT (UINT64_MAX/10)
/* based on https://stackoverflow.com/a/4143288 */
static
int
num_digits_u
(
uint64_t
i
)
{
int
n
;
uint64_t
po10
;
n
=
1
;
po10
=
10
;
while
(
i
>=
po10
)
{
n
++
;
if
(
po10
>
PO10u_LIMIT
)
break
;
po10
*=
10
;
}
return
n
;
}
static
void
node_estimate_size
(
node_t
*
node
,
uint64_t
*
size
,
uint32_t
depth
)
{
plist_data_t
data
;
if
(
!
node
)
{
return
;
}
data
=
plist_get_data
(
node
);
if
(
node
->
children
)
{
node_t
*
ch
;
for
(
ch
=
node_first_child
(
node
);
ch
;
ch
=
node_next_sibling
(
ch
))
{
node_estimate_size
(
ch
,
size
,
depth
+
1
);
}
switch
(
data
->
type
)
{
case
PLIST_DICT
:
*
size
+=
(
XPLIST_DICT_LEN
<<
1
)
+
7
;
break
;
case
PLIST_ARRAY
:
*
size
+=
(
XPLIST_ARRAY_LEN
<<
1
)
+
7
;
break
;
default:
break
;
}
*
size
+=
(
depth
<<
1
);
}
else
{
uint32_t
indent
=
(
depth
>
8
)
?
8
:
depth
;
switch
(
data
->
type
)
{
case
PLIST_DATA
:
{
uint32_t
req_lines
=
(
data
->
length
/
MAX_DATA_BYTES_PER_LINE
(
indent
))
+
1
;
uint32_t
b64len
=
data
->
length
+
(
data
->
length
/
3
);
b64len
+=
b64len
%
4
;
*
size
+=
b64len
;
*
size
+=
(
XPLIST_DATA_LEN
<<
1
)
+
5
+
(
indent
+
1
)
*
(
req_lines
+
1
)
+
1
;
}
break
;
case
PLIST_STRING
:
*
size
+=
data
->
length
;
*
size
+=
(
XPLIST_STRING_LEN
<<
1
)
+
6
;
break
;
case
PLIST_KEY
:
*
size
+=
data
->
length
;
*
size
+=
(
XPLIST_KEY_LEN
<<
1
)
+
6
;
break
;
case
PLIST_UINT
:
if
(
data
->
length
==
16
)
{
*
size
+=
num_digits_u
(
data
->
intval
);
}
else
{
*
size
+=
num_digits_i
((
int64_t
)
data
->
intval
);
}
*
size
+=
(
XPLIST_INT_LEN
<<
1
)
+
6
;
break
;
case
PLIST_REAL
:
*
size
+=
num_digits_i
((
int64_t
)
data
->
realval
)
+
7
;
*
size
+=
(
XPLIST_REAL_LEN
<<
1
)
+
6
;
break
;
case
PLIST_DATE
:
*
size
+=
20
;
/* YYYY-MM-DDThh:mm:ssZ */
*
size
+=
(
XPLIST_DATE_LEN
<<
1
)
+
6
;
break
;
case
PLIST_BOOLEAN
:
*
size
+=
((
data
->
boolval
)
?
XPLIST_TRUE_LEN
:
XPLIST_FALSE_LEN
)
+
4
;
break
;
case
PLIST_DICT
:
*
size
+=
XPLIST_DICT_LEN
+
4
;
/* <dict/> */
break
;
case
PLIST_ARRAY
:
*
size
+=
XPLIST_ARRAY_LEN
+
4
;
/* <array/> */
break
;
case
PLIST_UID
:
*
size
+=
num_digits_i
((
int64_t
)
data
->
intval
);
*
size
+=
(
XPLIST_DICT_LEN
<<
1
)
+
7
;
*
size
+=
indent
+
((
indent
+
1
)
<<
1
);
*
size
+=
18
;
/* <key>CF$UID</key> */
*
size
+=
(
XPLIST_INT_LEN
<<
1
)
+
6
;
break
;
default:
break
;
}
*
size
+=
indent
;
}
}
PLIST_API
void
plist_to_xml
(
plist_t
plist
,
char
**
plist_xml
,
uint32_t
*
length
)
PLIST_API
void
plist_to_xml
(
plist_t
plist
,
char
**
plist_xml
,
uint32_t
*
length
)
{
{
strbuf_t
*
outbuf
=
str_buf_new
();
uint64_t
size
=
0
;
node_estimate_size
(
plist
,
&
size
,
0
);
size
+=
sizeof
(
XML_PLIST_PROLOG
)
+
sizeof
(
XML_PLIST_EPILOG
)
-
1
;
strbuf_t
*
outbuf
=
str_buf_new
(
size
);
str_buf_append
(
outbuf
,
XML_PLIST_PROLOG
,
sizeof
(
XML_PLIST_PROLOG
)
-
1
);
str_buf_append
(
outbuf
,
XML_PLIST_PROLOG
,
sizeof
(
XML_PLIST_PROLOG
)
-
1
);
...
...
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