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
d3d95d5a
Commit
d3d95d5a
authored
Sep 23, 2015
by
Edward Thomson
Committed by
Edward Thomson
May 26, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
git_buf_quote: quote ugly characters
parent
72806f4c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
120 additions
and
27 deletions
+120
-27
src/buffer.c
+66
-0
src/buffer.h
+2
-1
tests/buf/quote.c
+52
-26
No files found.
src/buffer.c
View file @
d3d95d5a
...
...
@@ -858,6 +858,72 @@ int git_buf_splice(
return
0
;
}
/* Quote per http://marc.info/?l=git&m=112927316408690&w=2 */
int
git_buf_quote
(
git_buf
*
buf
)
{
const
char
whitespace
[]
=
{
'a'
,
'b'
,
't'
,
'n'
,
'v'
,
'f'
,
'r'
};
git_buf
quoted
=
GIT_BUF_INIT
;
size_t
i
=
0
;
bool
quote
=
false
;
int
error
=
0
;
/* walk to the first char that needs quoting */
if
(
buf
->
size
&&
buf
->
ptr
[
0
]
==
'!'
)
quote
=
true
;
for
(
i
=
0
;
!
quote
&&
i
<
buf
->
size
;
i
++
)
{
if
(
buf
->
ptr
[
i
]
==
'"'
||
buf
->
ptr
[
i
]
==
'\\'
||
buf
->
ptr
[
i
]
<
' '
||
buf
->
ptr
[
i
]
>
'~'
)
{
quote
=
true
;
break
;
}
}
if
(
!
quote
)
goto
done
;
git_buf_putc
(
&
quoted
,
'"'
);
git_buf_put
(
&
quoted
,
buf
->
ptr
,
i
);
for
(;
i
<
buf
->
size
;
i
++
)
{
/* whitespace - use the map above, which is ordered by ascii value */
if
(
buf
->
ptr
[
i
]
>=
'\a'
&&
buf
->
ptr
[
i
]
<=
'\r'
)
{
git_buf_putc
(
&
quoted
,
'\\'
);
git_buf_putc
(
&
quoted
,
whitespace
[
buf
->
ptr
[
i
]
-
'\a'
]);
}
/* double quote and backslash must be escaped */
else
if
(
buf
->
ptr
[
i
]
==
'"'
||
buf
->
ptr
[
i
]
==
'\\'
)
{
git_buf_putc
(
&
quoted
,
'\\'
);
git_buf_putc
(
&
quoted
,
buf
->
ptr
[
i
]);
}
/* escape anything unprintable as octal */
else
if
(
buf
->
ptr
[
i
]
!=
' '
&&
(
buf
->
ptr
[
i
]
<
'!'
||
buf
->
ptr
[
i
]
>
'~'
))
{
git_buf_printf
(
&
quoted
,
"
\\
%03o"
,
buf
->
ptr
[
i
]);
}
/* yay, printable! */
else
{
git_buf_putc
(
&
quoted
,
buf
->
ptr
[
i
]);
}
}
git_buf_putc
(
&
quoted
,
'"'
);
if
(
git_buf_oom
(
&
quoted
))
{
error
=
-
1
;
goto
done
;
}
git_buf_swap
(
&
quoted
,
buf
);
done:
git_buf_free
(
&
quoted
);
return
error
;
}
/* Unquote per http://marc.info/?l=git&m=112927316408690&w=2 */
int
git_buf_unquote
(
git_buf
*
buf
)
{
...
...
src/buffer.h
View file @
d3d95d5a
...
...
@@ -173,9 +173,10 @@ void git_buf_rtrim(git_buf *buf);
int
git_buf_cmp
(
const
git_buf
*
a
,
const
git_buf
*
b
);
/*
U
nquote a buffer as specified in
/*
Quote and u
nquote a buffer as specified in
* http://marc.info/?l=git&m=112927316408690&w=2
*/
int
git_buf_quote
(
git_buf
*
buf
);
int
git_buf_unquote
(
git_buf
*
buf
);
/* Write data as base64 encoded in buffer */
...
...
tests/buf/quote.c
View file @
d3d95d5a
#include "clar_libgit2.h"
#include "buffer.h"
static
void
expect_pass
(
const
char
*
expected
,
const
char
*
quoted
)
static
void
expect_quote_pass
(
const
char
*
expected
,
const
char
*
str
)
{
git_buf
buf
=
GIT_BUF_INIT
;
cl_git_pass
(
git_buf_puts
(
&
buf
,
str
));
cl_git_pass
(
git_buf_quote
(
&
buf
));
cl_assert_equal_s
(
expected
,
git_buf_cstr
(
&
buf
));
cl_assert_equal_i
(
strlen
(
expected
),
git_buf_len
(
&
buf
));
git_buf_free
(
&
buf
);
}
void
test_buf_quote__quote_succeeds
(
void
)
{
expect_quote_pass
(
""
,
""
);
expect_quote_pass
(
"foo"
,
"foo"
);
expect_quote_pass
(
"foo/bar/baz.c"
,
"foo/bar/baz.c"
);
expect_quote_pass
(
"foo bar"
,
"foo bar"
);
expect_quote_pass
(
"
\"\\\"
leading quote
\"
"
,
"
\"
leading quote"
);
expect_quote_pass
(
"
\"
slash
\\\\
y
\"
"
,
"slash
\\
y"
);
expect_quote_pass
(
"
\"
foo
\\
r
\\
nbar
\"
"
,
"foo
\r\n
bar"
);
expect_quote_pass
(
"
\"
foo
\\
177bar
\"
"
,
"foo
\177
bar"
);
expect_quote_pass
(
"
\"
foo
\\
001bar
\"
"
,
"foo
\001
bar"
);
}
static
void
expect_unquote_pass
(
const
char
*
expected
,
const
char
*
quoted
)
{
git_buf
buf
=
GIT_BUF_INIT
;
...
...
@@ -14,7 +40,7 @@ static void expect_pass(const char *expected, const char *quoted)
git_buf_free
(
&
buf
);
}
static
void
expect_fail
(
const
char
*
quoted
)
static
void
expect_
unquote_
fail
(
const
char
*
quoted
)
{
git_buf
buf
=
GIT_BUF_INIT
;
...
...
@@ -26,32 +52,32 @@ static void expect_fail(const char *quoted)
void
test_buf_quote__unquote_succeeds
(
void
)
{
expect_pass
(
""
,
"
\"\"
"
);
expect_pass
(
" "
,
"
\"
\"
"
);
expect_pass
(
"foo"
,
"
\"
foo
\"
"
);
expect_pass
(
"foo bar"
,
"
\"
foo bar
\"
"
);
expect_pass
(
"foo
\"
bar"
,
"
\"
foo
\\\"
bar
\"
"
);
expect_pass
(
"foo
\\
bar"
,
"
\"
foo
\\\\
bar
\"
"
);
expect_pass
(
"foo
\t
bar"
,
"
\"
foo
\\
tbar
\"
"
);
expect_pass
(
"
\v
foo
\t
bar
\n
"
,
"
\"\\
vfoo
\\
tbar
\\
n
\"
"
);
expect_pass
(
"foo
\n
bar"
,
"
\"
foo
\\
012bar
\"
"
);
expect_pass
(
"foo
\r\n
bar"
,
"
\"
foo
\\
015
\\
012bar
\"
"
);
expect_pass
(
"foo
\r\n
bar"
,
"
\"\\
146
\\
157
\\
157
\\
015
\\
012
\\
142
\\
141
\\
162
\"
"
);
expect_pass
(
"newline:
\n
"
,
"
\"
newline:
\\
012
\"
"
);
expect_
unquote_
pass
(
""
,
"
\"\"
"
);
expect_
unquote_
pass
(
" "
,
"
\"
\"
"
);
expect_
unquote_
pass
(
"foo"
,
"
\"
foo
\"
"
);
expect_
unquote_
pass
(
"foo bar"
,
"
\"
foo bar
\"
"
);
expect_
unquote_
pass
(
"foo
\"
bar"
,
"
\"
foo
\\\"
bar
\"
"
);
expect_
unquote_
pass
(
"foo
\\
bar"
,
"
\"
foo
\\\\
bar
\"
"
);
expect_
unquote_
pass
(
"foo
\t
bar"
,
"
\"
foo
\\
tbar
\"
"
);
expect_
unquote_
pass
(
"
\v
foo
\t
bar
\n
"
,
"
\"\\
vfoo
\\
tbar
\\
n
\"
"
);
expect_
unquote_
pass
(
"foo
\n
bar"
,
"
\"
foo
\\
012bar
\"
"
);
expect_
unquote_
pass
(
"foo
\r\n
bar"
,
"
\"
foo
\\
015
\\
012bar
\"
"
);
expect_
unquote_
pass
(
"foo
\r\n
bar"
,
"
\"\\
146
\\
157
\\
157
\\
015
\\
012
\\
142
\\
141
\\
162
\"
"
);
expect_
unquote_
pass
(
"newline:
\n
"
,
"
\"
newline:
\\
012
\"
"
);
}
void
test_buf_quote__unquote_fails
(
void
)
{
expect_fail
(
"no quotes at all"
);
expect_fail
(
"
\"
no trailing quote"
);
expect_fail
(
"no leading quote
\"
"
);
expect_fail
(
"
\"
invalid
\\
z escape char
\"
"
);
expect_fail
(
"
\"\\
q invalid escape char
\"
"
);
expect_fail
(
"
\"
invalid escape char
\\
p
\"
"
);
expect_fail
(
"
\"
invalid
\\
1 escape char
\"
"
);
expect_fail
(
"
\"
invalid
\\
14 escape char
\"
"
);
expect_fail
(
"
\"
invalid
\\
411 escape char
\"
"
);
expect_fail
(
"
\"
truncated escape char
\\\"
"
);
expect_fail
(
"
\"
truncated escape char
\\
0
\"
"
);
expect_fail
(
"
\"
truncated escape char
\\
01
\"
"
);
expect_
unquote_
fail
(
"no quotes at all"
);
expect_
unquote_
fail
(
"
\"
no trailing quote"
);
expect_
unquote_
fail
(
"no leading quote
\"
"
);
expect_
unquote_
fail
(
"
\"
invalid
\\
z escape char
\"
"
);
expect_
unquote_
fail
(
"
\"\\
q invalid escape char
\"
"
);
expect_
unquote_
fail
(
"
\"
invalid escape char
\\
p
\"
"
);
expect_
unquote_
fail
(
"
\"
invalid
\\
1 escape char
\"
"
);
expect_
unquote_
fail
(
"
\"
invalid
\\
14 escape char
\"
"
);
expect_
unquote_
fail
(
"
\"
invalid
\\
411 escape char
\"
"
);
expect_
unquote_
fail
(
"
\"
truncated escape char
\\\"
"
);
expect_
unquote_
fail
(
"
\"
truncated escape char
\\
0
\"
"
);
expect_
unquote_
fail
(
"
\"
truncated escape char
\\
01
\"
"
);
}
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