<commit_before>/** @file
  Routines to process Wrq (upload).
  
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
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<BR>

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Mtftp4Impl.h"



/**
  Build then send a MTFTP data packet for the MTFTP upload session.

  @param  Instance              The MTFTP upload session.
  @param  BlockNum              The block number to send.

  @retval EFI_OUT_OF_RESOURCES  Failed to build the packet.
  @retval EFI_ABORTED           The consumer of this child directs to abort the
                                transmission by return an error through PacketNeeded.
  @retval EFI_SUCCESS           The data is sent.

**/
EFI_STATUS
Mtftp4WrqSendBlock (
  IN OUT MTFTP4_PROTOCOL        *Instance,
  IN     UINT16                 BlockNum
  )
{
  EFI_MTFTP4_PACKET         *Packet;
  EFI_MTFTP4_TOKEN          *Token;
  NET_BUF                   *UdpPacket;
  EFI_STATUS                Status;
  UINT16                    DataLen;
  UINT8                     *DataBuf;
  UINT64                    Start;

  //
  // Allocate a buffer to hold the user data
  //
  UdpPacket = NetbufAlloc (Instance->BlkSize + MTFTP4_DATA_HEAD_LEN);

  if (UdpPacket == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet = (EFI_MTFTP4_PACKET *) NetbufAllocSpace (UdpPacket, MTFTP4_DATA_HEAD_LEN, FALSE);
  ASSERT (Packet != NULL);

  Packet->Data.OpCode = HTONS (EFI_MTFTP4_OPCODE_DATA);
  Packet->Data.Block  = HTONS (BlockNum);

  //
  // Read the block from either the buffer or PacketNeeded callback
  //
  Token   = Instance->Token;
  DataLen = Instance->BlkSize;

  if (Token->Buffer != NULL) {
    Start = MultU64x32 (BlockNum - 1, Instance->BlkSize);

    if (Token->BufferSize < Start + Instance->BlkSize) {
      DataLen             = (UINT16) (Token->BufferSize - Start);
      Instance->LastBlock = BlockNum;
      Mtftp4SetLastBlockNum (&Instance->Blocks, BlockNum);
    }

    if (DataLen > 0) {
      NetbufAllocSpace (UdpPacket, DataLen, FALSE);
      CopyMem (Packet->Data.Data, (UINT8 *) Token->Buffer + Start, DataLen);
    }

  } else {
    //
    // Get data from PacketNeeded
    //
    DataBuf = NULL;
    Status  = Token->PacketNeeded (
                       &Instance->Mtftp4,
                       Token,
                       &DataLen,
                       (VOID **) &DataBuf
                       );

    if (EFI_ERROR (Status) || (DataLen > Instance->BlkSize)) {
      if (DataBuf != NULL) {
        FreePool (DataBuf);
      }

      Mtftp4SendError (
        Instance,
        EFI_MTFTP4_ERRORCODE_REQUEST_DENIED,
        (UINT8 *) "User aborted the transfer"
        );

      return EFI_ABORTED;
    }

    if (DataLen < Instance->BlkSize) {
      Instance->LastBlock = BlockNum;
      Mtftp4SetLastBlockNum (&Instance->Blocks, BlockNum);
    }

    if (DataLen > 0) {<commit_msg>MdeModulePkg: Freed packet buffer when error occurs to avoid memory leak.<commit_after>/** @file
  Routines to process Wrq (upload).
  
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
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<BR>

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "Mtftp4Impl.h"



/**
  Build then send a MTFTP data packet for the MTFTP upload session.

  @param  Instance              The MTFTP upload session.
  @param  BlockNum              The block number to send.

  @retval EFI_OUT_OF_RESOURCES  Failed to build the packet.
  @retval EFI_ABORTED           The consumer of this child directs to abort the
                                transmission by return an error through PacketNeeded.
  @retval EFI_SUCCESS           The data is sent.

**/
EFI_STATUS
Mtftp4WrqSendBlock (
  IN OUT MTFTP4_PROTOCOL        *Instance,
  IN     UINT16                 BlockNum
  )
{
  EFI_MTFTP4_PACKET         *Packet;
  EFI_MTFTP4_TOKEN          *Token;
  NET_BUF                   *UdpPacket;
  EFI_STATUS                Status;
  UINT16                    DataLen;
  UINT8                     *DataBuf;
  UINT64                    Start;

  //
  // Allocate a buffer to hold the user data
  //
  UdpPacket = NetbufAlloc (Instance->BlkSize + MTFTP4_DATA_HEAD_LEN);

  if (UdpPacket == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Packet = (EFI_MTFTP4_PACKET *) NetbufAllocSpace (UdpPacket, MTFTP4_DATA_HEAD_LEN, FALSE);
  ASSERT (Packet != NULL);

  Packet->Data.OpCode = HTONS (EFI_MTFTP4_OPCODE_DATA);
  Packet->Data.Block  = HTONS (BlockNum);

  //
  // Read the block from either the buffer or PacketNeeded callback
  //
  Token   = Instance->Token;
  DataLen = Instance->BlkSize;

  if (Token->Buffer != NULL) {
    Start = MultU64x32 (BlockNum - 1, Instance->BlkSize);

    if (Token->BufferSize < Start + Instance->BlkSize) {
      DataLen             = (UINT16) (Token->BufferSize - Start);
      Instance->LastBlock = BlockNum;
      Mtftp4SetLastBlockNum (&Instance->Blocks, BlockNum);
    }

    if (DataLen > 0) {
      NetbufAllocSpace (UdpPacket, DataLen, FALSE);
      CopyMem (Packet->Data.Data, (UINT8 *) Token->Buffer + Start, DataLen);
    }

  } else {
    //
    // Get data from PacketNeeded
    //
    DataBuf = NULL;
    Status  = Token->PacketNeeded (
                       &Instance->Mtftp4,
                       Token,
                       &DataLen,
                       (VOID **) &DataBuf
                       );

    if (EFI_ERROR (Status) || (DataLen > Instance->BlkSize)) {
      if (DataBuf != NULL) {
        FreePool (DataBuf);
      }

      if (UdpPacket != NULL) {
        NetbufFree (UdpPacket);
      }

      Mtftp4SendError (
        Instance,
        EFI_MTFTP4_ERRORCODE_REQUEST_DENIED,
        (UINT8 *) "User aborted the transfer"
        );

      return EFI_ABORTED;
    }

    if (DataLen < Instance->BlkSize) {
      Instance->LastBlock = BlockNum;
      Mtftp4SetLastBlockNum (&Instance->Blocks, BlockNum);
    }

    if (DataLen > 0) {
{'fraction_non_alphanumeric': 0.08910139647844566, 'fraction_numerical': 0.012143290831815421, 'mean_word_length': 2.148112756808409, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5102270', 'n_tokens_mistral': 2154, 'n_tokens_neox': 2018, 'n_words': 577}