Skip to content

Commit

Permalink
vcs-svn: add binary-safe read function
Browse files Browse the repository at this point in the history
buffer_read_string works well for non line-oriented input except for
one problem: it does not tell the caller how many bytes were actually
written.  This means that unless one is very careful about checking
for errors (and eof) the calling program cannot tell the difference
between the string "foo" followed by an early end of file and the
string "foo\0bar\0baz".

So introduce a variant that reports the length, too, a thinner wrapper
around strbuf_fread.  Its result is written to a strbuf so the caller
does not need to keep track of the number of bytes read.

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
  • Loading branch information
jrn committed Feb 26, 2011
1 parent d280f68 commit e832f43
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 0 deletions.
18 changes: 18 additions & 0 deletions t/t0081-line-buffer.sh
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -151,6 +151,15 @@ test_expect_success 'skip, copy null byte' '
test_cmp expect actual test_cmp expect actual
' '


test_expect_success 'read null byte' '
echo ">QhelloQ" | q_to_nul >expect &&
q_to_nul <<-\EOF | test-line-buffer >actual &&
binary 8
QhelloQ
EOF
test_cmp expect actual
'

test_expect_success 'long reads are truncated' ' test_expect_success 'long reads are truncated' '
echo foo >expect && echo foo >expect &&
test-line-buffer <<-\EOF >actual && test-line-buffer <<-\EOF >actual &&
Expand All @@ -171,4 +180,13 @@ test_expect_success 'long copies are truncated' '
test_cmp expect actual test_cmp expect actual
' '


test_expect_success 'long binary reads are truncated' '
echo ">foo" >expect &&
test-line-buffer <<-\EOF >actual &&
binary 5
foo
EOF
test_cmp expect actual
'

test_done test_done
10 changes: 10 additions & 0 deletions test-line-buffer.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/ */


#include "git-compat-util.h" #include "git-compat-util.h"
#include "strbuf.h"
#include "vcs-svn/line_buffer.h" #include "vcs-svn/line_buffer.h"


static uint32_t strtouint32(const char *s) static uint32_t strtouint32(const char *s)
Expand All @@ -17,6 +18,15 @@ static uint32_t strtouint32(const char *s)
static void handle_command(const char *command, const char *arg, struct line_buffer *buf) static void handle_command(const char *command, const char *arg, struct line_buffer *buf)
{ {
switch (*command) { switch (*command) {
case 'b':
if (!prefixcmp(command, "binary ")) {
struct strbuf sb = STRBUF_INIT;
strbuf_addch(&sb, '>');
buffer_read_binary(buf, &sb, strtouint32(arg));
fwrite(sb.buf, 1, sb.len, stdout);
strbuf_release(&sb);
return;
}
case 'c': case 'c':
if (!prefixcmp(command, "copy ")) { if (!prefixcmp(command, "copy ")) {
buffer_copy_bytes(buf, strtouint32(arg)); buffer_copy_bytes(buf, strtouint32(arg));
Expand Down
6 changes: 6 additions & 0 deletions vcs-svn/line_buffer.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ char *buffer_read_string(struct line_buffer *buf, uint32_t len)
return ferror(buf->infile) ? NULL : buf->blob_buffer.buf; return ferror(buf->infile) ? NULL : buf->blob_buffer.buf;
} }


void buffer_read_binary(struct line_buffer *buf,
struct strbuf *sb, uint32_t size)
{
strbuf_fread(sb, size, buf->infile);
}

void buffer_copy_bytes(struct line_buffer *buf, uint32_t len) void buffer_copy_bytes(struct line_buffer *buf, uint32_t len)
{ {
char byte_buffer[COPY_BUFFER_LEN]; char byte_buffer[COPY_BUFFER_LEN];
Expand Down
1 change: 1 addition & 0 deletions vcs-svn/line_buffer.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ int buffer_init(struct line_buffer *buf, const char *filename);
int buffer_deinit(struct line_buffer *buf); int buffer_deinit(struct line_buffer *buf);
char *buffer_read_line(struct line_buffer *buf); char *buffer_read_line(struct line_buffer *buf);
char *buffer_read_string(struct line_buffer *buf, uint32_t len); char *buffer_read_string(struct line_buffer *buf, uint32_t len);
void buffer_read_binary(struct line_buffer *buf, struct strbuf *sb, uint32_t len);
void buffer_copy_bytes(struct line_buffer *buf, uint32_t len); void buffer_copy_bytes(struct line_buffer *buf, uint32_t len);
void buffer_skip_bytes(struct line_buffer *buf, uint32_t len); void buffer_skip_bytes(struct line_buffer *buf, uint32_t len);
void buffer_reset(struct line_buffer *buf); void buffer_reset(struct line_buffer *buf);
Expand Down

0 comments on commit e832f43

Please sign in to comment.