<commit_before>/*
     This file is part of libmicrohttpd
     Copyright (C) 2019 <NAME> (and other contributing authors)

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 of the License, or (at your option) any later version.

     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/
/**
 * @file http_chunked_compression.c
 * @brief example for how to compress a chunked HTTP response
 * @author <NAME> (silvioprog)
 */

#include "platform.h"
#include <zlib.h>
#include <microhttpd.h>

#define CHUNK 16384

struct Holder {
    FILE *file;
    z_stream stream;
    void *buf;
};

static int
compress_buf (z_stream *strm, const void *src, size_t src_size, size_t *offset, void **dest, size_t *dest_size,
              void *tmp)
{
  unsigned int have;
  int ret;
  int flush;
  *dest = NULL;
  *dest_size = 0;
  do
    {
      if (src_size > CHUNK)
        {
          strm->avail_in = CHUNK;
          src_size -= CHUNK;
          flush = Z_NO_FLUSH;
        }
      else
        {
          strm->avail_in = (uInt) src_size;
          flush = Z_SYNC_FLUSH;
        }
      *offset += strm->avail_in;
      strm->next_in = (Bytef *) src;
      do
        {
          strm->avail_out = CHUNK;
          strm->next_out = tmp;
          ret = deflate (strm, flush);
          have = CHUNK - strm->avail_out;
          *dest_size += have;
          *dest = realloc (*dest, *dest_size);
          if (NULL == *dest)
            return MHD_NO;
          memcpy ((*dest) + ((*dest_size) - have), tmp, have);
        }
      while (0 == strm->avail_out);
    }
  while (flush != Z_SYNC_FLUSH);
  return (Z_OK == ret) ? MHD_YES : MHD_NO;
}

static ssize_t
read_cb (void *cls, uint64_t pos, char *mem, size_t size)
{
  struct Holder *holder = cls;
  void *src;
  void *buf;
  src = malloc (size);
  if (NULL == src)
    return MHD_CONTENT_READER_END_WITH_ERROR;
  size = fread (src, 1, size, holder->file);
  if (size < 0)
    {
      size = MHD_CONTENT_READER_END_WITH_ERROR;
      goto done;
    }
  if (0 == size)
    {
      size = MHD_CONTENT_READER_END_OF_STREAM;
      goto done;
    }<commit_msg>Fix realloc memleak in compress_buf()<commit_after>/*
     This file is part of libmicrohttpd
     Copyright (C) 2019 <NAME> (and other contributing authors)

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 of the License, or (at your option) any later version.

     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/
/**
 * @file http_chunked_compression.c
 * @brief example for how to compress a chunked HTTP response
 * @author <NAME> (silvioprog)
 */

#include "platform.h"
#include <zlib.h>
#include <microhttpd.h>

#define CHUNK 16384

struct Holder {
    FILE *file;
    z_stream stream;
    void *buf;
};

static int
compress_buf (z_stream *strm, const void *src, size_t src_size, size_t *offset, void **dest, size_t *dest_size,
              void *tmp)
{
  unsigned int have;
  int ret;
  int flush;
  void *tmp_dest;
  *dest = NULL;
  *dest_size = 0;
  do
    {
      if (src_size > CHUNK)
        {
          strm->avail_in = CHUNK;
          src_size -= CHUNK;
          flush = Z_NO_FLUSH;
        }
      else
        {
          strm->avail_in = (uInt) src_size;
          flush = Z_SYNC_FLUSH;
        }
      *offset += strm->avail_in;
      strm->next_in = (Bytef *) src;
      do
        {
          strm->avail_out = CHUNK;
          strm->next_out = tmp;
          ret = deflate (strm, flush);
          have = CHUNK - strm->avail_out;
          *dest_size += have;
          tmp_dest = realloc (*dest, *dest_size);
          if (NULL == tmp_dest)
            {
              free (*dest);
              *dest = NULL;
              return MHD_NO;
            }
          *dest = tmp_dest;
          memcpy ((*dest) + ((*dest_size) - have), tmp, have);
        }
      while (0 == strm->avail_out);
    }
  while (flush != Z_SYNC_FLUSH);
  return (Z_OK == ret) ? MHD_YES : MHD_NO;
}

static ssize_t
read_cb (void *cls, uint64_t pos, char *mem, size_t size)
{
  struct Holder *holder = cls;
  void *src;
  void *buf;
  src = malloc (size);
  if (NULL == src)
    return MHD_CONTENT_READER_END_WITH_ERROR;
  size = fread (src, 1, size, holder->file);
  if (size < 0)
    {
      size = MHD_CONTENT_READER_END_WITH_ERROR;
      goto done;
    }
  if (0 == size)
    {
      size = MHD_CONTENT_READER_END_OF_STREAM;
      goto done;
    }
{'fraction_non_alphanumeric': 0.09546109510086455, 'fraction_numerical': 0.010446685878962535, 'mean_word_length': 2.3033908387864366, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 31, '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': '5512392', 'n_tokens_mistral': 1855, 'n_tokens_neox': 1817, 'n_words': 612}