Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
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
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
2516fb78
Commit
2516fb78
authored
Jun 24, 2015
by
Hans Leidekker
Committed by
Alexandre Julliard
Jun 24, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winhttp: Fix a couple of corner cases in header processing.
parent
49b6b60e
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
99 additions
and
52 deletions
+99
-52
request.c
dlls/winhttp/request.c
+39
-51
winhttp.c
dlls/winhttp/tests/winhttp.c
+60
-1
No files found.
dlls/winhttp/request.c
View file @
2516fb78
...
@@ -327,12 +327,8 @@ static header_t *parse_header( LPCWSTR string )
...
@@ -327,12 +327,8 @@ static header_t *parse_header( LPCWSTR string )
q
++
;
/* skip past colon */
q
++
;
/* skip past colon */
while
(
*
q
==
' '
)
q
++
;
while
(
*
q
==
' '
)
q
++
;
if
(
!*
q
)
{
WARN
(
"no value in line %s
\n
"
,
debugstr_w
(
string
));
return
header
;
}
len
=
strlenW
(
q
);
len
=
strlenW
(
q
);
if
(
!
(
header
->
value
=
heap_alloc
(
(
len
+
1
)
*
sizeof
(
WCHAR
)
)))
if
(
!
(
header
->
value
=
heap_alloc
(
(
len
+
1
)
*
sizeof
(
WCHAR
)
)))
{
{
free_header
(
header
);
free_header
(
header
);
...
@@ -404,76 +400,65 @@ static BOOL delete_header( request_t *request, DWORD index )
...
@@ -404,76 +400,65 @@ static BOOL delete_header( request_t *request, DWORD index )
static
BOOL
process_header
(
request_t
*
request
,
LPCWSTR
field
,
LPCWSTR
value
,
DWORD
flags
,
BOOL
request_only
)
static
BOOL
process_header
(
request_t
*
request
,
LPCWSTR
field
,
LPCWSTR
value
,
DWORD
flags
,
BOOL
request_only
)
{
{
int
index
;
int
index
;
header_t
*
heade
r
;
header_t
hd
r
;
TRACE
(
"%s: %s 0x%08x
\n
"
,
debugstr_w
(
field
),
debugstr_w
(
value
),
flags
);
TRACE
(
"%s: %s 0x%08x
\n
"
,
debugstr_w
(
field
),
debugstr_w
(
value
),
flags
);
/* replace wins out over add */
if
((
index
=
get_header_index
(
request
,
field
,
0
,
request_only
))
>=
0
)
if
(
flags
&
WINHTTP_ADDREQ_FLAG_REPLACE
)
flags
&=
~
WINHTTP_ADDREQ_FLAG_ADD
;
if
(
flags
&
WINHTTP_ADDREQ_FLAG_ADD
)
index
=
-
1
;
else
index
=
get_header_index
(
request
,
field
,
0
,
request_only
);
if
(
index
>=
0
)
{
{
if
(
flags
&
WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
)
return
FALSE
;
if
(
flags
&
WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
)
return
FALSE
;
header
=
&
request
->
headers
[
index
];
}
else
if
(
value
)
{
header_t
hdr
;
hdr
.
field
=
(
LPWSTR
)
field
;
hdr
.
value
=
(
LPWSTR
)
value
;
hdr
.
is_request
=
request_only
;
return
insert_header
(
request
,
&
hdr
);
}
}
/* no value to delete */
else
return
TRUE
;
if
(
flags
&
WINHTTP_ADDREQ_FLAG_REPLACE
)
if
(
flags
&
WINHTTP_ADDREQ_FLAG_REPLACE
)
{
{
if
(
index
>=
0
)
{
delete_header
(
request
,
index
);
delete_header
(
request
,
index
);
if
(
value
)
if
(
!
value
||
!
value
[
0
])
return
TRUE
;
}
else
if
(
!
(
flags
&
WINHTTP_ADDREQ_FLAG_ADD
))
{
{
header_t
hdr
;
set_last_error
(
ERROR_WINHTTP_HEADER_NOT_FOUND
);
return
FALSE
;
}
hdr
.
field
=
(
LPWSTR
)
field
;
hdr
.
field
=
(
LPWSTR
)
field
;
hdr
.
value
=
(
LPWSTR
)
value
;
hdr
.
value
=
(
LPWSTR
)
value
;
hdr
.
is_request
=
request_only
;
hdr
.
is_request
=
request_only
;
return
insert_header
(
request
,
&
hdr
);
return
insert_header
(
request
,
&
hdr
);
}
}
return
TRUE
;
else
if
(
value
)
}
else
if
(
flags
&
(
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
|
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
))
{
{
WCHAR
sep
,
*
tmp
;
int
len
,
orig_len
,
value_len
;
orig_len
=
strlenW
(
header
->
value
);
if
((
flags
&
(
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
|
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
))
&&
value_len
=
strlenW
(
value
);
index
>=
0
)
{
WCHAR
*
tmp
;
int
len
,
len_orig
,
len_value
;
header_t
*
header
=
&
request
->
headers
[
index
];
if
(
flags
&
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
)
sep
=
','
;
len_orig
=
strlenW
(
header
->
value
)
;
else
sep
=
';'
;
len_value
=
strlenW
(
value
)
;
len
=
orig_len
+
value_len
+
2
;
len
=
len_orig
+
len_value
+
2
;
if
((
tmp
=
heap_realloc
(
header
->
value
,
(
len
+
1
)
*
sizeof
(
WCHAR
)
)))
if
(
!
(
tmp
=
heap_realloc
(
header
->
value
,
(
len
+
1
)
*
sizeof
(
WCHAR
)
)))
return
FALSE
;
{
header
->
value
=
tmp
;
header
->
value
=
tmp
;
header
->
value
[
len_orig
++
]
=
(
flags
&
WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
)
?
','
:
';'
;
header
->
value
[
len_orig
++
]
=
' '
;
header
->
value
[
orig_len
]
=
sep
;
memcpy
(
&
header
->
value
[
len_orig
],
value
,
len_value
*
sizeof
(
WCHAR
)
);
orig_len
++
;
header
->
value
[
orig_len
]
=
' '
;
orig_len
++
;
memcpy
(
&
header
->
value
[
orig_len
],
value
,
value_len
*
sizeof
(
WCHAR
)
);
header
->
value
[
len
]
=
0
;
header
->
value
[
len
]
=
0
;
return
TRUE
;
return
TRUE
;
}
}
else
{
hdr
.
field
=
(
LPWSTR
)
field
;
hdr
.
value
=
(
LPWSTR
)
value
;
hdr
.
is_request
=
request_only
;
return
insert_header
(
request
,
&
hdr
);
}
}
}
return
TRUE
;
return
TRUE
;
}
}
...
@@ -2128,7 +2113,9 @@ static BOOL read_reply( request_t *request )
...
@@ -2128,7 +2113,9 @@ static BOOL read_reply( request_t *request )
/* we rely on the fact that the protocol is ascii */
/* we rely on the fact that the protocol is ascii */
MultiByteToWideChar
(
CP_ACP
,
0
,
status_code
,
len
,
status_codeW
,
len
);
MultiByteToWideChar
(
CP_ACP
,
0
,
status_code
,
len
,
status_codeW
,
len
);
status_codeW
[
len
]
=
0
;
status_codeW
[
len
]
=
0
;
if
(
!
(
process_header
(
request
,
attr_status
,
status_codeW
,
WINHTTP_ADDREQ_FLAG_REPLACE
,
FALSE
)))
return
FALSE
;
if
(
!
(
process_header
(
request
,
attr_status
,
status_codeW
,
WINHTTP_ADDREQ_FLAG_ADD
|
WINHTTP_ADDREQ_FLAG_REPLACE
,
FALSE
)))
return
FALSE
;
len
=
status_code
-
buffer
;
len
=
status_code
-
buffer
;
if
(
!
(
versionW
=
heap_alloc
(
len
*
sizeof
(
WCHAR
)
)))
return
FALSE
;
if
(
!
(
versionW
=
heap_alloc
(
len
*
sizeof
(
WCHAR
)
)))
return
FALSE
;
...
@@ -2358,7 +2345,7 @@ static BOOL handle_redirect( request_t *request, DWORD status )
...
@@ -2358,7 +2345,7 @@ static BOOL handle_redirect( request_t *request, DWORD status )
}
}
else
heap_free
(
hostname
);
else
heap_free
(
hostname
);
if
(
!
(
ret
=
add_host_header
(
request
,
WINHTTP_ADDREQ_FLAG_REPLACE
)))
goto
end
;
if
(
!
(
ret
=
add_host_header
(
request
,
WINHTTP_ADDREQ_FLAG_
ADD
|
WINHTTP_ADDREQ_FLAG_
REPLACE
)))
goto
end
;
if
(
!
(
ret
=
open_connection
(
request
)))
goto
end
;
if
(
!
(
ret
=
open_connection
(
request
)))
goto
end
;
heap_free
(
request
->
path
);
heap_free
(
request
->
path
);
...
@@ -3227,7 +3214,8 @@ static HRESULT WINAPI winhttp_request_SetRequestHeader(
...
@@ -3227,7 +3214,8 @@ static HRESULT WINAPI winhttp_request_SetRequestHeader(
goto
done
;
goto
done
;
}
}
sprintfW
(
str
,
fmtW
,
header
,
value
?
value
:
emptyW
);
sprintfW
(
str
,
fmtW
,
header
,
value
?
value
:
emptyW
);
if
(
!
WinHttpAddRequestHeaders
(
request
->
hrequest
,
str
,
len
,
WINHTTP_ADDREQ_FLAG_REPLACE
))
if
(
!
WinHttpAddRequestHeaders
(
request
->
hrequest
,
str
,
len
,
WINHTTP_ADDREQ_FLAG_ADD
|
WINHTTP_ADDREQ_FLAG_REPLACE
))
{
{
err
=
get_last_error
();
err
=
get_last_error
();
}
}
...
...
dlls/winhttp/tests/winhttp.c
View file @
2516fb78
...
@@ -420,6 +420,8 @@ static void test_WinHttpAddHeaders(void)
...
@@ -420,6 +420,8 @@ static void test_WinHttpAddHeaders(void)
{
'P'
,
'O'
,
'S'
,
'T'
,
' '
,
'h'
,
't'
,
't'
,
'p'
,
':'
,
'/'
,
'/'
,
't'
,
'e'
,
's'
,
't'
,
'.'
,
'w'
,
'i'
,
'n'
,
'e'
,
'h'
,
'q'
,
'.'
,
'o'
,
'r'
,
'g'
,
':'
,
'8'
,
'0'
,
'/'
,
'p'
,
'o'
,
's'
,
't'
,
'.'
,
'p'
,
'h'
,
'p'
,
' '
,
'H'
,
'T'
,
'T'
,
'P'
,
'/'
,
'1'
};
{
'P'
,
'O'
,
'S'
,
'T'
,
' '
,
'h'
,
't'
,
't'
,
'p'
,
':'
,
'/'
,
'/'
,
't'
,
'e'
,
's'
,
't'
,
'.'
,
'w'
,
'i'
,
'n'
,
'e'
,
'h'
,
'q'
,
'.'
,
'o'
,
'r'
,
'g'
,
':'
,
'8'
,
'0'
,
'/'
,
'p'
,
'o'
,
's'
,
't'
,
'.'
,
'p'
,
'h'
,
'p'
,
' '
,
'H'
,
'T'
,
'T'
,
'P'
,
'/'
,
'1'
};
static
const
WCHAR
test_header_end
[]
=
{
'\r'
,
'\n'
,
'\r'
,
'\n'
,
0
};
static
const
WCHAR
test_header_end
[]
=
{
'\r'
,
'\n'
,
'\r'
,
'\n'
,
0
};
static
const
WCHAR
test_header_name
[]
=
{
'W'
,
'a'
,
'r'
,
'n'
,
'i'
,
'n'
,
'g'
,
0
};
static
const
WCHAR
test_header_name
[]
=
{
'W'
,
'a'
,
'r'
,
'n'
,
'i'
,
'n'
,
'g'
,
0
};
static
const
WCHAR
test_header_name2
[]
=
{
'n'
,
'a'
,
'm'
,
'e'
,
0
};
static
const
WCHAR
test_header_name3
[]
=
{
'a'
,
0
};
static
const
WCHAR
test_header_range
[]
=
{
'R'
,
'a'
,
'n'
,
'g'
,
'e'
,
0
};
static
const
WCHAR
test_header_range
[]
=
{
'R'
,
'a'
,
'n'
,
'g'
,
'e'
,
0
};
static
const
WCHAR
test_header_range_bytes
[]
=
{
'R'
,
'a'
,
'n'
,
'g'
,
'e'
,
':'
,
' '
,
'b'
,
'y'
,
't'
,
'e'
,
's'
,
'='
,
'0'
,
'-'
,
'7'
,
'7'
,
'3'
,
'\r'
,
'\n'
,
0
};
static
const
WCHAR
test_header_range_bytes
[]
=
{
'R'
,
'a'
,
'n'
,
'g'
,
'e'
,
':'
,
' '
,
'b'
,
'y'
,
't'
,
'e'
,
's'
,
'='
,
'0'
,
'-'
,
'7'
,
'7'
,
'3'
,
'\r'
,
'\n'
,
0
};
static
const
WCHAR
test_header_bytes
[]
=
{
'b'
,
'y'
,
't'
,
'e'
,
's'
,
'='
,
'0'
,
'-'
,
'7'
,
'7'
,
'3'
,
0
};
static
const
WCHAR
test_header_bytes
[]
=
{
'b'
,
'y'
,
't'
,
'e'
,
's'
,
'='
,
'0'
,
'-'
,
'7'
,
'7'
,
'3'
,
0
};
...
@@ -438,6 +440,7 @@ static void test_WinHttpAddHeaders(void)
...
@@ -438,6 +440,7 @@ static void test_WinHttpAddHeaders(void)
static
const
WCHAR
field
[]
=
{
'f'
,
'i'
,
'e'
,
'l'
,
'd'
,
0
};
static
const
WCHAR
field
[]
=
{
'f'
,
'i'
,
'e'
,
'l'
,
'd'
,
0
};
static
const
WCHAR
value
[]
=
{
'v'
,
'a'
,
'l'
,
'u'
,
'e'
,
' '
,
0
};
static
const
WCHAR
value
[]
=
{
'v'
,
'a'
,
'l'
,
'u'
,
'e'
,
' '
,
0
};
static
const
WCHAR
value_nospace
[]
=
{
'v'
,
'a'
,
'l'
,
'u'
,
'e'
,
0
};
static
const
WCHAR
value_nospace
[]
=
{
'v'
,
'a'
,
'l'
,
'u'
,
'e'
,
0
};
static
const
WCHAR
empty
[]
=
{
0
};
static
const
WCHAR
test_headers
[][
14
]
=
static
const
WCHAR
test_headers
[][
14
]
=
{
{
...
@@ -454,7 +457,9 @@ static void test_WinHttpAddHeaders(void)
...
@@ -454,7 +457,9 @@ static void test_WinHttpAddHeaders(void)
{
':'
,
'b'
,
0
},
{
':'
,
'b'
,
0
},
{
'c'
,
'd'
,
0
},
{
'c'
,
'd'
,
0
},
{
' '
,
'e'
,
' '
,
':'
,
'f'
,
0
},
{
' '
,
'e'
,
' '
,
':'
,
'f'
,
0
},
{
'f'
,
'i'
,
'e'
,
'l'
,
'd'
,
':'
,
' '
,
'v'
,
'a'
,
'l'
,
'u'
,
'e'
,
' '
,
0
}
{
'f'
,
'i'
,
'e'
,
'l'
,
'd'
,
':'
,
' '
,
'v'
,
'a'
,
'l'
,
'u'
,
'e'
,
' '
,
0
},
{
'n'
,
'a'
,
'm'
,
'e'
,
':'
,
' '
,
'v'
,
'a'
,
'l'
,
'u'
,
'e'
,
0
},
{
'n'
,
'a'
,
'm'
,
'e'
,
':'
,
0
}
};
};
static
const
WCHAR
test_indices
[][
6
]
=
static
const
WCHAR
test_indices
[][
6
]
=
{
{
...
@@ -763,6 +768,14 @@ static void test_WinHttpAddHeaders(void)
...
@@ -763,6 +768,14 @@ static void test_WinHttpAddHeaders(void)
ret
=
WinHttpAddRequestHeaders
(
request
,
test_headers
[
9
],
~
0u
,
WINHTTP_ADDREQ_FLAG_ADD
);
ret
=
WinHttpAddRequestHeaders
(
request
,
test_headers
[
9
],
~
0u
,
WINHTTP_ADDREQ_FLAG_ADD
);
ok
(
ret
,
"WinHttpAddRequestHeaders failed
\n
"
);
ok
(
ret
,
"WinHttpAddRequestHeaders failed
\n
"
);
index
=
0
;
memset
(
buffer
,
0xff
,
sizeof
(
buffer
));
len
=
sizeof
(
buffer
);
ret
=
WinHttpQueryHeaders
(
request
,
WINHTTP_QUERY_CUSTOM
|
WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
test_header_name3
,
buffer
,
&
len
,
&
index
);
ok
(
ret
,
"WinHttpQueryHeaders failed: %u
\n
"
,
GetLastError
());
ok
(
!
memcmp
(
buffer
,
empty
,
sizeof
(
empty
)),
"unexpected result
\n
"
);
ret
=
WinHttpAddRequestHeaders
(
request
,
test_headers
[
10
],
~
0u
,
WINHTTP_ADDREQ_FLAG_ADD
);
ret
=
WinHttpAddRequestHeaders
(
request
,
test_headers
[
10
],
~
0u
,
WINHTTP_ADDREQ_FLAG_ADD
);
ok
(
!
ret
,
"WinHttpAddRequestHeaders failed
\n
"
);
ok
(
!
ret
,
"WinHttpAddRequestHeaders failed
\n
"
);
...
@@ -803,6 +816,52 @@ static void test_WinHttpAddHeaders(void)
...
@@ -803,6 +816,52 @@ static void test_WinHttpAddHeaders(void)
ok
(
len
==
lstrlenW
(
test_header_bytes
)
*
sizeof
(
WCHAR
),
"wrong length %u
\n
"
,
len
);
ok
(
len
==
lstrlenW
(
test_header_bytes
)
*
sizeof
(
WCHAR
),
"wrong length %u
\n
"
,
len
);
ok
(
index
==
1
,
"wrong index %u
\n
"
,
index
);
ok
(
index
==
1
,
"wrong index %u
\n
"
,
index
);
index
=
0
;
len
=
sizeof
(
buffer
);
ret
=
WinHttpQueryHeaders
(
request
,
WINHTTP_QUERY_CUSTOM
|
WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
test_header_name2
,
buffer
,
&
len
,
&
index
);
ok
(
!
ret
,
"unexpected success
\n
"
);
SetLastError
(
0xdeadbeef
);
ret
=
WinHttpAddRequestHeaders
(
request
,
test_headers
[
14
],
~
0u
,
WINHTTP_ADDREQ_FLAG_REPLACE
);
err
=
GetLastError
();
ok
(
!
ret
,
"unexpected success
\n
"
);
ok
(
err
==
ERROR_WINHTTP_HEADER_NOT_FOUND
,
"got %u
\n
"
,
err
);
ret
=
WinHttpAddRequestHeaders
(
request
,
test_headers
[
14
],
~
0u
,
WINHTTP_ADDREQ_FLAG_ADD
);
ok
(
ret
,
"got %u
\n
"
,
GetLastError
());
index
=
0
;
len
=
sizeof
(
buffer
);
ret
=
WinHttpQueryHeaders
(
request
,
WINHTTP_QUERY_CUSTOM
|
WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
test_header_name2
,
buffer
,
&
len
,
&
index
);
ok
(
ret
,
"got %u
\n
"
,
GetLastError
());
ok
(
index
==
1
,
"wrong index %u
\n
"
,
index
);
ok
(
!
memcmp
(
buffer
,
value_nospace
,
sizeof
(
value_nospace
)),
"incorrect string
\n
"
);
ret
=
WinHttpAddRequestHeaders
(
request
,
test_headers
[
15
],
~
0u
,
WINHTTP_ADDREQ_FLAG_REPLACE
);
ok
(
ret
,
"got %u
\n
"
,
GetLastError
());
index
=
0
;
len
=
sizeof
(
buffer
);
SetLastError
(
0xdeadbeef
);
ret
=
WinHttpQueryHeaders
(
request
,
WINHTTP_QUERY_CUSTOM
|
WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
test_header_name2
,
buffer
,
&
len
,
&
index
);
err
=
GetLastError
();
ok
(
!
ret
,
"unexpected success
\n
"
);
ok
(
err
==
ERROR_WINHTTP_HEADER_NOT_FOUND
,
"got %u
\n
"
,
err
);
ret
=
WinHttpAddRequestHeaders
(
request
,
test_headers
[
14
],
-
1L
,
0
);
ok
(
ret
,
"got %u
\n
"
,
GetLastError
());
index
=
0
;
len
=
sizeof
(
buffer
);
ret
=
WinHttpQueryHeaders
(
request
,
WINHTTP_QUERY_CUSTOM
|
WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
test_header_name2
,
buffer
,
&
len
,
&
index
);
ok
(
ret
,
"got %u
\n
"
,
GetLastError
());
ok
(
index
==
1
,
"wrong index %u
\n
"
,
index
);
ok
(
!
memcmp
(
buffer
,
value_nospace
,
sizeof
(
value_nospace
)),
"incorrect string
\n
"
);
ret
=
WinHttpCloseHandle
(
request
);
ret
=
WinHttpCloseHandle
(
request
);
ok
(
ret
==
TRUE
,
"WinHttpCloseHandle failed on closing request, got %d.
\n
"
,
ret
);
ok
(
ret
==
TRUE
,
"WinHttpCloseHandle failed on closing request, got %d.
\n
"
,
ret
);
done:
done:
...
...
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