Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnish-cache
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
varnishcache
varnish-cache
Commits
0799e0cc
Commit
0799e0cc
authored
Mar 01, 2021
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Sort out VSB quoting, add testcases and asserts on usage.
parent
c749a196
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
224 additions
and
51 deletions
+224
-51
vsb.h
include/vsb.h
+41
-1
vsb.c
lib/libvarnish/vsb.c
+79
-45
vsb_test.c
lib/libvarnish/vsb_test.c
+104
-5
No files found.
include/vsb.h
View file @
0799e0cc
...
@@ -79,12 +79,52 @@ ssize_t VSB_len(const struct vsb *);
...
@@ -79,12 +79,52 @@ ssize_t VSB_len(const struct vsb *);
void
VSB_delete
(
struct
vsb
*
)
v_deprecated_
;
void
VSB_delete
(
struct
vsb
*
)
v_deprecated_
;
void
VSB_fini
(
struct
vsb
*
);
void
VSB_fini
(
struct
vsb
*
);
void
VSB_destroy
(
struct
vsb
**
);
void
VSB_destroy
(
struct
vsb
**
);
#define VSB_QUOTE_NONL 1
/*
* VSB_quote[_pfx] has four major modes, and two modifiers
*/
#define VSB_QUOTE_PLAIN 0
/*
* Basic "show me the string" mode
* All output is a single line
*/
#define VSB_QUOTE_JSON 2
#define VSB_QUOTE_JSON 2
/*
* Output suitable for inclusion between "..." in JSON
* Uses JSON \u%04x quoting.
* Anything above 0x7e had better be UTF-8
*/
#define VSB_QUOTE_HEX 4
#define VSB_QUOTE_HEX 4
/*
* Hex dump, single line.
* All zero data is compressed to "0x0...0"
*/
#define VSB_QUOTE_CSTR 8
#define VSB_QUOTE_CSTR 8
/*
* C lanuage source code literal string(s)
* Breaks strings at \n (expecting string concatenation)
*/
#define VSB_QUOTE_UNSAFE 16
#define VSB_QUOTE_UNSAFE 16
/*
* For general display applications
* " and \ are not quoted
* Splits output to new line at '\n'
* Implies VSB_QUOTE_NONL
*/
#define VSB_QUOTE_NONL 1
/*
* If the output does not end in \n, append \n
* Can be combined with all other modes.
*/
#define VSB_QUOTE_ESCHEX 32
#define VSB_QUOTE_ESCHEX 32
/*
* Use \x%02x instead of \%03o
* Not valid with VSB_QUOTE_JSON and VSB_QUOTE_HEX
*/
void
VSB_quote_pfx
(
struct
vsb
*
,
const
char
*
,
const
void
*
,
void
VSB_quote_pfx
(
struct
vsb
*
,
const
char
*
,
const
void
*
,
int
len
,
int
how
);
int
len
,
int
how
);
void
VSB_quote
(
struct
vsb
*
,
const
void
*
,
int
len
,
int
how
);
void
VSB_quote
(
struct
vsb
*
,
const
void
*
,
int
len
,
int
how
);
...
...
lib/libvarnish/vsb.c
View file @
0799e0cc
...
@@ -555,73 +555,102 @@ VSB_destroy(struct vsb **s)
...
@@ -555,73 +555,102 @@ VSB_destroy(struct vsb **s)
/*
/*
* Quote a string
* Quote a string
*/
*/
static
void
vsb_quote_hex
(
struct
vsb
*
s
,
const
uint8_t
*
u
,
size_t
len
)
{
const
uint8_t
*
w
;
VSB_cat
(
s
,
"0x"
);
for
(
w
=
u
;
w
<
u
+
len
;
w
++
)
if
(
*
w
!=
0x00
)
break
;
if
(
w
==
u
+
len
&&
len
>
4
)
{
VSB_cat
(
s
,
"0...0"
);
}
else
{
for
(
w
=
u
;
w
<
u
+
len
;
w
++
)
VSB_printf
(
s
,
"%02x"
,
*
w
);
}
}
void
void
VSB_quote_pfx
(
struct
vsb
*
s
,
const
char
*
pfx
,
const
void
*
v
,
int
len
,
int
how
)
VSB_quote_pfx
(
struct
vsb
*
s
,
const
char
*
pfx
,
const
void
*
v
,
int
len
,
int
how
)
{
{
const
char
*
p
;
const
uint8_t
*
p
=
v
;
const
char
*
q
;
const
uint8_t
*
q
;
int
quote
=
0
;
int
quote
=
0
;
int
nl
=
0
;
int
nl
;
const
unsigned
char
*
u
,
*
w
;
nl
=
how
&
(
VSB_QUOTE_JSON
|
VSB_QUOTE_HEX
|
VSB_QUOTE_CSTR
|
VSB_QUOTE_UNSAFE
);
AZ
(
nl
&
(
nl
-
1
));
// Only one bit can be set
if
(
how
&
VSB_QUOTE_ESCHEX
)
AZ
(
how
&
(
VSB_QUOTE_JSON
|
VSB_QUOTE_HEX
));
if
(
how
&
VSB_QUOTE_UNSAFE
)
how
|=
VSB_QUOTE_NONL
;
assert
(
v
!=
NULL
);
assert
(
p
!=
NULL
);
if
(
len
==
-
1
)
if
(
len
==
-
1
)
len
=
strlen
(
v
);
len
=
strlen
(
v
);
if
(
len
==
0
&&
(
how
&
VSB_QUOTE_CSTR
))
{
if
(
len
==
0
&&
(
how
&
VSB_QUOTE_CSTR
))
{
VSB_printf
(
s
,
"%s
\"\"
"
,
pfx
);
VSB_printf
(
s
,
"%s
\"\"
"
,
pfx
);
return
;
if
((
how
&
VSB_QUOTE_NONL
))
}
else
if
(
len
==
0
)
VSB_putc
(
s
,
'\n'
);
}
if
(
len
==
0
)
return
;
return
;
VSB_cat
(
s
,
pfx
);
VSB_cat
(
s
,
pfx
);
if
(
how
&
VSB_QUOTE_HEX
)
{
if
(
how
&
VSB_QUOTE_HEX
)
{
u
=
v
;
vsb_quote_hex
(
s
,
v
,
len
);
for
(
w
=
u
;
w
<
u
+
len
;
w
++
)
if
(
how
&
VSB_QUOTE_NONL
)
if
(
*
w
!=
0x00
)
VSB_putc
(
s
,
'\n'
);
break
;
VSB_cat
(
s
,
"0x"
);
if
(
w
==
u
+
len
&&
len
>
4
)
{
VSB_cat
(
s
,
"0...0"
);
}
else
{
for
(
w
=
u
;
w
<
u
+
len
;
w
++
)
VSB_printf
(
s
,
"%02x"
,
*
w
);
}
return
;
return
;
}
}
p
=
v
;
if
(
how
&
VSB_QUOTE_CSTR
)
VSB_putc
(
s
,
'"'
);
for
(
q
=
p
;
q
<
p
+
len
;
q
++
)
{
for
(
q
=
p
;
q
<
p
+
len
;
q
++
)
{
if
(
!
isgraph
(
*
q
)
||
*
q
==
'"'
||
*
q
==
'\\'
)
{
if
(
*
q
<
0x20
||
*
q
==
'"'
||
*
q
==
'\\'
||
(
*
q
==
'?'
&&
(
how
&
VSB_QUOTE_CSTR
))
||
(
*
q
>
0x7e
&&
!
(
how
&
VSB_QUOTE_JSON
))
)
{
quote
++
;
quote
++
;
break
;
break
;
}
}
}
}
if
(
!
quote
&&
!
(
how
&
(
VSB_QUOTE_JSON
|
VSB_QUOTE_CSTR
)))
{
(
void
)
VSB_bcat
(
s
,
p
,
len
);
if
(
!
quote
)
{
if
((
how
&
(
VSB_QUOTE_UNSAFE
|
VSB_QUOTE_NONL
))
&&
VSB_bcat
(
s
,
p
,
len
);
if
((
how
&
VSB_QUOTE_NONL
)
&&
p
[
len
-
1
]
!=
'\n'
)
p
[
len
-
1
]
!=
'\n'
)
(
void
)
VSB_putc
(
s
,
'\n'
);
(
void
)
VSB_putc
(
s
,
'\n'
);
if
(
how
&
VSB_QUOTE_CSTR
)
VSB_putc
(
s
,
'"'
);
return
;
return
;
}
}
if
(
how
&
VSB_QUOTE_CSTR
)
nl
=
0
;
(
void
)
VSB_putc
(
s
,
'"'
);
for
(
q
=
p
;
q
<
p
+
len
;
q
++
)
{
for
(
q
=
p
;
q
<
p
+
len
;
q
++
)
{
if
(
nl
)
if
(
nl
)
VSB_cat
(
s
,
pfx
);
VSB_cat
(
s
,
pfx
);
nl
=
0
;
nl
=
0
;
switch
(
*
q
)
{
switch
(
*
q
)
{
case
'?'
:
case
'?'
:
if
(
how
&
VSB_QUOTE_CSTR
)
/* Avoid C Trigraph insanity */
if
(
how
&
VSB_QUOTE_CSTR
&&
!
(
how
&
VSB_QUOTE_JSON
))
(
void
)
VSB_putc
(
s
,
'\\'
);
(
void
)
VSB_putc
(
s
,
'\\'
);
(
void
)
VSB_putc
(
s
,
*
q
);
(
void
)
VSB_putc
(
s
,
*
q
);
break
;
break
;
case
' '
:
(
void
)
VSB_putc
(
s
,
*
q
);
break
;
case
'\\'
:
case
'\\'
:
case
'"'
:
case
'"'
:
if
(
!
(
how
&
VSB_QUOTE_UNSAFE
))
if
(
!
(
how
&
VSB_QUOTE_UNSAFE
))
...
@@ -630,38 +659,43 @@ VSB_quote_pfx(struct vsb *s, const char *pfx, const void *v, int len, int how)
...
@@ -630,38 +659,43 @@ VSB_quote_pfx(struct vsb *s, const char *pfx, const void *v, int len, int how)
break
;
break
;
case
'\n'
:
case
'\n'
:
if
(
how
&
VSB_QUOTE_CSTR
)
{
if
(
how
&
VSB_QUOTE_CSTR
)
{
(
void
)
VSB_printf
(
s
,
"
\\
n
\"\n
%s
\"
"
,
pfx
);
VSB_printf
(
s
,
"
\\
n
\"\n
%s
\"
"
,
pfx
);
}
else
if
(
how
&
(
VSB_QUOTE_NONL
|
VSB_QUOTE_UNSAFE
))
{
}
else
if
(
how
&
VSB_QUOTE_JSON
)
{
(
void
)
VSB_printf
(
s
,
"
\n
"
);
VSB_printf
(
s
,
"
\\
n"
);
}
else
if
(
how
&
VSB_QUOTE_NONL
)
{
VSB_putc
(
s
,
*
q
);
nl
=
1
;
nl
=
1
;
}
else
{
}
else
{
(
void
)
VSB_printf
(
s
,
"
\\
n"
);
VSB_printf
(
s
,
"
\\
n"
);
}
}
break
;
break
;
case
'\r'
:
case
'\r'
:
(
void
)
VSB_cat
(
s
,
"
\\
r"
);
VSB_cat
(
s
,
"
\\
r"
);
break
;
break
;
case
'\t'
:
case
'\t'
:
(
void
)
VSB_cat
(
s
,
"
\\
t"
);
VSB_cat
(
s
,
"
\\
t"
);
break
;
break
;
case
'\v'
:
case
'\v'
:
(
void
)
VSB_cat
(
s
,
"
\\
v"
);
VSB_cat
(
s
,
"
\\
v"
);
break
;
break
;
default:
default:
/* XXX: Implement VSB_QUOTE_JSON */
if
(
0x20
<=
*
q
&&
*
q
<=
0x7e
)
if
(
isgraph
(
*
q
))
VSB_putc
(
s
,
*
q
);
(
void
)
VSB_putc
(
s
,
*
q
);
else
if
(
*
q
>
0x7e
&&
(
how
&
VSB_QUOTE_JSON
))
VSB_putc
(
s
,
*
q
);
else
if
(
how
&
VSB_QUOTE_JSON
)
VSB_printf
(
s
,
"
\\
u%04x"
,
*
q
);
else
if
(
how
&
VSB_QUOTE_ESCHEX
)
else
if
(
how
&
VSB_QUOTE_ESCHEX
)
(
void
)
VSB_printf
(
s
,
"
\\
x%02x"
,
*
q
&
0xff
);
VSB_printf
(
s
,
"
\\
x%02x"
,
*
q
);
else
else
(
void
)
VSB_printf
(
s
,
"
\\
%03o"
,
*
q
&
0xff
);
VSB_printf
(
s
,
"
\\
%03o"
,
*
q
);
break
;
break
;
}
}
}
}
if
(
how
&
VSB_QUOTE_CSTR
)
if
(
how
&
VSB_QUOTE_CSTR
)
(
void
)
VSB_putc
(
s
,
'"'
);
VSB_putc
(
s
,
'"'
);
if
((
how
&
(
VSB_QUOTE_NONL
|
VSB_QUOTE_UNSAFE
)
)
&&
!
nl
)
if
((
how
&
VSB_QUOTE_NONL
)
&&
!
nl
)
(
void
)
VSB_putc
(
s
,
'\n'
);
VSB_putc
(
s
,
'\n'
);
}
}
void
void
...
...
lib/libvarnish/vsb_test.c
View file @
0799e0cc
...
@@ -10,13 +10,79 @@
...
@@ -10,13 +10,79 @@
struct
tc
{
struct
tc
{
int
how
;
int
how
;
int
inlen
;
const
char
*
in
;
const
char
*
in
;
const
char
*
out
;
const
char
*
out
;
};
};
static
struct
tc
tcs
[]
=
{
static
struct
tc
tcs
[]
=
{
{
{
0
,
NULL
,
NULL
VSB_QUOTE_HEX
,
5
,
"
\x00\n\x7e\x7f\xff
"
,
"PFX0x000a7e7fff"
},
{
VSB_QUOTE_HEX
,
5
,
"
\0\0\0\0\0
"
,
"PFX0x0...0"
},
{
VSB_QUOTE_HEX
|
VSB_QUOTE_NONL
,
5
,
"
\x00\n\x7e\x7f\xff
"
,
"PFX0x000a7e7fff
\n
"
},
{
VSB_QUOTE_ESCHEX
,
5
,
"
\x00\n\x7e\x7f\xff
"
,
"PFX
\\
x00
\\
n~
\\
x7f
\\
xff"
,
},
{
0
,
5
,
"
\x00\n\x7e\x7f\xff
"
,
"PFX
\\
000
\\
n~
\\
177
\\
377"
,
},
{
VSB_QUOTE_UNSAFE
,
5
,
"
\x00\n\x7e\x7f\xff
"
,
"PFX
\\
000
\n
PFX~
\\
177
\\
377
\n
"
,
},
{
VSB_QUOTE_UNSAFE
,
-
1
,
"
\n\"\\\t
"
,
"PFX
\n
PFX
\"\\\\
t
\n
"
},
{
VSB_QUOTE_CSTR
|
VSB_QUOTE_ESCHEX
,
5
,
"
\x00\n\x7e\x7f\xff
"
,
"PFX
\"\\
x00
\\
n
\"\n
PFX
\"
~
\\
x7f
\\
xff
\"
"
,
},
{
VSB_QUOTE_JSON
,
5
,
"
\x00\n\x7e\x7f\xff
"
,
"PFX
\\
u0000
\\
n~
\x7f\xff
"
,
},
{
VSB_QUOTE_JSON
|
VSB_QUOTE_NONL
,
5
,
"
\x00\n\x7e\x7f\xff
"
,
"PFX
\\
u0000
\\
n~
\x7f\xff\n
"
,
},
{
VSB_QUOTE_CSTR
,
-
1
,
""
,
"PFX
\"\"
"
},
{
VSB_QUOTE_CSTR
,
-
1
,
"?"
,
"PFX
\"\\
?
\"
"
},
{
VSB_QUOTE_NONL
,
-
1
,
"
\n\t
"
,
"PFX
\n
PFX
\\
t
\n
"
},
{
0
,
-
1
,
NULL
,
NULL
}
}
};
};
...
@@ -26,25 +92,58 @@ main(int argc, char *argv[])
...
@@ -26,25 +92,58 @@ main(int argc, char *argv[])
int
err
=
0
;
int
err
=
0
;
struct
tc
*
tc
;
struct
tc
*
tc
;
struct
vsb
*
vsb
;
struct
vsb
*
vsb
;
struct
vsb
*
vsbo
;
(
void
)
argc
;
(
void
)
argc
;
(
void
)
argv
;
(
void
)
argv
;
vsb
=
VSB_new_auto
();
vsb
=
VSB_new_auto
();
AN
(
vsb
);
AN
(
vsb
);
vsbo
=
VSB_new_auto
();
AN
(
vsbo
);
for
(
tc
=
tcs
;
tc
->
in
;
tc
++
)
{
for
(
tc
=
tcs
;
tc
->
in
;
tc
++
)
{
VSB_quote
(
vsb
,
tc
->
in
,
-
1
,
tc
->
how
);
VSB_quote
_pfx
(
vsb
,
"PFX"
,
tc
->
in
,
tc
->
inlen
,
tc
->
how
);
assert
(
VSB_finish
(
vsb
)
==
0
);
assert
(
VSB_finish
(
vsb
)
==
0
);
printf
(
"%s -> %s"
,
tc
->
in
,
VSB_data
(
vsb
));
VSB_clear
(
vsbo
);
VSB_printf
(
vsbo
,
"0x%02x: "
,
tc
->
how
);
VSB_quote
(
vsbo
,
tc
->
in
,
tc
->
inlen
,
VSB_QUOTE_HEX
);
VSB_printf
(
vsbo
,
" -> "
);
VSB_quote
(
vsbo
,
VSB_data
(
vsb
),
-
1
,
VSB_QUOTE_HEX
);
VSB_printf
(
vsbo
,
" ("
);
VSB_quote
(
vsbo
,
tc
->
out
,
-
1
,
VSB_QUOTE_ESCHEX
);
VSB_printf
(
vsbo
,
")"
);
if
(
strcmp
(
VSB_data
(
vsb
),
tc
->
out
))
{
if
(
strcmp
(
VSB_data
(
vsb
),
tc
->
out
))
{
printf
(
", but should have been %s"
,
tc
->
out
);
VSB_printf
(
vsbo
,
"
\n
Should have been:
\n\t
"
);
VSB_quote
(
vsbo
,
tc
->
out
,
-
1
,
VSB_QUOTE_HEX
);
VSB_printf
(
vsbo
,
"
\n
That's:
\n\t
"
);
VSB_quote
(
vsbo
,
VSB_data
(
vsb
),
-
1
,
VSB_QUOTE_ESCHEX
);
VSB_printf
(
vsbo
,
"
\n
vs:
\n\t
"
);
VSB_quote
(
vsbo
,
tc
->
out
,
-
1
,
VSB_QUOTE_ESCHEX
);
VSB_printf
(
vsbo
,
"
\n
Flags 0x%02x = "
,
tc
->
how
);
if
(
!
tc
->
how
)
VSB_printf
(
vsbo
,
"
\n\t
0"
);
if
(
tc
->
how
&
VSB_QUOTE_NONL
)
VSB_printf
(
vsbo
,
"
\n\t
VSB_QUOTE_NONL"
);
if
(
tc
->
how
&
VSB_QUOTE_JSON
)
VSB_printf
(
vsbo
,
"
\n\t
VSB_QUOTE_JSON"
);
if
(
tc
->
how
&
VSB_QUOTE_HEX
)
VSB_printf
(
vsbo
,
"
\n\t
VSB_QUOTE_HEX"
);
if
(
tc
->
how
&
VSB_QUOTE_CSTR
)
VSB_printf
(
vsbo
,
"
\n\t
VSB_QUOTE_CSTR"
);
if
(
tc
->
how
&
VSB_QUOTE_UNSAFE
)
VSB_printf
(
vsbo
,
"
\n\t
VSB_QUOTE_UNSAFE"
);
if
(
tc
->
how
&
VSB_QUOTE_ESCHEX
)
VSB_printf
(
vsbo
,
"
\n\t
VSB_QUOTE_ESCHEX"
);
VSB_printf
(
vsbo
,
"
\n\n
"
);
err
=
1
;
err
=
1
;
}
}
printf
(
"
\n
"
);
AZ
(
VSB_finish
(
vsbo
));
printf
(
"%s
\n
"
,
VSB_data
(
vsbo
));
VSB_clear
(
vsb
);
VSB_clear
(
vsb
);
}
}
VSB_destroy
(
&
vsb
);
VSB_destroy
(
&
vsb
);
VSB_destroy
(
&
vsbo
);
printf
(
"error is %i
\n
"
,
err
);
printf
(
"error is %i
\n
"
,
err
);
return
(
err
);
return
(
err
);
}
}
...
...
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