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; }