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 {
...
@@ -73,7 +73,7 @@ typedef struct {
/*
/*
* Initializes the |buf|. No memory is allocated in this function. Use
* 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
);
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) {
...
@@ -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
->
min_hd_table_bufsize_max
=
UINT32_MAX
;
inflater
->
ent_keep
=
NULL
;
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
->
opcode
=
NGHTTP2_HD_OPCODE_NONE
;
inflater
->
state
=
NGHTTP2_HD_STATE_INFLATE_START
;
inflater
->
state
=
NGHTTP2_HD_STATE_INFLATE_START
;
rv
=
nghttp2_bufs_init3
(
&
inflater
->
nvbufs
,
NGHTTP2_HD_MAX_NV
/
8
,
8
,
1
,
0
,
nghttp2_buf_init
(
&
inflater
->
namebuf
);
mem
);
nghttp2_buf_init
(
&
inflater
->
valuebuf
);
if
(
rv
!=
0
)
{
goto
nvbufs_fail
;
}
inflater
->
huffman_encoded
=
0
;
inflater
->
huffman_encoded
=
0
;
inflater
->
index
=
0
;
inflater
->
index
=
0
;
inflater
->
left
=
0
;
inflater
->
left
=
0
;
inflater
->
shift
=
0
;
inflater
->
shift
=
0
;
inflater
->
newnamelen
=
0
;
inflater
->
index_required
=
0
;
inflater
->
index_required
=
0
;
inflater
->
no_index
=
0
;
inflater
->
no_index
=
0
;
return
0
;
return
0
;
nvbufs_fail:
hd_context_free
(
&
inflater
->
ctx
);
fail:
fail:
return
rv
;
return
rv
;
}
}
...
@@ -1139,8 +1133,11 @@ static void hd_inflate_keep_free(nghttp2_hd_inflater *inflater) {
...
@@ -1139,8 +1133,11 @@ static void hd_inflate_keep_free(nghttp2_hd_inflater *inflater) {
inflater
->
ent_keep
=
NULL
;
inflater
->
ent_keep
=
NULL
;
}
}
nghttp2_mem_free
(
mem
,
inflater
->
nv_keep
);
nghttp2_mem_free
(
mem
,
inflater
->
nv_value_keep
);
inflater
->
nv_keep
=
NULL
;
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
)
{
void
nghttp2_hd_deflate_free
(
nghttp2_hd_deflater
*
deflater
)
{
...
@@ -1148,8 +1145,13 @@ 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
)
{
void
nghttp2_hd_inflate_free
(
nghttp2_hd_inflater
*
inflater
)
{
nghttp2_mem
*
mem
;
mem
=
inflater
->
ctx
.
mem
;
hd_inflate_keep_free
(
inflater
);
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
);
hd_context_free
(
&
inflater
->
ctx
);
}
}
...
@@ -2036,11 +2038,9 @@ static ssize_t hd_inflate_read_len(nghttp2_hd_inflater *inflater, int *rfin,
...
@@ -2036,11 +2038,9 @@ static ssize_t hd_inflate_read_len(nghttp2_hd_inflater *inflater, int *rfin,
* Out of memory
* Out of memory
* NGHTTP2_ERR_HEADER_COMP
* NGHTTP2_ERR_HEADER_COMP
* Huffman decoding failed
* Huffman decoding failed
* NGHTTP2_ERR_BUFFER_ERROR
* Out of buffer space.
*/
*/
static
ssize_t
hd_inflate_read_huff
(
nghttp2_hd_inflater
*
inflater
,
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
)
{
uint8_t
*
last
)
{
ssize_t
readlen
;
ssize_t
readlen
;
int
final
=
0
;
int
final
=
0
;
...
@@ -2048,7 +2048,7 @@ static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
...
@@ -2048,7 +2048,7 @@ static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
last
=
in
+
inflater
->
left
;
last
=
in
+
inflater
->
left
;
final
=
1
;
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
);
(
size_t
)(
last
-
in
),
final
);
if
(
readlen
<
0
)
{
if
(
readlen
<
0
)
{
...
@@ -2070,17 +2070,13 @@ static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
...
@@ -2070,17 +2070,13 @@ static ssize_t hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
* Out of memory
* Out of memory
* NGHTTP2_ERR_HEADER_COMP
* NGHTTP2_ERR_HEADER_COMP
* Header decompression failed
* Header decompression failed
* NGHTTP2_ERR_BUFFER_ERROR
* Out of buffer space.
*/
*/
static
ssize_t
hd_inflate_read
(
nghttp2_hd_inflater
*
inflater
,
static
ssize_t
hd_inflate_read
(
nghttp2_hd_inflater
*
inflater
,
nghttp2_buf
*
buf
,
nghttp2_bufs
*
bufs
,
uint8_t
*
in
,
uint8_t
*
last
)
{
uint8_t
*
in
,
uint8_t
*
last
)
{
int
rv
;
size_t
len
=
nghttp2_min
((
size_t
)(
last
-
in
),
inflater
->
left
);
size_t
len
=
nghttp2_min
((
size_t
)(
last
-
in
),
inflater
->
left
);
rv
=
nghttp2_bufs_add
(
bufs
,
in
,
len
);
if
(
rv
!=
0
)
{
buf
->
last
=
nghttp2_cpymem
(
buf
->
last
,
in
,
len
);
return
rv
;
}
inflater
->
left
-=
len
;
inflater
->
left
-=
len
;
return
(
ssize_t
)
len
;
return
(
ssize_t
)
len
;
}
}
...
@@ -2105,112 +2101,6 @@ static int hd_inflate_commit_indexed(nghttp2_hd_inflater *inflater,
...
@@ -2105,112 +2101,6 @@ static int hd_inflate_commit_indexed(nghttp2_hd_inflater *inflater,
return
0
;
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
* Finalize literal header representation - new name- reception. If
* header is emitted, |*nv_out| is filled with that value and 0 is
* 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,
...
@@ -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
,
static
int
hd_inflate_commit_newname
(
nghttp2_hd_inflater
*
inflater
,
nghttp2_nv
*
nv_out
,
int
*
token_out
)
{
nghttp2_nv
*
nv_out
,
int
*
token_out
)
{
int
rv
;
nghttp2_nv
nv
;
nghttp2_nv
nv
;
nghttp2_mem
*
mem
;
nghttp2_mem
*
mem
;
mem
=
inflater
->
ctx
.
mem
;
mem
=
inflater
->
ctx
.
mem
;
rv
=
hd_inflate_remove_bufs
(
inflater
,
&
nv
,
0
/* name and value */
);
nv
.
name
=
inflater
->
namebuf
.
pos
;
if
(
rv
!=
0
)
{
nv
.
namelen
=
nghttp2_buf_len
(
&
inflater
->
namebuf
);
return
NGHTTP2_ERR_NOMEM
;
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
)
{
if
(
inflater
->
no_index
)
{
nv
.
flags
=
NGHTTP2_NV_FLAG_NO_INDEX
;
nv
.
flags
=
NGHTTP2_NV_FLAG_NO_INDEX
;
...
@@ -2245,10 +2137,8 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
...
@@ -2245,10 +2137,8 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
nghttp2_hd_entry
*
new_ent
;
nghttp2_hd_entry
*
new_ent
;
uint8_t
ent_flags
;
uint8_t
ent_flags
;
/* nv->value points to the middle of the buffer pointed by
ent_flags
=
NGHTTP2_HD_FLAG_NAME_ALLOC
|
NGHTTP2_HD_FLAG_NAME_GIFT
|
nv->name. So we just need to keep track of nv->name for memory
NGHTTP2_HD_FLAG_VALUE_ALLOC
|
NGHTTP2_HD_FLAG_VALUE_GIFT
;
management. */
ent_flags
=
NGHTTP2_HD_FLAG_NAME_ALLOC
|
NGHTTP2_HD_FLAG_NAME_GIFT
;
new_ent
=
add_hd_table_incremental
(
&
inflater
->
ctx
,
&
nv
,
new_ent
=
add_hd_table_incremental
(
&
inflater
->
ctx
,
&
nv
,
lookup_token
(
nv
.
name
,
nv
.
namelen
),
lookup_token
(
nv
.
name
,
nv
.
namelen
),
...
@@ -2261,6 +2151,7 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
...
@@ -2261,6 +2151,7 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
return
0
;
return
0
;
}
}
nghttp2_mem_free
(
mem
,
nv
.
value
);
nghttp2_mem_free
(
mem
,
nv
.
name
);
nghttp2_mem_free
(
mem
,
nv
.
name
);
return
NGHTTP2_ERR_NOMEM
;
return
NGHTTP2_ERR_NOMEM
;
...
@@ -2268,9 +2159,8 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
...
@@ -2268,9 +2159,8 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
emit_literal_header
(
nv_out
,
token_out
,
&
nv
);
emit_literal_header
(
nv_out
,
token_out
,
&
nv
);
if
(
nv
.
name
!=
inflater
->
nvbufs
.
head
->
buf
.
pos
)
{
inflater
->
nv_name_keep
=
nv
.
name
;
inflater
->
nv_keep
=
nv
.
name
;
inflater
->
nv_value_keep
=
nv
.
value
;
}
return
0
;
return
0
;
}
}
...
@@ -2288,7 +2178,6 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
...
@@ -2288,7 +2178,6 @@ static int hd_inflate_commit_newname(nghttp2_hd_inflater *inflater,
*/
*/
static
int
hd_inflate_commit_indname
(
nghttp2_hd_inflater
*
inflater
,
static
int
hd_inflate_commit_indname
(
nghttp2_hd_inflater
*
inflater
,
nghttp2_nv
*
nv_out
,
int
*
token_out
)
{
nghttp2_nv
*
nv_out
,
int
*
token_out
)
{
int
rv
;
nghttp2_nv
nv
;
nghttp2_nv
nv
;
nghttp2_hd_entry
*
ent_name
;
nghttp2_hd_entry
*
ent_name
;
nghttp2_mem
*
mem
;
nghttp2_mem
*
mem
;
...
@@ -2307,24 +2196,20 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
...
@@ -2307,24 +2196,20 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
nghttp2_hd_entry
*
new_ent
;
nghttp2_hd_entry
*
new_ent
;
uint8_t
ent_flags
;
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 */
/* We don't copy name in static table */
rv
=
hd_inflate_remove_bufs
(
inflater
,
&
nv
,
1
/* value only */
);
ent_flags
|=
NGHTTP2_HD_FLAG_NAME_ALLOC
;
if
(
rv
!=
0
)
{
return
NGHTTP2_ERR_NOMEM
;
}
}
nv
.
name
=
ent_name
->
nv
.
name
;
nv
.
name
=
ent_name
->
nv
.
name
;
nv
.
namelen
=
ent_name
->
nv
.
namelen
;
nv
.
namelen
=
ent_name
->
nv
.
namelen
;
ent_flags
=
NGHTTP2_HD_FLAG_VALUE_ALLOC
|
NGHTTP2_HD_FLAG_VALUE_GIFT
;
nv
.
value
=
inflater
->
valuebuf
.
pos
;
}
else
{
nv
.
valuelen
=
nghttp2_buf_len
(
&
inflater
->
valuebuf
);
rv
=
hd_inflate_remove_bufs_with_name
(
inflater
,
&
nv
,
ent_name
);
if
(
rv
!=
0
)
{
nghttp2_buf_init
(
&
inflater
->
valuebuf
);
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
;
}
new_ent
=
add_hd_table_incremental
(
&
inflater
->
ctx
,
&
nv
,
ent_name
->
token
,
new_ent
=
add_hd_table_incremental
(
&
inflater
->
ctx
,
&
nv
,
ent_name
->
token
,
ent_flags
,
NULL
,
0
);
ent_flags
,
NULL
,
0
);
...
@@ -2339,28 +2224,21 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
...
@@ -2339,28 +2224,21 @@ static int hd_inflate_commit_indname(nghttp2_hd_inflater *inflater,
return
0
;
return
0
;
}
}
if
(
inflater
->
index
<
NGHTTP2_STATIC_TABLE_LENGTH
)
{
nghttp2_mem_free
(
mem
,
nv
.
value
);
nghttp2_mem_free
(
mem
,
nv
.
value
);
}
else
{
nghttp2_mem_free
(
mem
,
nv
.
name
);
}
return
NGHTTP2_ERR_NOMEM
;
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
.
name
=
ent_name
->
nv
.
name
;
nv
.
namelen
=
ent_name
->
nv
.
namelen
;
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
);
emit_literal_header
(
nv_out
,
token_out
,
&
nv
);
if
(
nv
.
value
!=
inflater
->
nvbufs
.
head
->
buf
.
pos
)
{
inflater
->
nv_value_keep
=
nv
.
value
;
inflater
->
nv_keep
=
nv
.
value
;
}
return
0
;
return
0
;
}
}
...
@@ -2383,6 +2261,9 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
...
@@ -2383,6 +2261,9 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
uint8_t
*
last
=
in
+
inlen
;
uint8_t
*
last
=
in
+
inlen
;
int
rfin
=
0
;
int
rfin
=
0
;
int
busy
=
0
;
int
busy
=
0
;
nghttp2_mem
*
mem
;
mem
=
inflater
->
ctx
.
mem
;
if
(
inflater
->
ctx
.
bad
)
{
if
(
inflater
->
ctx
.
bad
)
{
return
NGHTTP2_ERR_HEADER_COMP
;
return
NGHTTP2_ERR_HEADER_COMP
;
...
@@ -2541,12 +2422,20 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
...
@@ -2541,12 +2422,20 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_hd_huff_decode_context_init
(
&
inflater
->
huff_decode_ctx
);
nghttp2_hd_huff_decode_context_init
(
&
inflater
->
huff_decode_ctx
);
inflater
->
state
=
NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF
;
inflater
->
state
=
NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF
;
rv
=
nghttp2_buf_reserve
(
&
inflater
->
namebuf
,
inflater
->
left
*
2
+
1
,
mem
);
}
else
{
}
else
{
inflater
->
state
=
NGHTTP2_HD_STATE_NEWNAME_READ_NAME
;
inflater
->
state
=
NGHTTP2_HD_STATE_NEWNAME_READ_NAME
;
rv
=
nghttp2_buf_reserve
(
&
inflater
->
namebuf
,
inflater
->
left
+
1
,
mem
);
}
if
(
rv
!=
0
)
{
goto
fail
;
}
}
break
;
break
;
case
NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF
:
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
)
{
if
(
rv
<
0
)
{
goto
fail
;
goto
fail
;
}
}
...
@@ -2562,18 +2451,13 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
...
@@ -2562,18 +2451,13 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
goto
almost_ok
;
goto
almost_ok
;
}
}
inflater
->
newnamelen
=
nghttp2_bufs_len
(
&
inflater
->
nvbufs
);
*
inflater
->
namebuf
.
last
=
'\0'
;
rv
=
nghttp2_bufs_addb
(
&
inflater
->
nvbufs
,
'\0'
);
if
(
rv
!=
0
)
{
goto
fail
;
}
inflater
->
state
=
NGHTTP2_HD_STATE_CHECK_VALUELEN
;
inflater
->
state
=
NGHTTP2_HD_STATE_CHECK_VALUELEN
;
break
;
break
;
case
NGHTTP2_HD_STATE_NEWNAME_READ_NAME
:
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
)
{
if
(
rv
<
0
)
{
goto
fail
;
goto
fail
;
}
}
...
@@ -2588,12 +2472,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
...
@@ -2588,12 +2472,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
goto
almost_ok
;
goto
almost_ok
;
}
}
inflater
->
newnamelen
=
nghttp2_bufs_len
(
&
inflater
->
nvbufs
);
*
inflater
->
namebuf
.
last
=
'\0'
;
rv
=
nghttp2_bufs_addb
(
&
inflater
->
nvbufs
,
'\0'
);
if
(
rv
!=
0
)
{
goto
fail
;
}
inflater
->
state
=
NGHTTP2_HD_STATE_CHECK_VALUELEN
;
inflater
->
state
=
NGHTTP2_HD_STATE_CHECK_VALUELEN
;
...
@@ -2625,15 +2504,24 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
...
@@ -2625,15 +2504,24 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
nghttp2_hd_huff_decode_context_init
(
&
inflater
->
huff_decode_ctx
);
nghttp2_hd_huff_decode_context_init
(
&
inflater
->
huff_decode_ctx
);
inflater
->
state
=
NGHTTP2_HD_STATE_READ_VALUEHUFF
;
inflater
->
state
=
NGHTTP2_HD_STATE_READ_VALUEHUFF
;
rv
=
nghttp2_buf_reserve
(
&
inflater
->
valuebuf
,
inflater
->
left
*
2
+
1
,
mem
);
}
else
{
}
else
{
inflater
->
state
=
NGHTTP2_HD_STATE_READ_VALUE
;
inflater
->
state
=
NGHTTP2_HD_STATE_READ_VALUE
;
rv
=
nghttp2_buf_reserve
(
&
inflater
->
valuebuf
,
inflater
->
left
+
1
,
mem
);
}
if
(
rv
!=
0
)
{
goto
fail
;
}
}
busy
=
1
;
busy
=
1
;
break
;
break
;
case
NGHTTP2_HD_STATE_READ_VALUEHUFF
:
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
)
{
if
(
rv
<
0
)
{
goto
fail
;
goto
fail
;
}
}
...
@@ -2649,10 +2537,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
...
@@ -2649,10 +2537,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
goto
almost_ok
;
goto
almost_ok
;
}
}
rv
=
nghttp2_bufs_addb
(
&
inflater
->
nvbufs
,
'\0'
);
*
inflater
->
valuebuf
.
last
=
'\0'
;
if
(
rv
!=
0
)
{
goto
fail
;
}
if
(
inflater
->
opcode
==
NGHTTP2_HD_OPCODE_NEWNAME
)
{
if
(
inflater
->
opcode
==
NGHTTP2_HD_OPCODE_NEWNAME
)
{
rv
=
hd_inflate_commit_newname
(
inflater
,
nv_out
,
token_out
);
rv
=
hd_inflate_commit_newname
(
inflater
,
nv_out
,
token_out
);
...
@@ -2669,7 +2554,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
...
@@ -2669,7 +2554,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
return
(
ssize_t
)(
in
-
first
);
return
(
ssize_t
)(
in
-
first
);
case
NGHTTP2_HD_STATE_READ_VALUE
:
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
)
{
if
(
rv
<
0
)
{
DEBUGF
(
fprintf
(
stderr
,
"inflatehd: value read failure %zd: %s
\n
"
,
rv
,
DEBUGF
(
fprintf
(
stderr
,
"inflatehd: value read failure %zd: %s
\n
"
,
rv
,
nghttp2_strerror
((
int
)
rv
)));
nghttp2_strerror
((
int
)
rv
)));
...
@@ -2686,10 +2571,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
...
@@ -2686,10 +2571,7 @@ ssize_t nghttp2_hd_inflate_hd2(nghttp2_hd_inflater *inflater,
goto
almost_ok
;
goto
almost_ok
;
}
}
rv
=
nghttp2_bufs_addb
(
&
inflater
->
nvbufs
,
'\0'
);
*
inflater
->
valuebuf
.
last
=
'\0'
;
if
(
rv
!=
0
)
{
goto
fail
;
}
if
(
inflater
->
opcode
==
NGHTTP2_HD_OPCODE_NEWNAME
)
{
if
(
inflater
->
opcode
==
NGHTTP2_HD_OPCODE_NEWNAME
)
{
rv
=
hd_inflate_commit_newname
(
inflater
,
nv_out
,
token_out
);
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 {
...
@@ -276,7 +276,7 @@ struct nghttp2_hd_deflater {
struct
nghttp2_hd_inflater
{
struct
nghttp2_hd_inflater
{
nghttp2_hd_context
ctx
;
nghttp2_hd_context
ctx
;
/* header buffer */
/* header buffer */
nghttp2_buf
s
nvbufs
;
nghttp2_buf
namebuf
,
valuebuf
;
/* Stores current state of huffman decoding */
/* Stores current state of huffman decoding */
nghttp2_hd_huff_decode_context
huff_decode_ctx
;
nghttp2_hd_huff_decode_context
huff_decode_ctx
;
/* Pointer to the nghttp2_hd_entry which is used current header
/* Pointer to the nghttp2_hd_entry which is used current header
...
@@ -285,14 +285,11 @@ struct nghttp2_hd_inflater {
...
@@ -285,14 +285,11 @@ struct nghttp2_hd_inflater {
nghttp2_hd_entry
*
ent_keep
;
nghttp2_hd_entry
*
ent_keep
;
/* Pointer to the name/value pair buffer which is used in the
/* Pointer to the name/value pair buffer which is used in the
current header emission. */
current header emission. */
uint8_t
*
nv_keep
;
uint8_t
*
nv_
name_keep
,
*
nv_value_
keep
;
/* The number of bytes to read */
/* The number of bytes to read */
size_t
left
;
size_t
left
;
/* The index in indexed repr or indexed name */
/* The index in indexed repr or indexed name */
size_t
index
;
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
/* The maximum header table size the inflater supports. This is the
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
size_t
settings_hd_table_bufsize_max
;
size_t
settings_hd_table_bufsize_max
;
...
@@ -472,9 +469,8 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
...
@@ -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
* Decodes the given data |src| with length |srclen|. The |ctx| must
* be initialized by nghttp2_hd_huff_decode_context_init(). The result
* be initialized by nghttp2_hd_huff_decode_context_init(). The result
* will be added to |dest|. This function may expand |dest| as
* will be written to |buf|. This function assumes that |buf| has the
* needed. The caller is responsible to release the memory of |dest|
* enough room to store the decoded byte string.
* by calling nghttp2_bufs_free().
*
*
* The caller must set the |final| to nonzero if the given input is
* The caller must set the |final| to nonzero if the given input is
* the final block.
* the final block.
...
@@ -486,13 +482,11 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
...
@@ -486,13 +482,11 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
*
*
* NGHTTP2_ERR_NOMEM
* NGHTTP2_ERR_NOMEM
* Out of memory.
* Out of memory.
* NGHTTP2_ERR_BUFFER_ERROR
* Maximum buffer capacity size exceeded.
* NGHTTP2_ERR_HEADER_COMP
* NGHTTP2_ERR_HEADER_COMP
* Decoding process has failed.
* Decoding process has failed.
*/
*/
ssize_t
nghttp2_hd_huff_decode
(
nghttp2_hd_huff_decode_context
*
ctx
,
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
srclen
,
int
final
);
#endif
/* NGHTTP2_HD_H */
#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) {
...
@@ -166,31 +166,10 @@ void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx) {
ctx
->
accept
=
1
;
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
,
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
srclen
,
int
final
)
{
size_t
i
;
size_t
i
;
int
rv
;
size_t
avail
;
avail
=
nghttp2_bufs_cur_avail
(
bufs
);
/* We use the decoding algorithm described in
/* We use the decoding algorithm described in
http://graphics.ics.uci.edu/pub/Prefix.pdf */
http://graphics.ics.uci.edu/pub/Prefix.pdf */
...
@@ -202,8 +181,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
...
@@ -202,8 +181,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
return
NGHTTP2_ERR_HEADER_COMP
;
return
NGHTTP2_ERR_HEADER_COMP
;
}
}
if
(
t
->
flags
&
NGHTTP2_HUFF_SYM
)
{
if
(
t
->
flags
&
NGHTTP2_HUFF_SYM
)
{
/* this is macro, and may return from this function on error */
*
buf
->
last
++
=
t
->
sym
;
hd_huff_decode_sym_emit
(
bufs
,
t
->
sym
,
avail
);
}
}
t
=
&
huff_decode_table
[
t
->
state
][
src
[
i
]
&
0xf
];
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,
...
@@ -211,8 +189,7 @@ ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
return
NGHTTP2_ERR_HEADER_COMP
;
return
NGHTTP2_ERR_HEADER_COMP
;
}
}
if
(
t
->
flags
&
NGHTTP2_HUFF_SYM
)
{
if
(
t
->
flags
&
NGHTTP2_HUFF_SYM
)
{
/* this is macro, and may return from this function on error */
*
buf
->
last
++
=
t
->
sym
;
hd_huff_decode_sym_emit
(
bufs
,
t
->
sym
,
avail
);
}
}
ctx
->
state
=
t
->
state
;
ctx
->
state
=
t
->
state
;
...
...
tests/nghttp2_hd_test.c
View file @
8da20975
...
@@ -1352,13 +1352,15 @@ void test_nghttp2_hd_decode_length(void) {
...
@@ -1352,13 +1352,15 @@ void test_nghttp2_hd_decode_length(void) {
void
test_nghttp2_hd_huff_encode
(
void
)
{
void
test_nghttp2_hd_huff_encode
(
void
)
{
int
rv
;
int
rv
;
ssize_t
len
;
ssize_t
len
;
nghttp2_bufs
bufs
,
outbufs
;
nghttp2_buf
outbuf
;
nghttp2_bufs
bufs
;
nghttp2_hd_huff_decode_context
ctx
;
nghttp2_hd_huff_decode_context
ctx
;
const
uint8_t
t1
[]
=
{
22
,
21
,
20
,
19
,
18
,
17
,
16
,
15
,
14
,
13
,
12
,
11
,
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
};
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
(
&
bufs
);
frame_pack_bufs_init
(
&
outbufs
);
rv
=
nghttp2_hd_huff_encode
(
&
bufs
,
t1
,
sizeof
(
t1
));
rv
=
nghttp2_hd_huff_encode
(
&
bufs
,
t1
,
sizeof
(
t1
));
...
@@ -1366,14 +1368,13 @@ void test_nghttp2_hd_huff_encode(void) {
...
@@ -1366,14 +1368,13 @@ void test_nghttp2_hd_huff_encode(void) {
nghttp2_hd_huff_decode_context_init
(
&
ctx
);
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
);
nghttp2_bufs_len
(
&
bufs
),
1
);
CU_ASSERT
((
ssize_t
)
nghttp2_bufs_len
(
&
bufs
)
==
len
);
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
(
&
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