Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
nghttp2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
nghttp2
Commits
8da20975
Commit
8da20975
authored
Mar 11, 2016
by
Tatsuhiro Tsujikawa
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Always allocate buffer for name, and value
parent
eb393985
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
97 additions
and
243 deletions
+97
-243
lib/nghttp2_buf.h
lib/nghttp2_buf.h
+1
-1
lib/nghttp2_hd.c
lib/nghttp2_hd.c
+80
-198
lib/nghttp2_hd.h
lib/nghttp2_hd.h
+6
-12
lib/nghttp2_hd_huffman.c
lib/nghttp2_hd_huffman.c
+3
-26
tests/nghttp2_hd_test.c
tests/nghttp2_hd_test.c
+7
-6
No files found.
lib/nghttp2_buf.h
View file @
8da20975
...
...
@@ -73,7 +73,7 @@ typedef struct {
/*
* Initializes the |buf|. No memory is allocated in this function. Use
* nghttp2_buf_reserve()
or nghttp2_buf_reserve2()
to allocate memory.
* nghttp2_buf_reserve() to allocate memory.
*/
void
nghttp2_buf_init
(
nghttp2_buf
*
buf
);
...
...
lib/nghttp2_hd.c
View file @
8da20975
...
...
@@ -1099,30 +1099,24 @@ int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem) {
inflater
->
min_hd_table_bufsize_max
=
UINT32_MAX
;
inflater
->
ent_keep
=
NULL
;
inflater
->
nv_keep
=
NULL
;
inflater
->
nv_name_keep
=
NULL
;
inflater
->
nv_value_keep
=
NULL
;
inflater
->
opcode
=
NGHTTP2_HD_OPCODE_NONE
;
inflater
->
state
=
NGHTTP2_HD_STATE_INFLATE_START
;
rv
=
nghttp2_bufs_init3
(
&
inflater
->
nvbufs
,
NGHTTP2_HD_MAX_NV
/
8
,
8
,
1
,
0
,
mem
);
if
(
rv
!=
0
)
{
goto
nvbufs_fail
;
}
nghttp2_buf_init
(
&
inflater
->
namebuf
);
nghttp2_buf_init
(
&
inflater
->
valuebuf
);
inflater
->
huffman_encoded
=
0
;
inflater
->
index
=
0
;
inflater
->
left
=
0
;
inflater
->
shift
=
0
;
inflater
->
newnamelen
=
0
;
inflater
->
index_required
=
0
;
inflater
->
no_index
=
0
;
return
0
;
nvbufs_fail:
hd_context_free
(
&
inflater
->
ctx
);
fail:
return
rv
;
}
...
...
@@ -1139,8 +1133,11 @@ static void hd_inflate_keep_free(nghttp2_hd_inflater *inflater) {
inflater
->
ent_keep
=
NULL
;
}
nghttp2_mem_free
(
mem
,
inflater
->
nv_keep
);
inflater
->
nv_keep
=
NULL
;
nghttp2_mem_free
(
mem
,
inflater
->
nv_value_keep
);
inflater
->
nv_value_keep
=
NULL
;
nghttp2_mem_free
(
mem
,
inflater
->
nv_name_keep
);
inflater
->
nv_name_keep
=
NULL
;
}
void
nghttp2_hd_deflate_free
(
nghttp2_hd_deflater
*
deflater
)
{
...
...
@@ -1148,8 +1145,13 @@ void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater) {
}
void
nghttp2_hd_inflate_free
(
nghttp2_hd_inflater
*
inflater
)
{
nghttp2_mem
*
mem
;
mem
=
inflater
->
ctx
.
mem
;
hd_inflate_keep_free
(
inflater
);
nghttp2_bufs_free
(
&
inflater
->
nvbufs
);
nghttp2_buf_free
(
&
inflater
->
valuebuf
,
mem
);
nghttp2_buf_free
(
&
inflater
->
namebuf
,
mem
);
hd_context_free
(
&
inflater
->
ctx
);
}
...
...
@@ -2036,11 +2038,9 @@ static ssize_t hd_inflate_read_len(nghttp2_hd_inflater *inflater, int *rfin,
* Out of memory
* NGHTTP2_ERR_HEADER_COMP
* Huffman decoding failed
* NGHTTP2_ERR_BUFFER_ERROR
* Out of buffer space.
*/
static
ssize_t
hd_inflate_read_huff
(
nghttp2_hd_inflater
*
inflater
,
nghttp2_buf
s
*
bufs
,
uint8_t
*
in
,
nghttp2_buf
*
buf
,
uint8_t
*
in
,
uint8_t
*
last
)
{
ssize_t
readlen
;
int
final
=
0
;
...
...
@@ -2048,7 +2048,7 @@ static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
last
=
in
+
inflater
->
left
;
final
=
1
;
}
readlen
=
nghttp2_hd_huff_decode
(
&
inflater
->
huff_decode_ctx
,
buf
s
,
in
,
readlen
=
nghttp2_hd_huff_decode
(
&
inflater
->
huff_decode_ctx
,
buf
,
in
,
(
size_t
)(
last
-
in
),
final
);
if
(
readlen
<
0
)
{
...
...
@@ -2070,17 +2070,13 @@ static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
* Out of memory
* NGHTTP2_ERR_HEADER_COMP
* Header decompression failed
* NGHTTP2_ERR_BUFFER_ERROR
* Out of buffer space.
*/
static
ssize_t
hd_inflate_read
(
nghttp2_hd_inflater
*
inflater
,
nghttp2_bufs
*
bufs
,
uint8_t
*
in
,
uint8_t
*
last
)
{
int
rv
;
static
ssize_t
hd_inflate_read
(
nghttp2_hd_inflater
*
inflater
,
nghttp2_buf
*
buf
,
uint8_t
*
in
,
uint8_t
*
last
)
{
size_t
len
=
nghttp2_min
((
size_t
)(
last
-
in
),
inflater
->
left
);
rv
=
nghttp2_bufs_add
(
bufs
,
in
,
len
);
if
(
rv
!=
0
)
{
return
rv
;
}
buf
->
last
=
nghttp2_cpymem
(
buf
->
last
,
in
,
len
);
inflater
->
left
-=
len
;
return
(
ssize_t
)
len
;
}
...
...
@@ -2105,112 +2101,6 @@ static int hd_inflate_commit_indexed(nghttp2_hd_inflater *inflater,
return
0
;
}
static
int
hd_inflate_remove_bufs
(
nghttp2_hd_inflater
*
inflater
,
nghttp2_nv
*
nv
,
int
value_only
)
{
ssize_t
rv
;
size_t
buflen
;
uint8_t
*
buf
;
nghttp2_buf
*
pbuf
;
if
(
inflater
->
index_required
||
inflater
->
nvbufs
.
head
!=
inflater
->
nvbufs
.
cur
)
{
rv
=
nghttp2_bufs_remove
(
&
inflater
->
nvbufs
,
&
buf
);
if
(
rv
<
0
)
{
return
NGHTTP2_ERR_NOMEM
;
}
nghttp2_bufs_reset
(
&
inflater
->
nvbufs
);
buflen
=
(
size_t
)
rv
;
if
(
value_only
)
{
/* we don't use this value, so no need to NULL-terminate */
nv
->
name
=
NULL
;
nv
->
namelen
=
0
;
nv
->
value
=
buf
;
nv
->
valuelen
=
buflen
-
1
;
}
else
{
nv
->
name
=
buf
;
nv
->
namelen
=
inflater
->
newnamelen
;
nv
->
value
=
buf
+
nv
->
namelen
+
1
;
nv
->
valuelen
=
buflen
-
nv
->
namelen
-
2
;
}
return
0
;
}
/* If we are not going to store header in header table and
name/value are in first chunk, we just refer them from nv,
instead of mallocing another memory. */
pbuf
=
&
inflater
->
nvbufs
.
head
->
buf
;
if
(
value_only
)
{
/* we don't use this value, so no need to NULL-terminate */
nv
->
name
=
NULL
;
nv
->
namelen
=
0
;
nv
->
value
=
pbuf
->
pos
;
nv
->
valuelen
=
nghttp2_buf_len
(
pbuf
)
-
1
;
}
else
{
nv
->
name
=
pbuf
->
pos
;
nv
->
namelen
=
inflater
->
newnamelen
;
nv
->
value
=
pbuf
->
pos
+
nv
->
namelen
+
1
;
nv
->
valuelen
=
nghttp2_buf_len
(
pbuf
)
-
nv
->
namelen
-
2
;
}
/* Resetting does not change the content of first buffer */
nghttp2_bufs_reset
(
&
inflater
->
nvbufs
);
return
0
;
}
static
int
hd_inflate_remove_bufs_with_name
(
nghttp2_hd_inflater
*
inflater
,
nghttp2_nv
*
nv
,
nghttp2_hd_entry
*
ent_name
)
{
#ifndef NDEBUG
size_t
rv
;
#endif
size_t
buflen
;
uint8_t
*
buf
;
nghttp2_mem
*
mem
;
mem
=
inflater
->
ctx
.
mem
;
/* Allocate buffer including name in ent_name, plus terminating
NULL. */
buflen
=
ent_name
->
nv
.
namelen
+
1
+
nghttp2_bufs_len
(
&
inflater
->
nvbufs
);
buf
=
nghttp2_mem_malloc
(
mem
,
buflen
);
if
(
buf
==
NULL
)
{
return
NGHTTP2_ERR_NOMEM
;
}
/* Copy including terminal NULL */
memcpy
(
buf
,
ent_name
->
nv
.
name
,
ent_name
->
nv
.
namelen
+
1
);
#ifndef NDEBUG
rv
=
#endif
nghttp2_bufs_remove_copy
(
&
inflater
->
nvbufs
,
buf
+
ent_name
->
nv
.
namelen
+
1
);
assert
(
ent_name
->
nv
.
namelen
+
1
+
rv
==
buflen
);
nghttp2_bufs_reset
(
&
inflater
->
nvbufs
);
nv
->
name
=
buf
;
nv
->
namelen
=
ent_name
->
nv
.
namelen
;
nv
->
value
=
buf
+
nv
->
namelen
+
1
;
nv
->
valuelen
=
buflen
-
nv
->
namelen
-
2
;
return
0
;
}
/*
* Finalize literal header representation - new name- reception. If
* header is emitted, |*nv_out| is filled with that value and 0 is
...
...
@@ -2224,16 +2114,18 @@ static int hd_inflate_remove_bufs_with_name(nghttp2_hd_inflater *inflater,
*/
static
int
hd_inflate_commit_newname
(
nghttp2_hd_inflater
*
inflater
,
nghttp2_nv
*
nv_out
,
int
*
token_out
)
{
int
rv
;
nghttp2_nv
nv
;
nghttp2_mem
*
mem
;
mem
=
inflater
->
ctx
.
mem
;
rv
=
hd_inflate_remove_bufs
(
inflater
,
&
nv
,
0
/* name and value */
);
if
(
rv
!=
0
)
{
return
NGHTTP2_ERR_NOMEM
;
}
nv
.
name
=
inflater
->
namebuf
.
pos
;
nv
.
namelen
=
nghttp2_buf_len
(
&
inflater
->
namebuf
);
nv
.
value
=
inflater
->
valuebuf
.
pos
;
nv
.
valuelen
=
nghttp2_buf_len
(
&
inflater
->
valuebuf
);
nghttp2_buf_init
(
&
inflater
->
valuebuf
);
nghttp2_buf_init
(
&
inflater
->
namebuf
);
if
(
inflater
->
no_index
)
{
nv
.
flags
=
NGHTTP2_NV_FLAG_NO_INDEX
;
...
...
@@ -2245,10 +2137,8 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
nghttp2_hd_entry
*
new_ent
;
uint8_t
ent_flags
;
/* nv->value points to the middle of the buffer pointed by
nv->name. So we just need to keep track of nv->name for memory
management. */
ent_flags
=
NGHTTP2_HD_FLAG_NAME_ALLOC
|
NGHTTP2_HD_FLAG_NAME_GIFT
;
ent_flags
=
NGHTTP2_HD_FLAG_NAME_ALLOC
|
NGHTTP2_HD_FLAG_NAME_GIFT
|
NGHTTP2_HD_FLAG_VALUE_ALLOC
|
NGHTTP2_HD_FLAG_VALUE_GIFT
;
new_ent
=
add_hd_table_incremental
(
&
inflater
->
ctx
,
&
nv
,
lookup_token
(
nv
.
name
,
nv
.
namelen
),
...
...
@@ -2261,6 +2151,7 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
return
0
;
}
nghttp2_mem_free
(
mem
,
nv
.
value
);
nghttp2_mem_free
(
mem
,
nv
.
name
);
return
NGHTTP2_ERR_NOMEM
;
...
...
@@ -2268,9 +2159,8 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
emit_literal_header
(
nv_out
,
token_out
,
&
nv
);
if
(
nv
.
name
!=
inflater
->
nvbufs
.
head
->
buf
.
pos
)
{
inflater
->
nv_keep
=
nv
.
name
;
}
inflater
->
nv_name_keep
=
nv
.
name
;
inflater
->
nv_value_keep
=
nv
.
value
;
return
0
;
}
...
...
@@ -2288,7 +2178,6 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
*/
static
int
hd_inflate_commit_indname
(
nghttp2_hd_inflater
*
inflater
,
nghttp2_nv
*
nv_out
,
int
*
token_out
)
{
int
rv
;
nghttp2_nv
nv
;
nghttp2_hd_entry
*
ent_name
;
nghttp2_mem
*
mem
;
...
...
@@ -2307,24 +2196,20 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
nghttp2_hd_entry
*
new_ent
;
uint8_t
ent_flags
;
if
(
inflater
->
index
<
NGHTTP2_STATIC_TABLE_LENGTH
)
{
ent_flags
=
NGHTTP2_HD_FLAG_VALUE_ALLOC
|
NGHTTP2_HD_FLAG_VALUE_GIFT
;
if
(
inflater
->
index
>=
NGHTTP2_STATIC_TABLE_LENGTH
)
{
/* We don't copy name in static table */
rv
=
hd_inflate_remove_bufs
(
inflater
,
&
nv
,
1
/* value only */
);
if
(
rv
!=
0
)
{
return
NGHTTP2_ERR_NOMEM
;
ent_flags
|=
NGHTTP2_HD_FLAG_NAME_ALLOC
;
}
nv
.
name
=
ent_name
->
nv
.
name
;
nv
.
namelen
=
ent_name
->
nv
.
namelen
;
ent_flags
=
NGHTTP2_HD_FLAG_VALUE_ALLOC
|
NGHTTP2_HD_FLAG_VALUE_GIFT
;
}
else
{
rv
=
hd_inflate_remove_bufs_with_name
(
inflater
,
&
nv
,
ent_name
);
if
(
rv
!=
0
)
{
return
NGHTTP2_ERR_NOMEM
;
}
/* nv->name and nv->value are in the same buffer. */
ent_flags
=
NGHTTP2_HD_FLAG_NAME_ALLOC
|
NGHTTP2_HD_FLAG_NAME_GIFT
;
}
nv
.
value
=
inflater
->
valuebuf
.
pos
;
nv
.
valuelen
=
nghttp2_buf_len
(
&
inflater
->
valuebuf
);
nghttp2_buf_init
(
&
inflater
->
valuebuf
);
new_ent
=
add_hd_table_incremental
(
&
inflater
->
ctx
,
&
nv
,
ent_name
->
token
,
ent_flags
,
NULL
,
0
);
...
...
@@ -2339,28 +2224,21 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
return
0
;
}
if
(
inflater
->
index
<
NGHTTP2_STATIC_TABLE_LENGTH
)
{
nghttp2_mem_free
(
mem
,
nv
.
value
);
}
else
{
nghttp2_mem_free
(
mem
,
nv
.
name
);
}
return
NGHTTP2_ERR_NOMEM
;
}
rv
=
hd_inflate_remove_bufs
(
inflater
,
&
nv
,
1
/* value only */
);
if
(
rv
!=
0
)
{
return
NGHTTP2_ERR_NOMEM
;
}
nv
.
name
=
ent_name
->
nv
.
name
;
nv
.
namelen
=
ent_name
->
nv
.
namelen
;
nv
.
value
=
inflater
->
valuebuf
.
pos
;
nv
.
valuelen
=
nghttp2_buf_len
(
&
inflater
->
valuebuf
);
nghttp2_buf_init
(
&
inflater
->
valuebuf
);
emit_literal_header
(
nv_out
,
token_out
,
&
nv
);
if
(
nv
.
value
!=
inflater
->
nvbufs
.
head
->
buf
.
pos
)
{
inflater
->
nv_keep
=
nv
.
value
;
}
inflater
->
nv_value_keep
=
nv
.
value
;
return
0
;
}
...
...
@@ -2383,6 +2261,9 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
uint8_t
*
last
=
in
+
inlen
;
int
rfin
=
0
;
int
busy
=
0
;
nghttp2_mem
*
mem
;
mem
=
inflater
->
ctx
.
mem
;
if
(
inflater
->
ctx
.
bad
)
{
return
NGHTTP2_ERR_HEADER_COMP
;
...
...
@@ -2541,12 +2422,20 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_hd_huff_decode_context_init
(
&
inflater
->
huff_decode_ctx
);
inflater
->
state
=
NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF
;
rv
=
nghttp2_buf_reserve
(
&
inflater
->
namebuf
,
inflater
->
left
*
2
+
1
,
mem
);
}
else
{
inflater
->
state
=
NGHTTP2_HD_STATE_NEWNAME_READ_NAME
;
rv
=
nghttp2_buf_reserve
(
&
inflater
->
namebuf
,
inflater
->
left
+
1
,
mem
);
}
if
(
rv
!=
0
)
{
goto
fail
;
}
break
;
case
NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF
:
rv
=
hd_inflate_read_huff
(
inflater
,
&
inflater
->
n
vbufs
,
in
,
last
);
rv
=
hd_inflate_read_huff
(
inflater
,
&
inflater
->
n
amebuf
,
in
,
last
);
if
(
rv
<
0
)
{
goto
fail
;
}
...
...
@@ -2562,18 +2451,13 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
goto
almost_ok
;
}
inflater
->
newnamelen
=
nghttp2_bufs_len
(
&
inflater
->
nvbufs
);
rv
=
nghttp2_bufs_addb
(
&
inflater
->
nvbufs
,
'\0'
);
if
(
rv
!=
0
)
{
goto
fail
;
}
*
inflater
->
namebuf
.
last
=
'\0'
;
inflater
->
state
=
NGHTTP2_HD_STATE_CHECK_VALUELEN
;
break
;
case
NGHTTP2_HD_STATE_NEWNAME_READ_NAME
:
rv
=
hd_inflate_read
(
inflater
,
&
inflater
->
n
vbufs
,
in
,
last
);
rv
=
hd_inflate_read
(
inflater
,
&
inflater
->
n
amebuf
,
in
,
last
);
if
(
rv
<
0
)
{
goto
fail
;
}
...
...
@@ -2588,12 +2472,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
goto
almost_ok
;
}
inflater
->
newnamelen
=
nghttp2_bufs_len
(
&
inflater
->
nvbufs
);
rv
=
nghttp2_bufs_addb
(
&
inflater
->
nvbufs
,
'\0'
);
if
(
rv
!=
0
)
{
goto
fail
;
}
*
inflater
->
namebuf
.
last
=
'\0'
;
inflater
->
state
=
NGHTTP2_HD_STATE_CHECK_VALUELEN
;
...
...
@@ -2625,15 +2504,24 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_hd_huff_decode_context_init
(
&
inflater
->
huff_decode_ctx
);
inflater
->
state
=
NGHTTP2_HD_STATE_READ_VALUEHUFF
;
rv
=
nghttp2_buf_reserve
(
&
inflater
->
valuebuf
,
inflater
->
left
*
2
+
1
,
mem
);
}
else
{
inflater
->
state
=
NGHTTP2_HD_STATE_READ_VALUE
;
rv
=
nghttp2_buf_reserve
(
&
inflater
->
valuebuf
,
inflater
->
left
+
1
,
mem
);
}
if
(
rv
!=
0
)
{
goto
fail
;
}
busy
=
1
;
break
;
case
NGHTTP2_HD_STATE_READ_VALUEHUFF
:
rv
=
hd_inflate_read_huff
(
inflater
,
&
inflater
->
nvbufs
,
in
,
last
);
rv
=
hd_inflate_read_huff
(
inflater
,
&
inflater
->
valuebuf
,
in
,
last
);
if
(
rv
<
0
)
{
goto
fail
;
}
...
...
@@ -2649,10 +2537,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
goto
almost_ok
;
}
rv
=
nghttp2_bufs_addb
(
&
inflater
->
nvbufs
,
'\0'
);
if
(
rv
!=
0
)
{
goto
fail
;
}
*
inflater
->
valuebuf
.
last
=
'\0'
;
if
(
inflater
->
opcode
==
NGHTTP2_HD_OPCODE_NEWNAME
)
{
rv
=
hd_inflate_commit_newname
(
inflater
,
nv_out
,
token_out
);
...
...
@@ -2669,7 +2554,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
return
(
ssize_t
)(
in
-
first
);
case
NGHTTP2_HD_STATE_READ_VALUE
:
rv
=
hd_inflate_read
(
inflater
,
&
inflater
->
nvbufs
,
in
,
last
);
rv
=
hd_inflate_read
(
inflater
,
&
inflater
->
valuebuf
,
in
,
last
);
if
(
rv
<
0
)
{
DEBUGF
(
fprintf
(
stderr
,
"inflatehd: value read failure %zd: %s
\n
"
,
rv
,
nghttp2_strerror
((
int
)
rv
)));
...
...
@@ -2686,10 +2571,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
goto
almost_ok
;
}
rv
=
nghttp2_bufs_addb
(
&
inflater
->
nvbufs
,
'\0'
);
if
(
rv
!=
0
)
{
goto
fail
;
}
*
inflater
->
valuebuf
.
last
=
'\0'
;
if
(
inflater
->
opcode
==
NGHTTP2_HD_OPCODE_NEWNAME
)
{
rv
=
hd_inflate_commit_newname
(
inflater
,
nv_out
,
token_out
);
...
...
lib/nghttp2_hd.h
View file @
8da20975
...
...
@@ -276,7 +276,7 @@ struct nghttp2_hd_deflater {
struct
nghttp2_hd_inflater
{
nghttp2_hd_context
ctx
;
/* header buffer */
nghttp2_buf
s
nvbufs
;
nghttp2_buf
namebuf
,
valuebuf
;
/* Stores current state of huffman decoding */
nghttp2_hd_huff_decode_context
huff_decode_ctx
;
/* Pointer to the nghttp2_hd_entry which is used current header
...
...
@@ -285,14 +285,11 @@ struct nghttp2_hd_inflater {
nghttp2_hd_entry
*
ent_keep
;
/* Pointer to the name/value pair buffer which is used in the
current header emission. */
uint8_t
*
nv_keep
;
uint8_t
*
nv_
name_keep
,
*
nv_value_
keep
;
/* The number of bytes to read */
size_t
left
;
/* The index in indexed repr or indexed name */
size_t
index
;
/* The length of new name encoded in literal. For huffman encoded
string, this is the length after it is decoded. */
size_t
newnamelen
;
/* The maximum header table size the inflater supports. This is the
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
size_t
settings_hd_table_bufsize_max
;
...
...
@@ -472,9 +469,8 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
/*
* Decodes the given data |src| with length |srclen|. The |ctx| must
* be initialized by nghttp2_hd_huff_decode_context_init(). The result
* will be added to |dest|. This function may expand |dest| as
* needed. The caller is responsible to release the memory of |dest|
* by calling nghttp2_bufs_free().
* will be written to |buf|. This function assumes that |buf| has the
* enough room to store the decoded byte string.
*
* The caller must set the |final| to nonzero if the given input is
* the final block.
...
...
@@ -486,13 +482,11 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
*
* NGHTTP2_ERR_NOMEM
* Out of memory.
* NGHTTP2_ERR_BUFFER_ERROR
* Maximum buffer capacity size exceeded.
* NGHTTP2_ERR_HEADER_COMP
* Decoding process has failed.
*/
ssize_t
nghttp2_hd_huff_decode
(
nghttp2_hd_huff_decode_context
*
ctx
,
nghttp2_buf
s
*
bufs
,
const
uint8_t
*
src
,
nghttp2_buf
*
buf
,
const
uint8_t
*
src
,
size_t
srclen
,
int
final
);
#endif
/* NGHTTP2_HD_H */
lib/nghttp2_hd_huffman.c
View file @
8da20975
...
...
@@ -166,31 +166,10 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
ctx
->
accept
=
1
;
}
/* Use macro to make the code simpler..., but error case is tricky.
We spent most of the CPU in decoding, so we are doing this
thing. */
#define hd_huff_decode_sym_emit(bufs, sym, avail) \
do { \
if ((avail)) { \
nghttp2_bufs_fast_addb((bufs), (sym)); \
--(avail); \
} else { \
rv = nghttp2_bufs_addb((bufs), (sym)); \
if (rv != 0) { \
return rv; \
} \
(avail) = nghttp2_bufs_cur_avail((bufs)); \
} \
} while (0)
ssize_t
nghttp2_hd_huff_decode
(
nghttp2_hd_huff_decode_context
*
ctx
,
nghttp2_buf
s
*
bufs
,
const
uint8_t
*
src
,
nghttp2_buf
*
buf
,
const
uint8_t
*
src
,
size_t
srclen
,
int
final
)
{
size_t
i
;
int
rv
;
size_t
avail
;
avail
=
nghttp2_bufs_cur_avail
(
bufs
);
/* We use the decoding algorithm described in
http://graphics.ics.uci.edu/pub/Prefix.pdf */
...
...
@@ -202,8 +181,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
return
NGHTTP2_ERR_HEADER_COMP
;
}
if
(
t
->
flags
&
NGHTTP2_HUFF_SYM
)
{
/* this is macro, and may return from this function on error */
hd_huff_decode_sym_emit
(
bufs
,
t
->
sym
,
avail
);
*
buf
->
last
++
=
t
->
sym
;
}
t
=
&
huff_decode_table
[
t
->
state
][
src
[
i
]
&
0xf
];
...
...
@@ -211,8 +189,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
return
NGHTTP2_ERR_HEADER_COMP
;
}
if
(
t
->
flags
&
NGHTTP2_HUFF_SYM
)
{
/* this is macro, and may return from this function on error */
hd_huff_decode_sym_emit
(
bufs
,
t
->
sym
,
avail
);
*
buf
->
last
++
=
t
->
sym
;
}
ctx
->
state
=
t
->
state
;
...
...
tests/nghttp2_hd_test.c
View file @
8da20975
...
...
@@ -1352,13 +1352,15 @@ void test_nghttp2_hd_decode_length(void) {
void
test_nghttp2_hd_huff_encode
(
void
)
{
int
rv
;
ssize_t
len
;
nghttp2_bufs
bufs
,
outbufs
;
nghttp2_buf
outbuf
;
nghttp2_bufs
bufs
;
nghttp2_hd_huff_decode_context
ctx
;
const
uint8_t
t1
[]
=
{
22
,
21
,
20
,
19
,
18
,
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
};
uint8_t
b
[
256
];
nghttp2_buf_wrap_init
(
&
outbuf
,
b
,
sizeof
(
b
));
frame_pack_bufs_init
(
&
bufs
);
frame_pack_bufs_init
(
&
outbufs
);
rv
=
nghttp2_hd_huff_encode
(
&
bufs
,
t1
,
sizeof
(
t1
));
...
...
@@ -1366,14 +1368,13 @@ void test_nghttp2_hd_huff_encode(void) {
nghttp2_hd_huff_decode_context_init
(
&
ctx
);
len
=
nghttp2_hd_huff_decode
(
&
ctx
,
&
outbuf
s
,
bufs
.
cur
->
buf
.
pos
,
len
=
nghttp2_hd_huff_decode
(
&
ctx
,
&
outbuf
,
bufs
.
cur
->
buf
.
pos
,
nghttp2_bufs_len
(
&
bufs
),
1
);
CU_ASSERT
((
ssize_t
)
nghttp2_bufs_len
(
&
bufs
)
==
len
);
CU_ASSERT
((
ssize_t
)
sizeof
(
t1
)
==
nghttp2_buf
s_len
(
&
outbufs
));
CU_ASSERT
((
ssize_t
)
sizeof
(
t1
)
==
nghttp2_buf
_len
(
&
outbuf
));
CU_ASSERT
(
0
==
memcmp
(
t1
,
outbuf
s
.
cur
->
buf
.
pos
,
sizeof
(
t1
)));
CU_ASSERT
(
0
==
memcmp
(
t1
,
outbuf
.
pos
,
sizeof
(
t1
)));
nghttp2_bufs_free
(
&
bufs
);
nghttp2_bufs_free
(
&
outbufs
);
}
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