Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
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
lvzhengyang
git2
Commits
f5f04826
Commit
f5f04826
authored
Nov 30, 2011
by
Vicent Martí
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #503 from arrbee/git-buf-always-cstr
Make git_buf functions always maintain a valid cstr
parents
fc88a8d3
309113c9
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
111 additions
and
49 deletions
+111
-49
src/buffer.c
+78
-38
src/buffer.h
+5
-1
tests-clay/core/buffer.c
+28
-10
No files found.
src/buffer.c
View file @
f5f04826
...
...
@@ -8,13 +8,29 @@
#include "posix.h"
#include <stdarg.h>
/* Used as default value for git_buf->ptr so that people can always
* assume ptr is non-NULL and zero terminated even for new git_bufs.
*/
char
git_buf_initbuf
[
1
];
#define ENSURE_SIZE(b, d) \
if ((ssize_t)(d) > buf->asize && git_buf_grow(b, (d)) < GIT_SUCCESS)\
return;
void
git_buf_init
(
git_buf
*
buf
,
size_t
initial_size
)
{
buf
->
asize
=
0
;
buf
->
size
=
0
;
buf
->
ptr
=
git_buf_initbuf
;
if
(
initial_size
)
git_buf_grow
(
buf
,
initial_size
);
}
int
git_buf_grow
(
git_buf
*
buf
,
size_t
target_size
)
{
char
*
new_ptr
;
size_t
new_size
;
if
(
buf
->
asize
<
0
)
return
GIT_ENOMEM
;
...
...
@@ -22,27 +38,56 @@ int git_buf_grow(git_buf *buf, size_t target_size)
if
(
target_size
<=
(
size_t
)
buf
->
asize
)
return
GIT_SUCCESS
;
if
(
buf
->
asize
==
0
)
buf
->
asize
=
target_size
;
if
(
buf
->
asize
==
0
)
{
new_size
=
target_size
;
new_ptr
=
NULL
;
}
else
{
new_size
=
(
size_t
)
buf
->
asize
;
new_ptr
=
buf
->
ptr
;
}
/* grow the buffer size by 1.5, until it's big enough
* to fit our target size */
while
(
buf
->
asize
<
(
int
)
target_size
)
buf
->
asize
=
(
buf
->
asize
<<
1
)
-
(
buf
->
a
size
>>
1
);
while
(
new_size
<
target_size
)
new_size
=
(
new_size
<<
1
)
-
(
new_
size
>>
1
);
/* round allocation up to multiple of 8 */
buf
->
asize
=
(
buf
->
a
size
+
7
)
&
~
7
;
new_size
=
(
new_
size
+
7
)
&
~
7
;
new_ptr
=
git__realloc
(
buf
->
ptr
,
buf
->
a
size
);
new_ptr
=
git__realloc
(
new_ptr
,
new_
size
);
if
(
!
new_ptr
)
{
buf
->
asize
=
-
1
;
return
GIT_ENOMEM
;
}
buf
->
asize
=
new_size
;
buf
->
ptr
=
new_ptr
;
/* truncate the existing buffer size if necessary */
if
(
buf
->
size
>=
buf
->
asize
)
buf
->
size
=
buf
->
asize
-
1
;
buf
->
ptr
[
buf
->
size
]
=
'\0'
;
return
GIT_SUCCESS
;
}
void
git_buf_free
(
git_buf
*
buf
)
{
if
(
!
buf
)
return
;
if
(
buf
->
ptr
!=
git_buf_initbuf
)
git__free
(
buf
->
ptr
);
git_buf_init
(
buf
,
0
);
}
void
git_buf_clear
(
git_buf
*
buf
)
{
buf
->
size
=
0
;
if
(
buf
->
asize
>
0
)
buf
->
ptr
[
0
]
=
'\0'
;
}
int
git_buf_oom
(
const
git_buf
*
buf
)
{
return
(
buf
->
asize
<
0
);
...
...
@@ -53,9 +98,10 @@ void git_buf_set(git_buf *buf, const char *data, size_t len)
if
(
len
==
0
||
data
==
NULL
)
{
git_buf_clear
(
buf
);
}
else
{
ENSURE_SIZE
(
buf
,
len
);
ENSURE_SIZE
(
buf
,
len
+
1
);
memmove
(
buf
->
ptr
,
data
,
len
);
buf
->
size
=
len
;
buf
->
ptr
[
buf
->
size
]
=
'\0'
;
}
}
...
...
@@ -66,15 +112,17 @@ void git_buf_sets(git_buf *buf, const char *string)
void
git_buf_putc
(
git_buf
*
buf
,
char
c
)
{
ENSURE_SIZE
(
buf
,
buf
->
size
+
1
);
ENSURE_SIZE
(
buf
,
buf
->
size
+
2
);
buf
->
ptr
[
buf
->
size
++
]
=
c
;
buf
->
ptr
[
buf
->
size
]
=
'\0'
;
}
void
git_buf_put
(
git_buf
*
buf
,
const
char
*
data
,
size_t
len
)
{
ENSURE_SIZE
(
buf
,
buf
->
size
+
len
);
ENSURE_SIZE
(
buf
,
buf
->
size
+
len
+
1
);
memmove
(
buf
->
ptr
+
buf
->
size
,
data
,
len
);
buf
->
size
+=
len
;
buf
->
ptr
[
buf
->
size
]
=
'\0'
;
}
void
git_buf_puts
(
git_buf
*
buf
,
const
char
*
string
)
...
...
@@ -111,27 +159,25 @@ void git_buf_printf(git_buf *buf, const char *format, ...)
const
char
*
git_buf_cstr
(
git_buf
*
buf
)
{
if
(
buf
->
size
+
1
>
buf
->
asize
&&
git_buf_grow
(
buf
,
buf
->
size
+
1
)
<
GIT_SUCCESS
)
return
NULL
;
buf
->
ptr
[
buf
->
size
]
=
'\0'
;
return
buf
->
ptr
;
}
void
git_buf_
free
(
git_buf
*
buf
)
void
git_buf_
copy_cstr
(
char
*
data
,
size_t
datasize
,
git_buf
*
buf
)
{
if
(
!
buf
)
retur
n
;
size_t
copyle
n
;
git__free
(
buf
->
ptr
);
buf
->
ptr
=
NULL
;
buf
->
asize
=
0
;
buf
->
size
=
0
;
}
assert
(
data
&&
datasize
);
void
git_buf_clear
(
git_buf
*
buf
)
{
buf
->
size
=
0
;
data
[
0
]
=
'\0'
;
if
(
buf
->
size
==
0
||
buf
->
asize
<=
0
)
return
;
copylen
=
buf
->
size
;
if
(
copylen
>
datasize
-
1
)
copylen
=
datasize
-
1
;
memmove
(
data
,
buf
->
ptr
,
copylen
);
data
[
copylen
]
=
'\0'
;
}
void
git_buf_consume
(
git_buf
*
buf
,
const
char
*
end
)
...
...
@@ -140,6 +186,7 @@ void git_buf_consume(git_buf *buf, const char *end)
size_t
consumed
=
end
-
buf
->
ptr
;
memmove
(
buf
->
ptr
,
end
,
buf
->
size
-
consumed
);
buf
->
size
-=
consumed
;
buf
->
ptr
[
buf
->
size
]
=
'\0'
;
}
}
...
...
@@ -152,21 +199,12 @@ void git_buf_swap(git_buf *buf_a, git_buf *buf_b)
char
*
git_buf_take_cstr
(
git_buf
*
buf
)
{
char
*
data
=
NULL
;
char
*
data
=
buf
->
ptr
;
if
(
buf
->
ptr
==
NULL
)
if
(
buf
->
asize
<=
0
)
return
NULL
;
if
(
buf
->
size
+
1
>
buf
->
asize
&&
git_buf_grow
(
buf
,
buf
->
size
+
1
)
<
GIT_SUCCESS
)
return
NULL
;
data
=
buf
->
ptr
;
data
[
buf
->
size
]
=
'\0'
;
buf
->
ptr
=
NULL
;
buf
->
asize
=
0
;
buf
->
size
=
0
;
git_buf_init
(
buf
,
0
);
return
data
;
}
...
...
@@ -199,7 +237,7 @@ void git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
}
va_end
(
ap
);
ENSURE_SIZE
(
buf
,
buf
->
size
+
total_size
);
ENSURE_SIZE
(
buf
,
buf
->
size
+
total_size
+
1
);
out
=
buf
->
ptr
+
buf
->
size
;
...
...
@@ -235,6 +273,7 @@ void git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
/* set size based on num characters actually written */
buf
->
size
=
out
-
buf
->
ptr
;
buf
->
ptr
[
buf
->
size
]
=
'\0'
;
}
void
git_buf_join
(
...
...
@@ -277,7 +316,7 @@ void git_buf_join(
if
(
!
add_size
)
return
;
ENSURE_SIZE
(
buf
,
buf
->
size
+
add_size
);
ENSURE_SIZE
(
buf
,
buf
->
size
+
add_size
+
1
);
/* concatenate strings */
ptr
=
buf
->
ptr
+
buf
->
size
;
...
...
@@ -296,4 +335,5 @@ void git_buf_join(
/* set size based on num characters actually written */
buf
->
size
=
ptr
-
buf
->
ptr
;
buf
->
ptr
[
buf
->
size
]
=
'\0'
;
}
src/buffer.h
View file @
f5f04826
...
...
@@ -14,8 +14,11 @@ typedef struct {
ssize_t
asize
,
size
;
}
git_buf
;
#define GIT_BUF_INIT {NULL, 0, 0}
extern
char
git_buf_initbuf
[];
#define GIT_BUF_INIT { git_buf_initbuf, 0, 0 }
void
git_buf_init
(
git_buf
*
buf
,
size_t
initial_size
);
int
git_buf_grow
(
git_buf
*
buf
,
size_t
target_size
);
void
git_buf_free
(
git_buf
*
buf
);
void
git_buf_swap
(
git_buf
*
buf_a
,
git_buf
*
buf_b
);
...
...
@@ -42,6 +45,7 @@ void git_buf_join(git_buf *buf, char separator, const char *str_a, const char *s
const
char
*
git_buf_cstr
(
git_buf
*
buf
);
char
*
git_buf_take_cstr
(
git_buf
*
buf
);
void
git_buf_copy_cstr
(
char
*
data
,
size_t
datasize
,
git_buf
*
buf
);
#define git_buf_PUTS(buf, str) git_buf_put(buf, str, sizeof(str) - 1)
...
...
tests-clay/core/buffer.c
View file @
f5f04826
...
...
@@ -52,19 +52,19 @@ void test_core_buffer__2(void)
{
git_buf
buf
=
GIT_BUF_INIT
;
int
i
;
char
data
[
100
];
cl_assert
(
buf
.
size
==
0
);
/* this must be safe to do */
git_buf_free
(
&
buf
);
cl_assert
(
buf
.
size
==
0
);
cl_assert
(
buf
.
asize
==
0
);
/* empty buffer should be empty string */
cl_assert_strequal
(
""
,
git_buf_cstr
(
&
buf
));
cl_assert
(
buf
.
size
==
0
);
cl_assert
(
buf
.
asize
>
0
);
/* cl_assert(buf.asize == 0); -- should not assume what git_buf does */
/* free should set us back to the beginning */
git_buf_free
(
&
buf
);
...
...
@@ -130,6 +130,27 @@ void test_core_buffer__2(void)
cl_assert_strequal
(
""
,
git_buf_cstr
(
&
buf
));
git_buf_free
(
&
buf
);
/* test extracting data into buffer */
git_buf_puts
(
&
buf
,
REP4
(
"0123456789"
));
cl_assert
(
git_buf_oom
(
&
buf
)
==
0
);
git_buf_copy_cstr
(
data
,
100
,
&
buf
);
cl_assert_strequal
(
data
,
REP4
(
"0123456789"
));
git_buf_copy_cstr
(
data
,
11
,
&
buf
);
cl_assert_strequal
(
data
,
"0123456789"
);
git_buf_copy_cstr
(
data
,
3
,
&
buf
);
cl_assert_strequal
(
data
,
"01"
);
git_buf_copy_cstr
(
data
,
1
,
&
buf
);
cl_assert_strequal
(
data
,
""
);
git_buf_copy_cstr
(
data
,
100
,
&
buf
);
cl_assert_strequal
(
data
,
REP4
(
"0123456789"
));
git_buf_free
(
&
buf
);
git_buf_copy_cstr
(
data
,
100
,
&
buf
);
cl_assert_strequal
(
data
,
""
);
}
/* let's do some tests with larger buffers to push our limits */
...
...
@@ -203,9 +224,6 @@ check_buf_append(
cl_assert
(
git_buf_oom
(
&
tgt
)
==
0
);
git_buf_puts
(
&
tgt
,
data_b
);
cl_assert
(
git_buf_oom
(
&
tgt
)
==
0
);
if
(
expected_data
==
NULL
)
cl_assert
(
tgt
.
ptr
==
NULL
);
else
cl_assert_strequal
(
expected_data
,
git_buf_cstr
(
&
tgt
));
cl_assert
(
tgt
.
size
==
expected_size
);
if
(
expected_asize
>
0
)
...
...
@@ -277,15 +295,15 @@ void test_core_buffer__5(void)
*/
check_buf_append
(
"abcdefgh"
,
"/"
,
"abcdefgh/"
,
9
,
16
);
check_buf_append
(
"abcdefgh"
,
"ijklmno"
,
"abcdefghijklmno"
,
15
,
24
);
check_buf_append
(
"abcdefgh"
,
"ijklmno"
,
"abcdefghijklmno"
,
15
,
16
);
check_buf_append
(
"abcdefgh"
,
"ijklmnop"
,
"abcdefghijklmnop"
,
16
,
24
);
check_buf_append
(
"0123456789"
,
"0123456789"
,
"01234567890123456789"
,
20
,
24
);
check_buf_append
(
REP16
(
"x"
),
REP16
(
"o"
),
REP16
(
"x"
)
REP16
(
"o"
),
32
,
40
);
check_buf_append
(
test_4096
,
""
,
test_4096
,
4096
,
614
4
);
check_buf_append
(
test_4096
,
test_4096
,
test_8192
,
8192
,
92
16
);
check_buf_append
(
test_4096
,
""
,
test_4096
,
4096
,
410
4
);
check_buf_append
(
test_4096
,
test_4096
,
test_8192
,
8192
,
92
40
);
/* check sequences of appends */
check_buf_append_abc
(
"a"
,
"b"
,
"c"
,
...
...
@@ -335,13 +353,13 @@ void test_core_buffer__7(void)
b
=
git_buf_take_cstr
(
&
a
);
cl_assert_strequal
(
"foo"
,
b
);
cl_assert_strequal
(
NULL
,
a
.
ptr
);
cl_assert_strequal
(
""
,
a
.
ptr
);
git__free
(
b
);
b
=
git_buf_take_cstr
(
&
a
);
cl_assert_strequal
(
NULL
,
b
);
cl_assert_strequal
(
NULL
,
a
.
ptr
);
cl_assert_strequal
(
""
,
a
.
ptr
);
git_buf_free
(
&
a
);
}
...
...
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