parse_toggle_state() only returns 0 or 1, so check for 1 directly.
[privoxy.git] / pcrs.c
diff --git a/pcrs.c b/pcrs.c
index 301c7c2..0f5145a 100644 (file)
--- a/pcrs.c
+++ b/pcrs.c
@@ -1,5 +1,4 @@
-const char pcrs_rcs[] = "$Id: pcrs.c,v 1.25 2007/04/30 15:02:18 fabiankeil Exp $";
-
+const char pcrs_rcs[] = "$Id: pcrs.c,v 1.36 2011/03/03 14:49:08 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/pcrs.c,v $
@@ -36,143 +35,12 @@ const char pcrs_rcs[] = "$Id: pcrs.c,v 1.25 2007/04/30 15:02:18 fabiankeil Exp $
  *                or write to the Free Software Foundation, Inc., 59
  *                Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  *
- * Revisions   :
- *    $Log: pcrs.c,v $
- *    Revision 1.25  2007/04/30 15:02:18  fabiankeil
- *    Introduce dynamic pcrs jobs that can resolve variables.
- *
- *    Revision 1.24  2007/01/05 15:46:12  fabiankeil
- *    Don't use strlen() to calculate the length of
- *    the pcrs substitutes. They don't have to be valid C
- *    strings and getting their length wrong can result in
- *    user-controlled memory corruption.
- *
- *    Thanks to Felix Gröbert for reporting the problem
- *    and providing the fix [#1627140].
- *
- *    Revision 1.23  2006/12/29 17:53:05  fabiankeil
- *    Fixed gcc43 conversion warnings.
- *
- *    Revision 1.22  2006/12/24 17:34:20  fabiankeil
- *    Add pcrs_strerror() message for PCRE_ERROR_MATCHLIMIT
- *    and give a hint why an error code might be unknown.
- *
- *    Catch NULL subjects early in pcrs_execute().
- *
- *    Revision 1.21  2006/07/18 14:48:47  david__schmidt
- *    Reorganizing the repository: swapping out what was HEAD (the old 3.1 branch)
- *    with what was really the latest development (the v_3_0_branch branch)
- *
- *    Revision 1.19.2.4  2005/05/07 21:50:55  david__schmidt
- *    A few memory leaks plugged (mostly on error paths)
- *
- *    Revision 1.19.2.3  2003/12/04 12:32:45  oes
- *    Append a trailing nullbyte to result to facilitate string processing
- *
- *    Revision 1.19.2.2  2002/10/08 16:22:28  oes
- *    Bugfix: Need to check validity of backreferences explicitly,
- *    because when max_matches are reached and matches is expanded,
- *    realloc() does not zero the memory. Fixes Bug # 606227
- *
- *    Revision 1.19.2.1  2002/08/10 11:23:40  oes
- *    Include prce.h via project.h, where the appropriate
- *    source will have been selected
- *
- *    Revision 1.19  2002/03/08 14:47:48  oes
- *    Cosmetics
- *
- *    Revision 1.18  2002/03/08 14:17:14  oes
- *    Fixing -Wconversion warnings
- *
- *    Revision 1.17  2002/03/08 13:45:48  oes
- *    Hiding internal functions
- *
- *    Revision 1.16  2001/11/30 21:32:14  jongfoster
- *    Fixing signed/unsigned comparison (Andreas please check this!)
- *    One tab->space
- *
- *    Revision 1.15  2001/09/20 16:11:06  steudten
- *
- *    Add casting for some string functions.
- *
- *    Revision 1.14  2001/09/09 21:41:57  oes
- *    Fixing yet another silly bug
- *
- *    Revision 1.13  2001/09/06 14:05:59  oes
- *    Fixed silly bug
- *
- *    Revision 1.12  2001/08/18 11:35:00  oes
- *    - Introduced pcrs_strerror()
- *    - made some NULL arguments non-fatal
- *    - added support for \n \r \e \b \t \f \a \0 in substitute
- *    - made quoting adhere to standard rules
- *    - added warning for bad backrefs
- *    - added pcrs_execute_list()
- *    - fixed comments
- *    - bugfix & cosmetics
- *
- *    Revision 1.11  2001/08/15 15:32:03  oes
- *     - Added support for Perl's special variables $+, $' and $`
- *     - Improved the substitute parser
- *     - Replaced the hard limit for the maximum number of matches
- *       by dynamic reallocation
- *
- *    Revision 1.10  2001/08/05 13:13:11  jongfoster
- *    Making parameters "const" where possible.
- *
- *    Revision 1.9  2001/07/18 17:27:00  oes
- *    Changed interface; Cosmetics
- *
- *    Revision 1.8  2001/06/29 21:45:41  oes
- *    Indentation, CRLF->LF, Tab-> Space
- *
- *    Revision 1.7  2001/06/29 13:33:04  oes
- *    - Cleaned up, renamed and reordered functions,
- *      improved comments
- *    - Removed my_strsep
- *    - Replaced globalflag with a general flags int
- *      that holds PCRS_GLOBAL, PCRS_SUCCESS, and PCRS_TRIVIAL
- *    - Introduced trivial option that will prevent pcrs
- *      from honouring backreferences in the substitute,
- *      which is useful for large substitutes that are
- *      red in from somewhere and saves the pain of escaping
- *      the backrefs
- *    - Introduced convenience function pcrs_free_joblist()
- *    - Split pcrs_make_job() into pcrs_compile(), which still
- *      takes a complete s/// comand as argument and parses it,
- *      and a new function pcrs_make_job, which takes the
- *      three separate components. This should make for a
- *      much friendlier frontend.
- *    - Removed create_pcrs_job() which was useless
- *    - Fixed a bug in pcrs_execute
- *    - Success flag is now handled by pcrs instead of user
- *
- *    Revision 1.6  2001/06/03 19:12:45  oes
- *    added FIXME
- *
- *    Revision 1.5  2001/05/29 09:50:24  jongfoster
- *    (Fixed one int -> size_t)
- *
- *    Revision 1.4  2001/05/25 14:12:40  oes
- *    Fixed bug: Empty substitutes now detected
- *
- *    Revision 1.3  2001/05/25 11:03:55  oes
- *    Added sanity check for NULL jobs to pcrs_exec_substitution
- *
- *    Revision 1.2  2001/05/22 18:46:04  oes
- *
- *      Added support for PCRE_UNGREEDY behaviour to pcrs,
- *      which is selected by the (nonstandard and therefore
- *      capital) letter 'U' in the option string.
- *      It causes the quantifiers to be ungreedy by default.
- *      Appending a ? turns back to greedy (!).
- *
- *    Revision 1.1.1.1  2001/05/15 13:59:02  oes
- *    Initial import of version 2.9.3 source tree
- *
- *
  *********************************************************************/
-\f
+
+
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
 
 /*
  * Include project.h just so that the right pcre.h gets
@@ -182,10 +50,8 @@ const char pcrs_rcs[] = "$Id: pcrs.c,v 1.25 2007/04/30 15:02:18 fabiankeil Exp $
 
 /* For snprintf only */
 #include "miscutil.h"
-
-#include <string.h>
-#include <ctype.h>
-#include <assert.h>
+/* For xtoi */
+#include "encode.h"
 
 #include "pcrs.h"
 
@@ -199,7 +65,6 @@ static int              pcrs_parse_perl_options(const char *optstring, int *flag
 static pcrs_substitute *pcrs_compile_replacement(const char *replacement, int trivialflag,
                         int capturecount, int *errptr);
 static int              is_hex_sequence(const char *sequence);
-static char             hex_to_byte(const char *sequence);
 
 /*********************************************************************
  *
@@ -215,7 +80,7 @@ static char             hex_to_byte(const char *sequence);
  *********************************************************************/
 const char *pcrs_strerror(const int error)
 {
-   if (error < 0)
+   if (error != 0)
    {
       switch (error)
       {
@@ -429,7 +294,16 @@ static pcrs_substitute *pcrs_compile_replacement(const char *replacement, int tr
                }
                else if (is_hex_sequence(&replacement[i]))
                {
-                  text[k++] = hex_to_byte(&replacement[i+2]);
+                  /*
+                   * Replace a hex sequence with a single
+                   * character with the sequence's ascii value.
+                   * e.g.: '\x7e' => '~'
+                   */
+                  const int ascii_value = xtoi(&replacement[i+2]);
+
+                  assert(ascii_value > 0);
+                  assert(ascii_value < 256);
+                  text[k++] = (char)ascii_value;
                   i += 4;
                }               
                else
@@ -474,7 +348,7 @@ static pcrs_substitute *pcrs_compile_replacement(const char *replacement, int tr
                }
                else /* $' or $` */
                {
-                  r->backref[l] = PCRS_MAX_SUBMATCHES + 1 - (symbol - symbols);
+                  r->backref[l] = (int)(PCRS_MAX_SUBMATCHES + 1 - (symbol - symbols));
                }
                i += 2;
             }
@@ -523,7 +397,7 @@ plainchar:
  * Function    :  pcrs_free_job
  *
  * Description :  Frees the memory used by a pcrs_job struct and its
- *                dependant structures.
+ *                dependent structures.
  *
  * Parameters  :
  *          1  :  job = pointer to the pcrs_job structure to be freed
@@ -607,7 +481,7 @@ pcrs_job *pcrs_compile_command(const char *command, int *errptr)
    char *tokens[4];   
    pcrs_job *newjob;
    
-   i = k = l = 0;
+   k = l = 0;
    
    /*
     * Tokenize the perl command
@@ -808,7 +682,7 @@ int pcrs_execute_list(pcrs_job *joblist, char *subject, size_t subject_length, c
  
    old = subject;
    *result_length = subject_length;
-   hits = total_hits = 0;
+   total_hits = 0;
 
    for (job = joblist; job != NULL; job = job->next)
    {
@@ -872,7 +746,7 @@ int pcrs_execute(pcrs_job *job, const char *subject, size_t subject_length, char
    pcrs_match *matches, *dummy;
    char *result_offset;
 
-   offset = i = k = 0;
+   offset = i = 0;
 
    /* 
     * Sanity check & memory allocation
@@ -1051,57 +925,6 @@ static int is_hex_sequence(const char *sequence)
 }
 
 
-/*********************************************************************
- *
- * Function    :  hex_to_byte
- *
- * Description :  Converts two bytes in hex into a single byte
- *                with that value. For example '40' is converted
- *                into '@'.
- *
- *                Based on Werner Koch's _gpgme_hextobyte()
- *                in gpgme's conversion.c.
- *
- * Parameters  :
- *          1  :  hex_sequence = Pointer to the two bytes to convert.
- *
- * Returns     :  The byte value.
- *
- *********************************************************************/
-static char hex_to_byte(const char *hex_sequence)
-{
-   const char *current_position = hex_sequence;
-   int value = 0;
-
-   do
-   {
-      const char current_digit = (char)toupper(*current_position);
-
-      if ((current_digit >= '0') && (current_digit <= '9'))
-      {
-         value += current_digit - '0';
-      }
-      else if ((current_digit >= 'A') && (current_digit <= 'F'))
-      {
-         value += current_digit - 'A' + 10; /* + 10 for the hex offset */
-      }
-
-      if (current_position == hex_sequence)
-      {
-         /*
-          * As 0xNM is N * 16**1 + M * 16**0, the value
-          * of the first byte has to be multiplied.
-          */
-         value *= 16;
-      }
-
-   } while (current_position++ < hex_sequence + 1);
-
-   return (char)value;
-
-}
-
-
 /*
  * Functions below this line are only part of the pcrs version
  * included in Privoxy. If you use any of them you should not
@@ -1232,7 +1055,7 @@ char *pcrs_execute_single_command(const char *subject, const char *pcrs_command,
 }
 
 
-const static char warning[] = "... [too long, truncated]";
+static const char warning[] = "... [too long, truncated]";
 /*********************************************************************
  *
  * Function    :  pcrs_compile_dynamic_command
@@ -1241,10 +1064,9 @@ const static char warning[] = "... [too long, truncated]";
  *                values of the variables and compiles it.
  *
  * Parameters  :
- *          1  :  csp = Current client state (buffers, headers, etc...)
- *          2  :  pcrs_command = The dynamic pcrs command to compile
- *          3  :  v = NULL terminated array of variables and their values.
- *          4  :  error = pcrs error code
+ *          1  :  pcrs_command = The dynamic pcrs command to compile
+ *          2  :  v = NULL terminated array of variables and their values.
+ *          3  :  error = pcrs error code
  *
  * Returns     :  NULL in case of hard errors, otherwise the
  *                compiled pcrs job.