diff --git a/postfix/HISTORY b/postfix/HISTORY index 0fea8fb36..d413a089b 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -10872,3 +10872,16 @@ Apologies for any names omitted. Workaround: don't consume in_flow tokens when incoming mail is placed on hold. Back-ported from Postfix 2.3. File: cleanup/cleanup_api.c. + +20060310 + + Workaround: null-terminate the input after stripping CR, + and before passing the input to the MIME processor. Leandro + Santi. The fix, a rewrite of the MIME processor input + handling, is too much change for a stable release. File: + sendmail/sendmail.c. + + Workaround: the PCRE library reports an inappropriate error + code (invalid substring) when $number refers to a valid () + expression that matches the null string. This caused fatal + run-time errors. File: dict_pcre.c. diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index a3b701de7..02cebc7fd 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,8 +20,8 @@ * Patches change the patchlevel and the release date. Snapshots change the * release date only. */ -#define MAIL_RELEASE_DATE "20060221" -#define MAIL_VERSION_NUMBER "2.2.9" +#define MAIL_RELEASE_DATE "20060315" +#define MAIL_VERSION_NUMBER "2.2.10-RC1" #define VAR_MAIL_VERSION "mail_version" #ifdef SNAPSHOT diff --git a/postfix/src/sendmail/sendmail.c b/postfix/src/sendmail/sendmail.c index d4d8645fc..943536b0d 100644 --- a/postfix/src/sendmail/sendmail.c +++ b/postfix/src/sendmail/sendmail.c @@ -742,8 +742,10 @@ static void enqueue(const int flags, const char *encoding, const char *sender, skip_from_ = 0; } if (strip_cr == STRIP_CR_DO && type == REC_TYPE_NORM) - if (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\r') + if (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\r') { vstring_truncate(buf, VSTRING_LEN(buf) - 1); + VSTRING_TERMINATE(buf); + } if ((flags & SM_FLAG_AEOF) && prev_type != REC_TYPE_CONT && VSTRING_LEN(buf) == 1 && *STR(buf) == '.') break; diff --git a/postfix/src/util/dict_pcre.c b/postfix/src/util/dict_pcre.c index 4745281e0..ef19f5cc4 100644 --- a/postfix/src/util/dict_pcre.c +++ b/postfix/src/util/dict_pcre.c @@ -171,8 +171,7 @@ static int dict_pcre_expand(int type, VSTRING *buf, char *ptr) ctxt->matches, n, &pp); if (ret < 0) { if (ret == PCRE_ERROR_NOSUBSTRING) - msg_fatal("regexp %s, line %d: replace index out of range", - ctxt->mapname, ctxt->lineno); + return (MAC_PARSE_UNDEF); else msg_fatal("regexp %s, line %d: pcre_get_substring error: %d", ctxt->mapname, ctxt->lineno, ret); @@ -543,6 +542,7 @@ static DICT_PCRE_RULE *dict_pcre_parse_rule(const char *mapname, int lineno, int dict_flags) { char *p; + int actual_sub; p = line; @@ -599,6 +599,23 @@ static DICT_PCRE_RULE *dict_pcre_parse_rule(const char *mapname, int lineno, */ if (dict_pcre_compile(mapname, lineno, ®exp, &engine) == 0) return (0); +#ifdef PCRE_INFO_CAPTURECOUNT + if (pcre_fullinfo(engine.pattern, engine.hints, + PCRE_INFO_CAPTURECOUNT, + (void *) &actual_sub) != 0) + msg_panic("pcre map %s, line %d: pcre_fullinfo failed", + mapname, lineno); + if (prescan_context.max_sub > actual_sub) { + msg_warn("regexp map %s, line %d: out of range replacement index \"%d\": " + "skipping this rule", mapname, lineno, + (int) prescan_context.max_sub); + if (engine.pattern) + myfree((char *) engine.pattern); + if (engine.hints) + myfree((char *) engine.hints); + return (0); + } +#endif /* * Save the result. diff --git a/postfix/src/util/dict_pcre.ref b/postfix/src/util/dict_pcre.ref index 78f45e76d..e7c04227d 100644 --- a/postfix/src/util/dict_pcre.ref +++ b/postfix/src/util/dict_pcre.ref @@ -2,19 +2,34 @@ ./dict_open: warning: pcre map dict_pcre.map, line 5: ignoring extra text after ENDIF ./dict_open: warning: pcre map dict_pcre.map, line 8: unknown regexp option "!": skipping this rule ./dict_open: warning: dict_pcre.map, line 9: no replacement text: using empty string +./dict_open: warning: regexp map dict_pcre.map, line 10: out of range replacement index "5": skipping this rule ./dict_open: warning: pcre map dict_pcre.map, line 17: $number found in negative match replacement text: skipping this rule ./dict_open: warning: pcre map dict_pcre.map, line 22: no regexp: skipping this rule +> get true true: not found +> get true1 true1=1 +> get true2 true2: not found +> get truefalse2 truefalse2=2 +> get 3 3: not found +> get true3 true3=3 +> get c c= +> get d d: not found +> get 1234 1234=(1)(2)(3)(4) +> get 123 123=(1)(2)(3) +> get bar/find bar/find: not found +> get bar/whynot bar/whynot=Don't have a liquor license +> get bar/elbereth bar/elbereth=(elbereth) +> get say/elbereth say/elbereth: not found