<commit_before>/***************************************************************************
                          mimeheader.cc  -  description
                             -------------------
    begin                : Fri Oct 20 2000
    copyright            : (C) 2000 by <NAME>
    email                : <EMAIL>
 ***************************************************************************/

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

#include "mimeheader.h"
#include "mimehdrline.h"
#include "mailheader.h"
#include "rfcdecoder.h"

#include <qregexp.h>

// #include <iostream.h>
#include <kglobal.h>
#include <kinstance.h>
#include <kiconloader.h>
#include <kmimetype.h>
#include <kmimemagic.h>
#include <kmdcodec.h>
#include <kdebug.h>

mimeHeader::mimeHeader ():
typeList (17, false), dispositionList (17, false)
{
  // Case insensitive hashes are killing us.  Also are they too small?
  originalHdrLines.setAutoDelete (true);
  additionalHdrLines.setAutoDelete (false); // is also in original lines
  nestedParts.setAutoDelete (true);
  typeList.setAutoDelete (true);
  dispositionList.setAutoDelete (true);
  nestedMessage = NULL;
  contentLength = 0;
  contentType = "application/octet-stream";
}

mimeHeader::~mimeHeader ()
{
}

/*
QPtrList<mimeHeader> mimeHeader::getAllParts()
{
	QPtrList<mimeHeader> retVal;

	// caller is responsible for clearing
	retVal.setAutoDelete( false );
	nestedParts.setAutoDelete( false );
	
	// shallow copy
	retVal = nestedParts;
	
	// can't have duplicate pointers
	nestedParts.clear();
	
	// restore initial state
	nestedParts.setAutoDelete( true );
	
	return retVal;
} */

void
mimeHeader::addHdrLine (mimeHdrLine * aHdrLine)
{
  mimeHdrLine *addLine = new mimeHdrLine (aHdrLine);
  if (addLine)
  {
    originalHdrLines.append (addLine);
    if (qstrnicmp (addLine->getLabel (), "Content-", 8))
    {
      additionalHdrLines.append (addLine);
    }
    else
    {
      int skip;
      char *aCStr = addLine->getValue ().data ();
      QDict < QString > *aList = 0;

      skip = mimeHdrLine::parseSeparator (';', aCStr);
      if (skip > 0)
      {
        int cut = 0;
        if (skip >= 2)
        {
          if (aCStr[skip - 1] == '\r')
            cut++;
          if (aCStr[skip - 1] == '\n')
            cut++;
          if (aCStr[skip - 2] == '\r')
            cut++;
          if (aCStr[skip - 1] == ';')
            cut++;
        }
        QCString mimeValue = QCString (aCStr, skip - cut + 1);  // cutting of one because of 0x00


        if (!qstricmp (addLine->getLabel (), "Content-Disposition"))
        {
          aList = &dispositionList;
          _contentDisposition = mimeValue;
        }
        else if (!qstricmp (addLine->getLabel (), "Content-Type"))
        {
          aList = &typeList;
          contentType = mimeValue;
        }
        else
          if (!qstricmp (addLine->getLabel (), "Content-Transfer-Encoding"))
        {
          contentEncoding = mimeValue;
        }
        else if (!qstricmp (addLine->getLabel (), "Content-ID"))
        {
          contentID = mimeValue;
        }
        else if (!qstricmp (addLine->getLabel (), "Content-Description"))
        {
          _contentDescription = mimeValue;
        }
        else if (!qstricmp (addLine->getLabel (), "Content-MD5"))
        {
          contentMD5 = mimeValue;
        }
        else if (!qstricmp (addLine->getLabel (), "Content-Length"))
        {
          contentLength = mimeValue.toULong ();
        }
        else
        {
          additionalHdrLines.append (addLine);
          aList = new QDict < QString >;
        }
//        cout << addLine->getLabel().data() << ": '" << mimeValue.data() << "'" << endl;

        aCStr += skip;
        while ((skip = mimeHdrLine::parseSeparator (';', aCStr)))
        {
          if (skip > 0)
          {
            addParameter (QCString (aCStr, skip).simplifyWhiteSpace(), aList);
//            cout << "-- '" << aParm.data() << "'" << endl;
            mimeValue = QCString (addLine->getValue ().data (), skip);
            aCStr += skip;
          }
          else
            break;
        }
      }
    }
  }
}

void
mimeHeader::addParameter (const QCString& aParameter, QDict < QString > *aList)
{
  QString *aValue;
  QCString aLabel;
  int pos = aParameter.find ('=');
//  cout << aParameter.left(pos).data();
  aValue = new QString ();
  aValue->setLatin1 (aParameter.right (aParameter.length () - pos - 1));
  aLabel = aParameter.left (pos);
  if ((*aValue)[0] == '"')
    *aValue = aValue->mid (1, aValue->length () - 2);

  aList->insert (aLabel, aValue);
//  cout << "=" << aValue->data() << endl;
}

QString
mimeHeader::getDispositionParm (const QCString& aStr)
{
  return getParameter (aStr, &dispositionList);
}

QString
mimeHeader::getTypeParm (const QCString& aStr)
{
  return getParameter (aStr, &typeList);<commit_msg>Backport: Add a crash guard instead of a memory leak.<commit_after>/***************************************************************************
                          mimeheader.cc  -  description
                             -------------------
    begin                : Fri Oct 20 2000
    copyright            : (C) 2000 by <NAME>
    email                : <EMAIL>
 ***************************************************************************/

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

#include "mimeheader.h"
#include "mimehdrline.h"
#include "mailheader.h"
#include "rfcdecoder.h"

#include <qregexp.h>

// #include <iostream.h>
#include <kglobal.h>
#include <kinstance.h>
#include <kiconloader.h>
#include <kmimetype.h>
#include <kmimemagic.h>
#include <kmdcodec.h>
#include <kdebug.h>

mimeHeader::mimeHeader ():
typeList (17, false), dispositionList (17, false)
{
  // Case insensitive hashes are killing us.  Also are they too small?
  originalHdrLines.setAutoDelete (true);
  additionalHdrLines.setAutoDelete (false); // is also in original lines
  nestedParts.setAutoDelete (true);
  typeList.setAutoDelete (true);
  dispositionList.setAutoDelete (true);
  nestedMessage = NULL;
  contentLength = 0;
  contentType = "application/octet-stream";
}

mimeHeader::~mimeHeader ()
{
}

/*
QPtrList<mimeHeader> mimeHeader::getAllParts()
{
	QPtrList<mimeHeader> retVal;

	// caller is responsible for clearing
	retVal.setAutoDelete( false );
	nestedParts.setAutoDelete( false );
	
	// shallow copy
	retVal = nestedParts;
	
	// can't have duplicate pointers
	nestedParts.clear();
	
	// restore initial state
	nestedParts.setAutoDelete( true );
	
	return retVal;
} */

void
mimeHeader::addHdrLine (mimeHdrLine * aHdrLine)
{
  mimeHdrLine *addLine = new mimeHdrLine (aHdrLine);
  if (addLine)
  {
    originalHdrLines.append (addLine);
    if (qstrnicmp (addLine->getLabel (), "Content-", 8))
    {
      additionalHdrLines.append (addLine);
    }
    else
    {
      int skip;
      char *aCStr = addLine->getValue ().data ();
      QDict < QString > *aList = 0;

      skip = mimeHdrLine::parseSeparator (';', aCStr);
      if (skip > 0)
      {
        int cut = 0;
        if (skip >= 2)
        {
          if (aCStr[skip - 1] == '\r')
            cut++;
          if (aCStr[skip - 1] == '\n')
            cut++;
          if (aCStr[skip - 2] == '\r')
            cut++;
          if (aCStr[skip - 1] == ';')
            cut++;
        }
        QCString mimeValue = QCString (aCStr, skip - cut + 1);  // cutting of one because of 0x00


        if (!qstricmp (addLine->getLabel (), "Content-Disposition"))
        {
          aList = &dispositionList;
          _contentDisposition = mimeValue;
        }
        else if (!qstricmp (addLine->getLabel (), "Content-Type"))
        {
          aList = &typeList;
          contentType = mimeValue;
        }
        else
          if (!qstricmp (addLine->getLabel (), "Content-Transfer-Encoding"))
        {
          contentEncoding = mimeValue;
        }
        else if (!qstricmp (addLine->getLabel (), "Content-ID"))
        {
          contentID = mimeValue;
        }
        else if (!qstricmp (addLine->getLabel (), "Content-Description"))
        {
          _contentDescription = mimeValue;
        }
        else if (!qstricmp (addLine->getLabel (), "Content-MD5"))
        {
          contentMD5 = mimeValue;
        }
        else if (!qstricmp (addLine->getLabel (), "Content-Length"))
        {
          contentLength = mimeValue.toULong ();
        }
        else
        {
          additionalHdrLines.append (addLine);
        }
//        cout << addLine->getLabel().data() << ": '" << mimeValue.data() << "'" << endl;

        aCStr += skip;
        while ((skip = mimeHdrLine::parseSeparator (';', aCStr)))
        {
          if (skip > 0)
          {
            addParameter (QCString (aCStr, skip).simplifyWhiteSpace(), aList);
//            cout << "-- '" << aParm.data() << "'" << endl;
            mimeValue = QCString (addLine->getValue ().data (), skip);
            aCStr += skip;
          }
          else
            break;
        }
      }
    }
  }
}

void
mimeHeader::addParameter (const QCString& aParameter, QDict < QString > *aList)
{
  if ( !aList )
    return;

  QString *aValue;
  QCString aLabel;
  int pos = aParameter.find ('=');
//  cout << aParameter.left(pos).data();
  aValue = new QString ();
  aValue->setLatin1 (aParameter.right (aParameter.length () - pos - 1));
  aLabel = aParameter.left (pos);
  if ((*aValue)[0] == '"')
    *aValue = aValue->mid (1, aValue->length () - 2);

  aList->insert (aLabel, aValue);
//  cout << "=" << aValue->data() << endl;
}

QString
mimeHeader::getDispositionParm (const QCString& aStr)
{
  return getParameter (aStr, &dispositionList);
}

QString
mimeHeader::getTypeParm (const QCString& aStr)
{
  return getParameter (aStr, &typeList);
{'fraction_non_alphanumeric': 0.1866397504129198, 'fraction_numerical': 0.0067902367406863645, 'mean_word_length': 2.1409221902017292, 'pattern_counts': {'":': 2, '<': 86, '<?xml version=': 0, '>': 72, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2463201', 'n_tokens_mistral': 3389, 'n_tokens_neox': 3185, 'n_words': 755}