// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/fgas/crt/fgas_memory.h"

#ifndef MEMORY_TOOL_REPLACES_ALLOCATOR
// Use CFX_DefStore to replace CFX_FixedStore to simplify memory
// management so that some problems such Use-After-Free can be
// detected by Asan or ClusterFuzz tools.
#define MEMORY_TOOL_REPLACES_ALLOCATOR
#endif

#include <algorithm>

namespace {

struct FX_STATICSTORECHUNK {
  FX_STATICSTORECHUNK* pNextChunk;
  size_t iChunkSize;
  size_t iFreeSize;
};

class CFX_StaticStore : public IFX_MemoryAllocator, public CFX_Target {
 public:
  explicit CFX_StaticStore(size_t iDefChunkSize);
  ~CFX_StaticStore() override;

  void* Alloc(size_t size) override;
  void Free(void* pBlock) override {}

 private:
  size_t m_iAllocatedSize;
  size_t m_iDefChunkSize;
  FX_STATICSTORECHUNK* m_pChunk;
  FX_STATICSTORECHUNK* m_pLastChunk;
  FX_STATICSTORECHUNK* AllocChunk(size_t size);
  FX_STATICSTORECHUNK* FindChunk(size_t size);
};

#ifdef MEMORY_TOOL_REPLACES_ALLOCATOR

class CFX_DefStore : public IFX_MemoryAllocator, public CFX_Target {
 public:
  CFX_DefStore() {}
  ~CFX_DefStore() override {}

  void* Alloc(size_t size) override { return FX_Alloc(uint8_t, size); }
  void Free(void* pBlock) override { FX_Free(pBlock); }
};

#else

struct FX_FIXEDSTORECHUNK {
  uint8_t* FirstFlag() { return reinterpret_cast<uint8_t*>(this + 1); }
  uint8_t* FirstBlock() { return FirstFlag() + iChunkSize; }

  FX_FIXEDSTORECHUNK* pNextChunk;
  size_t iChunkSize;
  size_t iFreeNum;
};

class CFX_FixedStore : public IFX_MemoryAllocator, public CFX_Target {
 public:
  CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk);
  ~CFX_FixedStore() override;
  void* Alloc(size_t size) override;
  void Free(void* pBlock) override;

 private:
  FX_FIXEDSTORECHUNK* AllocChunk();

  size_t m_iBlockSize;
  size_t m_iDefChunkSize;
  FX_FIXEDSTORECHUNK* m_pChunk;
};

#endif  // MEMORY_TOOL_REPLACES_ALLOCATOR

}  // namespace

#define FX_4BYTEALIGN(size) (((size) + 3) & ~3)

std::unique_ptr<IFX_MemoryAllocator> IFX_MemoryAllocator::Create(
    FX_ALLOCTYPE eType,
    size_t chunkSize,
    size_t blockSize) {
  switch (eType) {
    case FX_ALLOCTYPE_Static:
      return std::unique_ptr<IFX_MemoryAllocator>(
          new CFX_StaticStore(chunkSize));
    case FX_ALLOCTYPE_Fixed:
#ifdef MEMORY_TOOL_REPLACES_ALLOCATOR
      return std::unique_ptr<IFX_MemoryAllocator>(new CFX_DefStore());
#else
      return std::unique_ptr<IFX_MemoryAllocator>(
          new CFX_FixedStore(blockSize, chunkSize));
#endif  // MEMORY_TOOL_REPLACES_ALLOCATOR
    default:
      ASSERT(0);
      return nullptr;
  }
}

CFX_StaticStore::CFX_StaticStore(size_t iDefChunkSize)
    : m_iAllocatedSize(0),
      m_iDefChunkSize(iDefChunkSize),
      m_pChunk(nullptr),
      m_pLastChunk(nullptr) {
  ASSERT(m_iDefChunkSize != 0);
}

CFX_StaticStore::~CFX_StaticStore() {
  FX_STATICSTORECHUNK* pChunk = m_pChunk;
  while (pChunk) {
    FX_STATICSTORECHUNK* pNext = pChunk->pNextChunk;
    FX_Free(pChunk);
    pChunk = pNext;
  }
}

FX_STATICSTORECHUNK* CFX_StaticStore::AllocChunk(size_t size) {
  ASSERT(size != 0);
  FX_STATICSTORECHUNK* pChunk = (FX_STATICSTORECHUNK*)FX_Alloc(
      uint8_t, sizeof(FX_STATICSTORECHUNK) + size);
  pChunk->iChunkSize = size;
  pChunk->iFreeSize = size;
  pChunk->pNextChunk = nullptr;
  if (!m_pLastChunk) {
    m_pChunk = pChunk;
  } else {
    m_pLastChunk->pNextChunk = pChunk;
  }
  m_pLastChunk = pChunk;
  return pChunk;
}

FX_STATICSTORECHUNK* CFX_StaticStore::FindChunk(size_t size) {
  ASSERT(size != 0);
  if (!m_pLastChunk || m_pLastChunk->iFreeSize < size) {
    return AllocChunk(std::max(m_iDefChunkSize, size));
  }
  return m_pLastChunk;
}

void* CFX_StaticStore::Alloc(size_t size) {
  size = FX_4BYTEALIGN(size);
  ASSERT(size != 0);
  FX_STATICSTORECHUNK* pChunk = FindChunk(size);
  ASSERT(pChunk->iFreeSize >= size);
  uint8_t* p = (uint8_t*)pChunk;
  p += sizeof(FX_STATICSTORECHUNK) + pChunk->iChunkSize - pChunk->iFreeSize;
  pChunk->iFreeSize -= size;
  m_iAllocatedSize += size;
  return p;
}

#ifndef MEMORY_TOOL_REPLACES_ALLOCATOR

CFX_FixedStore::CFX_FixedStore(size_t iBlockSize, size_t iBlockNumsInChunk)
    : m_iBlockSize(FX_4BYTEALIGN(iBlockSize)),
      m_iDefChunkSize(FX_4BYTEALIGN(iBlockNumsInChunk)),
      m_pChunk(nullptr) {
  ASSERT(m_iBlockSize != 0 && m_iDefChunkSize != 0);
}

CFX_FixedStore::~CFX_FixedStore() {
  FX_FIXEDSTORECHUNK* pChunk = m_pChunk;
  while (pChunk) {
    FX_FIXEDSTORECHUNK* pNext = pChunk->pNextChunk;
    FX_Free(pChunk);
    pChunk = pNext;
  }
}

FX_FIXEDSTORECHUNK* CFX_FixedStore::AllocChunk() {
  int32_t iTotalSize = sizeof(FX_FIXEDSTORECHUNK) + m_iDefChunkSize +
                       m_iBlockSize * m_iDefChunkSize;
  FX_FIXEDSTORECHUNK* pChunk =
      (FX_FIXEDSTORECHUNK*)FX_Alloc(uint8_t, iTotalSize);
  if (!pChunk)
    return nullptr;

  FXSYS_memset(pChunk->FirstFlag(), 0, m_iDefChunkSize);
  pChunk->pNextChunk = m_pChunk;
  pChunk->iChunkSize = m_iDefChunkSize;
  pChunk->iFreeNum = m_iDefChunkSize;
  m_pChunk = pChunk;
  return pChunk;
}

void* CFX_FixedStore::Alloc(size_t size) {
  if (size > m_iBlockSize) {
    return nullptr;
  }
  FX_FIXEDSTORECHUNK* pChunk = m_pChunk;
  while (pChunk) {
    if (pChunk->iFreeNum > 0) {
      break;
    }
    pChunk = pChunk->pNextChunk;
  }
  if (!pChunk) {
    pChunk = AllocChunk();
  }
  uint8_t* pFlags = pChunk->FirstFlag();
  size_t i = 0;
  for (; i < pChunk->iChunkSize; i++)
    if (pFlags[i] == 0) {
      break;
    }
  ASSERT(i < pChunk->iChunkSize);
  pFlags[i] = 1;
  pChunk->iFreeNum--;
  return pChunk->FirstBlock() + i * m_iBlockSize;
}

void CFX_FixedStore::Free(void* pBlock) {
  FX_FIXEDSTORECHUNK* pPrior = nullptr;
  FX_FIXEDSTORECHUNK* pChunk = m_pChunk;
  uint8_t* pStart = nullptr;
  uint8_t* pEnd;
  while (pChunk) {
    pStart = pChunk->FirstBlock();
    if (pBlock >= pStart) {
      pEnd = pStart + m_iBlockSize * pChunk->iChunkSize;
      if (pBlock < pEnd) {
        break;
      }
    }
    pPrior = pChunk, pChunk = pChunk->pNextChunk;
  }
  ASSERT(pChunk);
  size_t iPos = ((uint8_t*)pBlock - pStart) / m_iBlockSize;
  ASSERT(iPos < pChunk->iChunkSize);
  uint8_t* pFlags = pChunk->FirstFlag();
  if (pFlags[iPos] == 0) {
    return;
  }
  pFlags[iPos] = 0;
  pChunk->iFreeNum++;
  if (pChunk->iFreeNum == pChunk->iChunkSize) {
    if (!pPrior) {
      m_pChunk = pChunk->pNextChunk;
    } else {
      pPrior->pNextChunk = pChunk->pNextChunk;
    }
    FX_Free(pChunk);
  }
}

#endif  // MEMORY_TOOL_REPLACES_ALLOCATOR
