Don't use strlen() to calculate the length of
authorFabian Keil <fk@fabiankeil.de>
Fri, 5 Jan 2007 15:46:12 +0000 (15:46 +0000)
committerFabian Keil <fk@fabiankeil.de>
Fri, 5 Jan 2007 15:46:12 +0000 (15:46 +0000)
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].

AUTHORS
pcrs.c
pcrs.h

diff --git a/AUTHORS b/AUTHORS
index 5ce2a21..c3d05d7 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -50,6 +50,7 @@ alphabetical order):
  Florian Effenberger
  Dean Gaudet
  Daniel Griscom
+ Felix Gröbert
  Aaron Hamid
  Darel Henman
  Magnus Holmgren
diff --git a/pcrs.c b/pcrs.c
index dd6968f..ee51d0a 100644 (file)
--- a/pcrs.c
+++ b/pcrs.c
@@ -1,4 +1,4 @@
-const char pcrs_rcs[] = "$Id: pcrs.c,v 1.22 2006/12/24 17:34:20 fabiankeil Exp $";
+const char pcrs_rcs[] = "$Id: pcrs.c,v 1.23 2006/12/29 17:53:05 fabiankeil Exp $";
 
 /*********************************************************************
  *
@@ -33,6 +33,9 @@ const char pcrs_rcs[] = "$Id: pcrs.c,v 1.22 2006/12/24 17:34:20 fabiankeil Exp $
  *
  * Revisions   :
  *    $Log: pcrs.c,v $
+ *    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.
@@ -477,6 +480,7 @@ plainchar:
     */
    r->text = text;
    r->backrefs = l;
+   r->length = (size_t)k;
    r->block_length[l] = (size_t)(k - r->block_offset[l]);
 
    return r;
@@ -879,7 +883,7 @@ int pcrs_execute(pcrs_job *job, char *subject, size_t subject_length, char **res
          newsize += matches[i].submatch_length[k] * (size_t)job->substitute->backref_count[k];
       }
       /* plus replacement text size minus match text size */
-      newsize += strlen(job->substitute->text) - matches[i].submatch_length[0]; 
+      newsize += job->substitute->length - matches[i].submatch_length[0]; 
 
       /* chunk before match */
       matches[i].submatch_offset[PCRS_MAX_SUBMATCHES] = 0;
diff --git a/pcrs.h b/pcrs.h
index 4b22a1b..a99293f 100644 (file)
--- a/pcrs.h
+++ b/pcrs.h
  *
  * Revisions   :
  *    $Log: pcrs.h,v $
+ *    Revision 1.14  2006/12/24 17:27:37  fabiankeil
+ *    Increase pcrs error code offset to prevent overlaps
+ *    with pcre versions newer than our own.
+ *
  *    Revision 1.13  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)
@@ -66,7 +70,7 @@
  *
  *********************************************************************/
 
-#define PCRS_H_VERSION "$Id: pcrs.h,v 1.13 2006/07/18 14:48:47 david__schmidt Exp $"
+#define PCRS_H_VERSION "$Id: pcrs.h,v 1.14 2006/12/24 17:27:37 fabiankeil Exp $"
 \f
 
 #ifndef _PCRE_H
@@ -118,6 +122,7 @@ extern "C" {
 
 typedef struct {
   char  *text;                                   /* The plaintext part of the substitute, with all backreferences stripped */
+  size_t length;                                 /* The substitute may not be a valid C string so we can't rely on strlen(). */
   int    backrefs;                               /* The number of backreferences */
   int    block_offset[PCRS_MAX_SUBMATCHES];      /* Array with the offsets of all plaintext blocks in text */
   size_t block_length[PCRS_MAX_SUBMATCHES];      /* Array with the lengths of all plaintext blocks in text */