X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FLibrary%2FDxeHttpLib%2FDxeHttpLib.c;h=8b74554cd96157b2cb788b1c32f9c50a6664ef9f;hp=774bf7d7e56a39fd3b9e4226b16c264f8e4ef2eb;hb=c0fd7f734e2d33e22215899b40a47b843129541d;hpb=f5168b847d8d374fc0206603c7479a3c7ed5fbb0
diff --git a/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.c b/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.c
index 774bf7d7e5..8b74554cd9 100644
--- a/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.c
+++ b/MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.c
@@ -2,15 +2,9 @@
This library is used to share code between UEFI network stack modules.
It provides the helper routines to parse the HTTP message byte stream.
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -20,10 +14,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
/**
Decode a percent-encoded URI component to the ASCII character.
-
- Decode the input component in Buffer according to RFC 3986. The caller is responsible to make
+
+ Decode the input component in Buffer according to RFC 3986. The caller is responsible to make
sure ResultBuffer points to a buffer with size equal or greater than ((AsciiStrSize (Buffer))
- in bytes.
+ in bytes.
@param[in] Buffer The pointer to a percent-encoded URI component.
@param[in] BufferLength Length of Buffer in bytes.
@@ -32,7 +26,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@retval EFI_SUCCESS Successfully decoded the URI.
@retval EFI_INVALID_PARAMETER Buffer is not a valid percent-encoded string.
-
+
**/
EFI_STATUS
EFIAPI
@@ -50,13 +44,14 @@ UriPercentDecode (
if (Buffer == NULL || BufferLength == 0 || ResultBuffer == NULL) {
return EFI_INVALID_PARAMETER;
}
-
+
Index = 0;
Offset = 0;
HexStr[2] = '\0';
while (Index < BufferLength) {
if (Buffer[Index] == '%') {
- if (Index + 1 >= BufferLength || Index + 2 >= BufferLength || !NET_IS_HEX_CHAR (Buffer[Index+1]) || !NET_IS_HEX_CHAR (Buffer[Index+2])) {
+ if (Index + 1 >= BufferLength || Index + 2 >= BufferLength ||
+ !NET_IS_HEX_CHAR (Buffer[Index+1]) || !NET_IS_HEX_CHAR (Buffer[Index+2])) {
return EFI_INVALID_PARAMETER;
}
HexStr[0] = Buffer[Index+1];
@@ -71,7 +66,7 @@ UriPercentDecode (
}
*ResultLength = (UINT32) Offset;
-
+
return EFI_SUCCESS;
}
@@ -81,8 +76,8 @@ UriPercentDecode (
@param[in] Char Next character.
@param[in] State Current value of the parser state machine.
- @param[in] IsRightBracket TRUE if there is an sign ']' in the authority component and
- indicates the next part is ':' before Port.
+ @param[in] IsRightBracket TRUE if there is an sign ']' in the authority component and
+ indicates the next part is ':' before Port.
@return Updated state value.
**/
@@ -115,27 +110,27 @@ NetHttpParseAuthorityChar (
break;
case UrlParserHost:
- case UrlParserHostStart:
+ case UrlParserHostStart:
if (Char == '[') {
return UrlParserHostIpv6;
}
-
+
if (Char == ':') {
return UrlParserPortStart;
}
-
+
return UrlParserHost;
-
- case UrlParserHostIpv6:
+
+ case UrlParserHostIpv6:
if (Char == ']') {
*IsRightBracket = TRUE;
}
-
+
if (Char == ':' && *IsRightBracket) {
return UrlParserPortStart;
}
return UrlParserHostIpv6;
-
+
case UrlParserPort:
case UrlParserPortStart:
return UrlParserPort;
@@ -155,7 +150,7 @@ NetHttpParseAuthorityChar (
@param[in, out] UrlParser Pointer to the buffer of the parse result.
@retval EFI_SUCCESS Successfully parse the authority.
- @retval Other Error happened.
+ @retval EFI_INVALID_PARAMETER The Url is invalid to parse the authority component.
**/
EFI_STATUS
@@ -172,7 +167,7 @@ NetHttpParseAuthority (
UINT32 Field;
UINT32 OldField;
BOOLEAN IsrightBracket;
-
+
ASSERT ((UrlParser->FieldBitMap & BIT (HTTP_URI_FIELD_AUTHORITY)) != 0);
//
@@ -202,7 +197,7 @@ NetHttpParseAuthority (
case UrlParserUserInfo:
Field = HTTP_URI_FIELD_USERINFO;
break;
-
+
case UrlParserHost:
Field = HTTP_URI_FIELD_HOST;
break;
@@ -210,7 +205,7 @@ NetHttpParseAuthority (
case UrlParserHostIpv6:
Field = HTTP_URI_FIELD_HOST;
break;
-
+
case UrlParserPort:
Field = HTTP_URI_FIELD_PORT;
break;
@@ -258,12 +253,12 @@ NetHttpParseUrlChar (
if (Char == ' ' || Char == '\r' || Char == '\n') {
return UrlParserStateMax;
}
-
+
//
// http_URL = "http:" "//" host [ ":" port ] [ abs_path [ "?" query ]]
- //
+ //
// Request-URI = "*" | absolute-URI | path-absolute | authority
- //
+ //
// absolute-URI = scheme ":" hier-part [ "?" query ]
// path-absolute = "/" [ segment-nz *( "/" segment ) ]
// authority = [ userinfo "@" ] host [ ":" port ]
@@ -332,7 +327,7 @@ NetHttpParseUrlChar (
case UrlParserFragmentStart:
return UrlParserFragment;
-
+
default:
break;
}
@@ -374,7 +369,7 @@ HttpParseUrl (
HTTP_URL_PARSER *Parser;
Parser = NULL;
-
+
if (Url == NULL || Length == 0 || UrlParser == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -383,7 +378,7 @@ HttpParseUrl (
if (Parser == NULL) {
return EFI_OUT_OF_RESOURCES;
}
-
+
if (IsConnectMethod) {
//
// According to RFC 2616, the authority form is only used by the CONNECT method.
@@ -406,7 +401,7 @@ HttpParseUrl (
case UrlParserStateMax:
FreePool (Parser);
return EFI_INVALID_PARAMETER;
-
+
case UrlParserSchemeColon:
case UrlParserSchemeColonSlash:
case UrlParserSchemeColonSlashSlash:
@@ -416,7 +411,7 @@ HttpParseUrl (
// Skip all the delimiting char: "://" "?" "@"
//
continue;
-
+
case UrlParserScheme:
Field = HTTP_URI_FIELD_SCHEME;
break;
@@ -473,7 +468,7 @@ HttpParseUrl (
}
*UrlParser = Parser;
- return EFI_SUCCESS;
+ return EFI_SUCCESS;
}
/**
@@ -490,7 +485,7 @@ HttpParseUrl (
@retval EFI_INVALID_PARAMETER Uri is NULL or HostName is NULL or UrlParser is invalid.
@retval EFI_NOT_FOUND No hostName component in the URL.
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
-
+
**/
EFI_STATUS
EFIAPI
@@ -509,7 +504,7 @@ HttpUrlGetHostName (
return EFI_INVALID_PARAMETER;
}
- Parser = (HTTP_URL_PARSER*) UrlParser;
+ Parser = (HTTP_URL_PARSER *) UrlParser;
if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) {
return EFI_NOT_FOUND;
@@ -519,7 +514,7 @@ HttpUrlGetHostName (
if (Name == NULL) {
return EFI_OUT_OF_RESOURCES;
}
-
+
Status = UriPercentDecode (
Url + Parser->FieldData[HTTP_URI_FIELD_HOST].Offset,
Parser->FieldData[HTTP_URI_FIELD_HOST].Length,
@@ -550,7 +545,7 @@ HttpUrlGetHostName (
@retval EFI_INVALID_PARAMETER Uri is NULL or Ip4Address is NULL or UrlParser is invalid.
@retval EFI_NOT_FOUND No IPv4 address component in the URL.
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
-
+
**/
EFI_STATUS
EFIAPI
@@ -564,22 +559,22 @@ HttpUrlGetIp4 (
EFI_STATUS Status;
UINT32 ResultLength;
HTTP_URL_PARSER *Parser;
-
+
if (Url == NULL || UrlParser == NULL || Ip4Address == NULL) {
return EFI_INVALID_PARAMETER;
}
- Parser = (HTTP_URL_PARSER*) UrlParser;
+ Parser = (HTTP_URL_PARSER *) UrlParser;
if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) {
- return EFI_INVALID_PARAMETER;
+ return EFI_NOT_FOUND;
}
Ip4String = AllocatePool (Parser->FieldData[HTTP_URI_FIELD_HOST].Length + 1);
if (Ip4String == NULL) {
return EFI_OUT_OF_RESOURCES;
}
-
+
Status = UriPercentDecode (
Url + Parser->FieldData[HTTP_URI_FIELD_HOST].Offset,
Parser->FieldData[HTTP_URI_FIELD_HOST].Length,
@@ -611,7 +606,7 @@ HttpUrlGetIp4 (
@retval EFI_INVALID_PARAMETER Uri is NULL or Ip6Address is NULL or UrlParser is invalid.
@retval EFI_NOT_FOUND No IPv6 address component in the URL.
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
-
+
**/
EFI_STATUS
EFIAPI
@@ -627,15 +622,15 @@ HttpUrlGetIp6 (
EFI_STATUS Status;
UINT32 ResultLength;
HTTP_URL_PARSER *Parser;
-
+
if (Url == NULL || UrlParser == NULL || Ip6Address == NULL) {
return EFI_INVALID_PARAMETER;
}
- Parser = (HTTP_URL_PARSER*) UrlParser;
+ Parser = (HTTP_URL_PARSER *) UrlParser;
if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_HOST)) == 0) {
- return EFI_INVALID_PARAMETER;
+ return EFI_NOT_FOUND;
}
//
@@ -655,7 +650,7 @@ HttpUrlGetIp6 (
if (Ip6String == NULL) {
return EFI_OUT_OF_RESOURCES;
}
-
+
Status = UriPercentDecode (
Ptr + 1,
Length - 2,
@@ -666,7 +661,7 @@ HttpUrlGetIp6 (
FreePool (Ip6String);
return Status;
}
-
+
Ip6String[ResultLength] = '\0';
Status = NetLibAsciiStrToIp6 (Ip6String, Ip6Address);
FreePool (Ip6String);
@@ -687,7 +682,7 @@ HttpUrlGetIp6 (
@retval EFI_INVALID_PARAMETER Uri is NULL or Port is NULL or UrlParser is invalid.
@retval EFI_NOT_FOUND No port number in the URL.
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
-
+
**/
EFI_STATUS
EFIAPI
@@ -697,11 +692,11 @@ HttpUrlGetPort (
OUT UINT16 *Port
)
{
- CHAR8 *PortString;
- EFI_STATUS Status;
- UINTN Index;
- UINTN Data;
- UINT32 ResultLength;
+ CHAR8 *PortString;
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN Data;
+ UINT32 ResultLength;
HTTP_URL_PARSER *Parser;
if (Url == NULL || UrlParser == NULL || Port == NULL) {
@@ -711,10 +706,10 @@ HttpUrlGetPort (
*Port = 0;
Index = 0;
- Parser = (HTTP_URL_PARSER*) UrlParser;
+ Parser = (HTTP_URL_PARSER *) UrlParser;
if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_PORT)) == 0) {
- return EFI_INVALID_PARAMETER;
+ return EFI_NOT_FOUND;
}
PortString = AllocatePool (Parser->FieldData[HTTP_URI_FIELD_PORT].Length + 1);
@@ -770,7 +765,7 @@ ON_EXIT:
@retval EFI_INVALID_PARAMETER Uri is NULL or HostName is NULL or UrlParser is invalid.
@retval EFI_NOT_FOUND No hostName component in the URL.
@retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
-
+
**/
EFI_STATUS
EFIAPI
@@ -789,7 +784,7 @@ HttpUrlGetPath (
return EFI_INVALID_PARAMETER;
}
- Parser = (HTTP_URL_PARSER*) UrlParser;
+ Parser = (HTTP_URL_PARSER *) UrlParser;
if ((Parser->FieldBitMap & BIT (HTTP_URI_FIELD_PATH)) == 0) {
return EFI_NOT_FOUND;
@@ -799,7 +794,7 @@ HttpUrlGetPath (
if (PathStr == NULL) {
return EFI_OUT_OF_RESOURCES;
}
-
+
Status = UriPercentDecode (
Url + Parser->FieldData[HTTP_URI_FIELD_PATH].Offset,
Parser->FieldData[HTTP_URI_FIELD_PATH].Length,
@@ -820,7 +815,7 @@ HttpUrlGetPath (
Release the resource of the URL parser.
@param[in] UrlParser Pointer to the parser.
-
+
**/
VOID
EFIAPI
@@ -834,9 +829,9 @@ HttpUrlFreeParser (
/**
Find a specified header field according to the field name.
- @param[in] HeaderCount Number of HTTP header structures in Headers list.
+ @param[in] HeaderCount Number of HTTP header structures in Headers list.
@param[in] Headers Array containing list of HTTP headers.
- @param[in] FieldName Null terminated string which describes a field name.
+ @param[in] FieldName Null terminated string which describes a field name.
@return Pointer to the found header or NULL.
@@ -897,27 +892,6 @@ typedef struct {
UINTN CurrentChunkParsedSize;
} HTTP_BODY_PARSER;
-/**
-
- Convert an Ascii char to its uppercase.
-
- @param[in] Char Ascii character.
-
- @return Uppercase value of the input Char.
-
-**/
-CHAR8
-HttpIoCharToUpper (
- IN CHAR8 Char
- )
-{
- if (Char >= 'a' && Char <= 'z') {
- return Char - ('a' - 'A');
- }
-
- return Char;
-}
-
/**
Convert an hexadecimal char to a value of type UINTN.
@@ -935,7 +909,7 @@ HttpIoHexCharToUintn (
return Char - '0';
}
- return (10 + HttpIoCharToUpper (Char) - 'A');
+ return (10 + AsciiCharToUpper (Char) - 'A');
}
/**
@@ -974,7 +948,7 @@ HttpIoParseContentLengthHeader (
@param[in] Headers Array containing list of HTTP headers.
@return The message is "chunked" transfer-coding (TRUE) or not (FALSE).
-
+
**/
BOOLEAN
HttpIoIsChunked (
@@ -1071,7 +1045,7 @@ HttpInitMsgParser (
{
EFI_STATUS Status;
HTTP_BODY_PARSER *Parser;
-
+
if (HeaderCount != 0 && Headers == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -1086,7 +1060,7 @@ HttpInitMsgParser (
}
Parser->State = BodyParserBodyStart;
-
+
//
// Determine the message length according to RFC 2616.
// 1. Check whether the message "MUST NOT" have a message-body.
@@ -1107,7 +1081,7 @@ HttpInitMsgParser (
// 4. Range header is not supported now, so we won't meet media type "multipart/byteranges".
// 5. By server closing the connection
//
-
+
//
// Set state to skip body parser if the message shouldn't have a message body.
//
@@ -1133,7 +1107,8 @@ HttpInitMsgParser (
@retval EFI_SUCCESS Successfully parse the message-body.
@retval EFI_INVALID_PARAMETER MsgParser is NULL or Body is NULL or BodyLength is 0.
- @retval Others Operation aborted.
+ @retval EFI_ABORTED Operation aborted.
+ @retval Other Error happened while parsing message body.
**/
EFI_STATUS
@@ -1149,7 +1124,7 @@ HttpParseMessageBody (
UINTN LengthForCallback;
EFI_STATUS Status;
HTTP_BODY_PARSER *Parser;
-
+
if (BodyLength == 0 || Body == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -1158,17 +1133,17 @@ HttpParseMessageBody (
return EFI_INVALID_PARAMETER;
}
- Parser = (HTTP_BODY_PARSER*) MsgParser;
+ Parser = (HTTP_BODY_PARSER *) MsgParser;
if (Parser->IgnoreBody) {
Parser->State = BodyParserComplete;
if (Parser->Callback != NULL) {
Status = Parser->Callback (
- BodyParseEventOnComplete,
- Body,
- 0,
- Parser->Context
- );
+ BodyParseEventOnComplete,
+ Body,
+ 0,
+ Parser->Context
+ );
if (EFI_ERROR (Status)) {
return Status;
}
@@ -1193,18 +1168,18 @@ HttpParseMessageBody (
switch (Parser->State) {
case BodyParserStateMax:
return EFI_ABORTED;
-
+
case BodyParserBodyIdentity:
//
// Identity transfer-coding, just notify user to save the body data.
//
if (Parser->Callback != NULL) {
Status = Parser->Callback (
- BodyParseEventOnData,
- Char,
- MIN (BodyLength, Parser->ContentLength - Parser->ParsedBodyLength),
- Parser->Context
- );
+ BodyParseEventOnData,
+ Char,
+ MIN (BodyLength, Parser->ContentLength - Parser->ParsedBodyLength),
+ Parser->Context
+ );
if (EFI_ERROR (Status)) {
return Status;
}
@@ -1215,11 +1190,11 @@ HttpParseMessageBody (
Parser->State = BodyParserComplete;
if (Parser->Callback != NULL) {
Status = Parser->Callback (
- BodyParseEventOnComplete,
- Char,
- 0,
- Parser->Context
- );
+ BodyParseEventOnComplete,
+ Char,
+ 0,
+ Parser->Context
+ );
if (EFI_ERROR (Status)) {
return Status;
}
@@ -1263,7 +1238,7 @@ HttpParseMessageBody (
}
Char++;
break;
-
+
case BodyParserChunkSizeEndCR:
if (*Char != '\n') {
Parser->State = BodyParserStateMax;
@@ -1272,7 +1247,7 @@ HttpParseMessageBody (
Char++;
if (Parser->CurrentChunkSize == 0) {
//
- // The last chunk has been parsed and now assumed the state
+ // The last chunk has been parsed and now assumed the state
// of HttpBodyParse is ParserLastCRLF. So it need to decide
// whether the rest message is trailer or last CRLF in the next round.
//
@@ -1283,10 +1258,10 @@ HttpParseMessageBody (
Parser->State = BodyParserChunkDataStart;
Parser->CurrentChunkParsedSize = 0;
break;
-
+
case BodyParserLastCRLF:
//
- // Judge the byte is belong to the Last CRLF or trailer, and then
+ // Judge the byte is belong to the Last CRLF or trailer, and then
// configure the state of HttpBodyParse to corresponding state.
//
if (*Char == '\r') {
@@ -1297,18 +1272,18 @@ HttpParseMessageBody (
Parser->State = BodyParserTrailer;
break;
}
-
+
case BodyParserLastCRLFEnd:
if (*Char == '\n') {
Parser->State = BodyParserComplete;
Char++;
if (Parser->Callback != NULL) {
Status = Parser->Callback (
- BodyParseEventOnComplete,
- Char,
- 0,
- Parser->Context
- );
+ BodyParseEventOnComplete,
+ Char,
+ 0,
+ Parser->Context
+ );
if (EFI_ERROR (Status)) {
return Status;
}
@@ -1318,13 +1293,13 @@ HttpParseMessageBody (
Parser->State = BodyParserStateMax;
break;
}
-
+
case BodyParserTrailer:
if (*Char == '\r') {
Parser->State = BodyParserChunkSizeEndCR;
}
Char++;
- break;
+ break;
case BodyParserChunkDataStart:
//
@@ -1334,11 +1309,11 @@ HttpParseMessageBody (
LengthForCallback = MIN (Parser->CurrentChunkSize - Parser->CurrentChunkParsedSize, RemainderLengthInThis);
if (Parser->Callback != NULL) {
Status = Parser->Callback (
- BodyParseEventOnData,
- Char,
- LengthForCallback,
- Parser->Context
- );
+ BodyParseEventOnData,
+ Char,
+ LengthForCallback,
+ Parser->Context
+ );
if (EFI_ERROR (Status)) {
return Status;
}
@@ -1348,7 +1323,7 @@ HttpParseMessageBody (
Parser->CurrentChunkParsedSize += LengthForCallback;
if (Parser->CurrentChunkParsedSize == Parser->CurrentChunkSize) {
Parser->State = BodyParserChunkDataEnd;
- }
+ }
break;
case BodyParserChunkDataEnd:
@@ -1367,7 +1342,7 @@ HttpParseMessageBody (
}
Char++;
Parser->State = BodyParserChunkSizeStart;
- break;
+ break;
default:
break;
@@ -1399,7 +1374,11 @@ HttpIsMessageComplete (
{
HTTP_BODY_PARSER *Parser;
- Parser = (HTTP_BODY_PARSER*) MsgParser;
+ if (MsgParser == NULL) {
+ return FALSE;
+ }
+
+ Parser = (HTTP_BODY_PARSER *) MsgParser;
if (Parser->State == BodyParserComplete) {
return TRUE;
@@ -1418,7 +1397,7 @@ HttpIsMessageComplete (
@retval EFI_SUCCESS Successfully to get the entity length.
@retval EFI_NOT_READY Entity length is not valid yet.
@retval EFI_INVALID_PARAMETER MsgParser is NULL or ContentLength is NULL.
-
+
**/
EFI_STATUS
EFIAPI
@@ -1433,7 +1412,7 @@ HttpGetEntityLength (
return EFI_INVALID_PARAMETER;
}
- Parser = (HTTP_BODY_PARSER*) MsgParser;
+ Parser = (HTTP_BODY_PARSER *) MsgParser;
if (!Parser->ContentLengthIsValid) {
return EFI_NOT_READY;
@@ -1447,7 +1426,7 @@ HttpGetEntityLength (
Release the resource of the message parser.
@param[in] MsgParser Pointer to the message parser.
-
+
**/
VOID
EFIAPI
@@ -1471,7 +1450,6 @@ HttpFreeMsgParser (
**/
CHAR8 *
-EFIAPI
AsciiStrGetNextToken (
IN CONST CHAR8 *String,
IN CHAR8 Separator
@@ -1500,6 +1478,7 @@ AsciiStrGetNextToken (
@retval EFI_SUCCESS The FieldName and FieldValue are set into HttpHeader successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
**/
@@ -1514,6 +1493,10 @@ HttpSetFieldNameAndValue (
UINTN FieldNameSize;
UINTN FieldValueSize;
+ if (HttpHeader == NULL || FieldName == NULL || FieldValue == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
if (HttpHeader->FieldName != NULL) {
FreePool (HttpHeader->FieldName);
}
@@ -1587,6 +1570,18 @@ HttpGetFieldNameAndValue (
//
// Each header field consists of a name followed by a colon (":") and the field value.
+ // The field value MAY be preceded by any amount of LWS, though a single SP is preferred.
+ //
+ // message-header = field-name ":" [ field-value ]
+ // field-name = token
+ // field-value = *( field-content | LWS )
+ //
+ // Note: "*(element)" allows any number element, including zero; "1*(element)" requires at least one element.
+ // [element] means element is optional.
+ // LWS = [CRLF] 1*(SP|HT), it can be ' ' or '\t' or '\r\n ' or '\r\n\t'.
+ // CRLF = '\r\n'.
+ // SP = ' '.
+ // HT = '\t' (Tab).
//
FieldNameStr = String;
FieldValueStr = AsciiStrGetNextToken (FieldNameStr, ':');
@@ -1595,51 +1590,70 @@ HttpGetFieldNameAndValue (
}
//
- // Replace ':' with 0
+ // Replace ':' with 0, then FieldName has been retrived from String.
//
*(FieldValueStr - 1) = 0;
//
- // The field value MAY be preceded by any amount of LWS, though a single SP is preferred.
- // Note: LWS = [CRLF] 1*(SP|HT), it can be '\r\n ' or '\r\n\t' or ' ' or '\t'.
- // CRLF = '\r\n'.
- // SP = ' '.
- // HT = '\t' (Tab).
+ // Handle FieldValueStr, skip all the preceded LWS.
//
while (TRUE) {
if (*FieldValueStr == ' ' || *FieldValueStr == '\t') {
//
- // Boundary condition check.
+ // Boundary condition check.
//
- if ((UINTN)EndofHeader - (UINTN)(FieldValueStr) < 1) {
- return NULL;
+ if ((UINTN) EndofHeader - (UINTN) FieldValueStr < 1) {
+ //
+ // Wrong String format!
+ //
+ return NULL;
}
-
+
FieldValueStr ++;
} else if (*FieldValueStr == '\r') {
//
- // Boundary condition check.
+ // Boundary condition check.
//
- if ((UINTN)EndofHeader - (UINTN)(FieldValueStr) < 3) {
- return NULL;
+ if ((UINTN) EndofHeader - (UINTN) FieldValueStr < 3) {
+ //
+ // No more preceded LWS, so break here.
+ //
+ break;
}
- if (*(FieldValueStr + 1) == '\n' && (*(FieldValueStr + 2) == ' ' || *(FieldValueStr + 2) == '\t')) {
- FieldValueStr = FieldValueStr + 3;
+ if (*(FieldValueStr + 1) == '\n' ) {
+ if (*(FieldValueStr + 2) == ' ' || *(FieldValueStr + 2) == '\t') {
+ FieldValueStr = FieldValueStr + 3;
+ } else {
+ //
+ // No more preceded LWS, so break here.
+ //
+ break;
+ }
+ } else {
+ //
+ // Wrong String format!
+ //
+ return NULL;
}
} else {
+ //
+ // No more preceded LWS, so break here.
+ //
break;
}
}
- //
- // Header fields can be extended over multiple lines by preceding each extra
- // line with at least one SP or HT.
- //
StrPtr = FieldValueStr;
do {
+ //
+ // Handle the LWS within the field value.
+ //
StrPtr = AsciiStrGetNextToken (StrPtr, '\r');
if (StrPtr == NULL || *StrPtr != '\n') {
+ //
+ // Wrong String format!
+ //
return NULL;
}
@@ -1706,9 +1720,9 @@ HttpFreeHeaderFields (
NULL if any error occured.
@param[out] RequestMsgSize Size of the RequestMsg (in bytes).
- @return EFI_SUCCESS If HTTP request string was created successfully
+ @retval EFI_SUCCESS If HTTP request string was created successfully.
@retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
- @retval EFI_INVALID_PARAMETER The input arguments are invalid
+ @retval EFI_INVALID_PARAMETER The input arguments are invalid.
**/
EFI_STATUS
@@ -1731,10 +1745,6 @@ HttpGenRequestMessage (
UINTN Index;
EFI_HTTP_UTILITIES_PROTOCOL *HttpUtilitiesProtocol;
-
- ASSERT (Message != NULL);
-
- *RequestMsg = NULL;
Status = EFI_SUCCESS;
HttpHdrSize = 0;
MsgSize = 0;
@@ -1749,7 +1759,8 @@ HttpGenRequestMessage (
// 3. If we do not have a Request, HeaderCount should be zero
// 4. If we do not have Request and Headers, we need at least a message-body
//
- if ((Message->Data.Request != NULL && Url == NULL) ||
+ if ((Message == NULL || RequestMsg == NULL || RequestMsgSize == NULL) ||
+ (Message->Data.Request != NULL && Url == NULL) ||
(Message->Data.Request != NULL && Message->HeaderCount == 0) ||
(Message->Data.Request == NULL && Message->HeaderCount != 0) ||
(Message->Data.Request == NULL && Message->HeaderCount == 0 && Message->BodyLength == 0)) {
@@ -1763,7 +1774,7 @@ HttpGenRequestMessage (
Status = gBS->LocateProtocol (
&gEfiHttpUtilitiesProtocolGuid,
NULL,
- (VOID **)&HttpUtilitiesProtocol
+ (VOID **) &HttpUtilitiesProtocol
);
if (EFI_ERROR (Status)) {
@@ -1787,20 +1798,18 @@ HttpGenRequestMessage (
// Build raw HTTP Headers
//
Status = HttpUtilitiesProtocol->Build (
- HttpUtilitiesProtocol,
- 0,
- NULL,
- 0,
- NULL,
- Message->HeaderCount,
- AppendList,
- &HttpHdrSize,
- &HttpHdr
- );
-
- if (AppendList != NULL) {
- FreePool (AppendList);
- }
+ HttpUtilitiesProtocol,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ Message->HeaderCount,
+ AppendList,
+ &HttpHdrSize,
+ &HttpHdr
+ );
+
+ FreePool (AppendList);
if (EFI_ERROR (Status) || HttpHdr == NULL){
return Status;
@@ -1830,6 +1839,7 @@ HttpGenRequestMessage (
//
// memory for the string that needs to be sent to TCP
//
+ *RequestMsg = NULL;
*RequestMsg = AllocateZeroPool (MsgSize);
if (*RequestMsg == NULL) {
Status = EFI_OUT_OF_RESOURCES;
@@ -2055,7 +2065,15 @@ HttpIsValidHttpHeader (
{
UINTN Index;
+ if (FieldName == NULL) {
+ return FALSE;
+ }
+
for (Index = 0; Index < DeleteCount; Index++) {
+ if (DeleteList[Index] == NULL) {
+ continue;
+ }
+
if (AsciiStrCmp (FieldName, DeleteList[Index]) == 0) {
return FALSE;
}