<commit_before>//
// Copyright (C) 2004, 2005 Pingtel Corp.
// 
//
// $$
////////////////////////////////////////////////////////////////////////
// Derived from regex.hpp, the original copyright and license notice from regex.cpp:
// ----------------
// regex.hpp 1.0 Copyright (c) 2003 <NAME> (<EMAIL>)
// Simple C++ wrapper for PCRE
//
// This source file is freeware. You may use it for any purpose without
// restriction except that the copyright notice as the top of this file as
// well as this paragraph may not be removed or altered.
// ----------------
//

#include "assert.h"
#include "utl/UtlRegex.h"

#ifndef    SIPX_MAX_REGEX_RECURSION
#   define SIPX_MAX_REGEX_RECURSION 800
#endif

const unsigned long int RegEx::MAX_RECURSION = SIPX_MAX_REGEX_RECURSION;

// Some versions do not separately define a limit for stack recursion;
// for those, we must just limit the number of matches.
#ifndef   PCRE_EXTRA_MATCH_LIMIT_RECURSION
#  define PCRE_EXTRA_MATCH_LIMIT_RECURSION PCRE_EXTRA_MATCH_LIMIT
#  define match_limit_recursion match_limit
#endif

/////////////////////////////////
RegEx::RegEx(const char * regex, int options, unsigned long int maxDepth)
{
   const char*  pcre_error;
   int          erroffset;

   // compile and study the expression
   re = pcre_compile(regex, options, &pcre_error, &erroffset, NULL);
   if (re == NULL)
   {
      UtlString errorMsg("Regular Expression compile error: ");
      errorMsg.append(pcre_error);
      errorMsg.append(" at offset ");
      char offsetStr[10];
      sprintf(offsetStr, "%9d", erroffset);
      errorMsg.append(offsetStr);
      errorMsg.append(" in expression '");
      errorMsg.append(regex);
      errorMsg.append("'");

      throw errorMsg.data();
      assert(FALSE); // regex failed to compile
   }
   pe = pcre_study(re, 0, &pcre_error);
   if ( pcre_error == NULL )
   {
      // save the compilation block sizes for the copy constructor.
      pcre_fullinfo(re, pe, PCRE_INFO_SIZE, &re_size);
      pcre_fullinfo(re, pe, PCRE_INFO_STUDYSIZE, &study_size);
      allocated_study = false;
   }
   else
   {
      re_size = 0;
      study_size = 0;
   }

   if (!pe)
   {
      // pcre_study didn't return any study data,
      // but we need the pcre_extra block anyway for the recursion limit,
      // so get one
      pe = (pcre_extra*)pcre_malloc(sizeof(pcre_extra));
      memset(pe, 0, sizeof(pcre_extra));
   }
   // set the maximum recursion depth option in the pcre_extra (pe) block
   pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
   pe->match_limit_recursion = maxDepth;
      
   // allocate space for match results based on how many substrings
   // there are in the expression (+1 for the entire match)
   pcre_fullinfo(re, pe, PCRE_INFO_CAPTURECOUNT, &substrcount);
   substrcount++;
   ovector = new int[3*substrcount];
   matchlist = NULL;
};

/////////////////////////////////
RegEx::RegEx(const RegEx& regex)
{
   const char * error = __FILE__ ": unknown error in RegEx(RegEx)";

   // allocate memory for the compiled regular expression information
   re = (pcre*)pcre_malloc(regex.re_size); 
   if (re)
   {
      // copy the compiled regular expression information
      memcpy(re, regex.re, regex.re_size);
      re_size = regex.re_size;
         
      if (regex.pe) // should always be true, because constructor allocates it
      {
         // allocate memory for the extra study information and recursion limit
         pe = (pcre_extra*)pcre_malloc(sizeof(pcre_extra));
         if (pe)
         {
            void* copied_study_data = pcre_malloc(regex.study_size);
            if (copied_study_data)
            {
               // copy the extra and study information
               memcpy(pe, regex.pe, sizeof(pcre_extra)) ;
               pe->study_data = copied_study_data;
               memcpy(pe->study_data, regex.pe->study_data, regex.study_size) ;
               study_size = regex.study_size;
               allocated_study = true;
            }
            else
            {
               // failed to allocate the study data - not optimal, but we can continue
               study_size = 0;
               allocated_study = false;
            }
         }
         else
         {
            // failed to allocate extra data - not good, but try to continue
            study_size = 0;
            allocated_study = false;
         }
      }
      else
      {
         // no extra or study data to copy
         // this should not happen because we always want the recursion limit
         pe = NULL;
         study_size = 0;
         allocated_study = false;
      }
      substrcount = regex.substrcount;
      ovector = new int[3*substrcount];
      matchlist = NULL;<commit_msg>Plug a memory Leak in RegEx.<commit_after>//
// Copyright (C) 2004, 2005 Pingtel Corp.
// 
//
// $$
////////////////////////////////////////////////////////////////////////
// Derived from regex.hpp, the original copyright and license notice from regex.cpp:
// ----------------
// regex.hpp 1.0 Copyright (c) 2003 <NAME> (<EMAIL>)
// Simple C++ wrapper for PCRE
//
// This source file is freeware. You may use it for any purpose without
// restriction except that the copyright notice as the top of this file as
// well as this paragraph may not be removed or altered.
// ----------------
//

#include "assert.h"
#include "utl/UtlRegex.h"

#ifndef    SIPX_MAX_REGEX_RECURSION
#   define SIPX_MAX_REGEX_RECURSION 800
#endif

const unsigned long int RegEx::MAX_RECURSION = SIPX_MAX_REGEX_RECURSION;

// Some versions do not separately define a limit for stack recursion;
// for those, we must just limit the number of matches.
#ifndef   PCRE_EXTRA_MATCH_LIMIT_RECURSION
#  define PCRE_EXTRA_MATCH_LIMIT_RECURSION PCRE_EXTRA_MATCH_LIMIT
#  define match_limit_recursion match_limit
#endif

/////////////////////////////////
RegEx::RegEx(const char * regex, int options, unsigned long int maxDepth)
{
   const char*  pcre_error;
   int          erroffset;

   // compile and study the expression
   re = pcre_compile(regex, options, &pcre_error, &erroffset, NULL);
   if (re == NULL)
   {
      UtlString errorMsg("Regular Expression compile error: ");
      errorMsg.append(pcre_error);
      errorMsg.append(" at offset ");
      char offsetStr[10];
      sprintf(offsetStr, "%9d", erroffset);
      errorMsg.append(offsetStr);
      errorMsg.append(" in expression '");
      errorMsg.append(regex);
      errorMsg.append("'");

      throw errorMsg.data();
      assert(FALSE); // regex failed to compile
   }
   pe = pcre_study(re, 0, &pcre_error);
   if ( pcre_error == NULL )
   {
      // save the compilation block sizes for the copy constructor.
      pcre_fullinfo(re, pe, PCRE_INFO_SIZE, &re_size);
      pcre_fullinfo(re, pe, PCRE_INFO_STUDYSIZE, &study_size);
      allocated_study = false;
   }
   else
   {
      re_size = 0;
      study_size = 0;
   }

   if (!pe)
   {
      // pcre_study didn't return any study data,
      // but we need the pcre_extra block anyway for the recursion limit,
      // so get one
      pe = (pcre_extra*)pcre_malloc(sizeof(pcre_extra));
      memset(pe, 0, sizeof(pcre_extra));
   }
   // set the maximum recursion depth option in the pcre_extra (pe) block
   pe->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
   pe->match_limit_recursion = maxDepth;
      
   // allocate space for match results based on how many substrings
   // there are in the expression (+1 for the entire match)
   pcre_fullinfo(re, pe, PCRE_INFO_CAPTURECOUNT, &substrcount);
   substrcount++;
   ovector = new int[3*substrcount];
   matchlist = NULL;
};

/////////////////////////////////
RegEx::RegEx(const RegEx& regex)
{
   const char * error = __FILE__ ": unknown error in RegEx(RegEx)";

   // allocate memory for the compiled regular expression information
   re = (pcre*)pcre_malloc(regex.re_size); 
   if (re)
   {
      // copy the compiled regular expression information
      memcpy(re, regex.re, regex.re_size);
      re_size = regex.re_size;
         
      pe = NULL;
      study_size = 0;
      allocated_study = false;
      if (regex.pe) // should always be true, because constructor allocates it
      {
         // allocate memory for the extra study information and recursion limit
         pe = (pcre_extra*)pcre_malloc(sizeof(pcre_extra));
         if (pe)
         {
            // copy the extra information
            memcpy(pe, regex.pe, sizeof(pcre_extra)) ;

            // copy any study information
            if (regex.study_size > 0)
            {
               void* copied_study_data = pcre_malloc(regex.study_size);

               if (copied_study_data)
               {
                  pe->study_data = copied_study_data;
                  memcpy(pe->study_data, regex.pe->study_data, regex.study_size) ;
                  study_size = regex.study_size;
                  allocated_study = true;
               }
            }
         }
      }
      else
      {
         // no extra or study data to copy
         // this should not happen because we always want the recursion limit
      }
      substrcount = regex.substrcount;
      ovector = new int[3*substrcount];
      matchlist = NULL;
{'fraction_non_alphanumeric': 0.12793107209074053, 'fraction_numerical': 0.00643472570618388, 'mean_word_length': 2.139335843889079, 'pattern_counts': {'":': 2, '<': 7, '<?xml version=': 0, '>': 18, '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': '4870309', 'n_tokens_mistral': 2805, 'n_tokens_neox': 2706, 'n_words': 808}