diff -cr perl-5.8.2/op.c perl-5.8.2.patched/op.c
*** perl-5.8.2/op.c	Thu Oct 30 23:56:36 2003
--- perl-5.8.2.patched/op.c	Mon Dec 12 18:25:59 2005
***************
*** 1991,1997 ****
  	/* XXX might want a ck_negate() for this */
  	cUNOPo->op_first->op_private &= ~OPpCONST_STRICT;
  	break;
-     case OP_SPRINTF:
      case OP_UCFIRST:
      case OP_LCFIRST:
      case OP_UC:
--- 1991,1996 ----
diff -cr perl-5.8.2/opcode.h perl-5.8.2.patched/opcode.h
*** perl-5.8.2/opcode.h	Mon Nov  3 08:04:42 2003
--- perl-5.8.2.patched/opcode.h	Mon Dec 12 18:25:59 2005
***************
*** 1585,1591 ****
  	0x0022281c,	/* vec */
  	0x0122291c,	/* index */
  	0x0122291c,	/* rindex */
! 	0x0004280f,	/* sprintf */
  	0x00042805,	/* formline */
  	0x0001379e,	/* ord */
  	0x0001378e,	/* chr */
--- 1585,1591 ----
  	0x0022281c,	/* vec */
  	0x0122291c,	/* index */
  	0x0122291c,	/* rindex */
! 	0x0004280d,	/* sprintf */
  	0x00042805,	/* formline */
  	0x0001379e,	/* ord */
  	0x0001378e,	/* chr */
diff -cr perl-5.8.2/opcode.pl perl-5.8.2.patched/opcode.pl
*** perl-5.8.2/opcode.pl	Tue Sep 30 18:11:39 2003
--- perl-5.8.2.patched/opcode.pl	Mon Dec 12 18:25:59 2005
***************
*** 602,608 ****
  index		index			ck_index	isT@	S S S?
  rindex		rindex			ck_index	isT@	S S S?
  
! sprintf		sprintf			ck_fun		mfst@	S L
  formline	formline		ck_fun		ms@	S L
  ord		ord			ck_fun		ifsTu%	S?
  chr		chr			ck_fun		fsTu%	S?
--- 602,608 ----
  index		index			ck_index	isT@	S S S?
  rindex		rindex			ck_index	isT@	S S S?
  
! sprintf		sprintf			ck_fun		mst@	S L
  formline	formline		ck_fun		ms@	S L
  ord		ord			ck_fun		ifsTu%	S?
  chr		chr			ck_fun		fsTu%	S?
diff -cr perl-5.8.2/patchlevel.h perl-5.8.2.patched/patchlevel.h
*** perl-5.8.2/patchlevel.h	Wed Nov  5 21:04:54 2003
--- perl-5.8.2.patched/patchlevel.h	Mon Dec 12 18:25:59 2005
***************
*** 123 ****
! 	,NULL
--- 123,124 ----
! 	,"SPRINTF0 - fixes for sprintf formatting issues - CVE-2005-3962"
! 	,NULL
diff -cr perl-5.8.2/perl.h perl-5.8.2.patched/perl.h
*** perl-5.8.2/perl.h	Sat Nov  1 12:24:06 2003
--- perl-5.8.2.patched/perl.h	Mon Dec 12 18:25:59 2005
***************
*** 3070,3075 ****
--- 3070,3077 ----
    INIT("\"my\" variable %s can't be in a package");
  EXTCONST char PL_no_localize_ref[]
    INIT("Can't localize through a reference");
+   EXTCONST char PL_memory_wrap[]
+     INIT("panic: memory wrap");
  
  EXTCONST char PL_uuemap[65]
    INIT("`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_");
diff -cr perl-5.8.2/sv.c perl-5.8.2.patched/sv.c
*** perl-5.8.2/sv.c	Mon Nov  3 08:04:30 2003
--- perl-5.8.2.patched/sv.c	Mon Dec 12 18:27:33 2005
***************
*** 8458,8466 ****
  	    if (vectorarg) {
  		if (args)
  		    vecsv = va_arg(*args, SV*);
! 		else
! 		    vecsv = (evix ? evix <= svmax : svix < svmax) ?
! 			svargs[evix ? evix-1 : svix++] : &PL_sv_undef;
  		dotstr = SvPVx(vecsv, dotstrlen);
  		if (DO_UTF8(vecsv))
  		    is_utf8 = TRUE;
--- 8458,8469 ----
  	    if (vectorarg) {
  		if (args)
  		    vecsv = va_arg(*args, SV*);
! 		else if (evix) {
! 		    vecsv = (evix > 0 && evix <= svmax)
! 			? svargs[evix-1] : &PL_sv_undef;
! 		} else {
! 		    vecsv = svix < svmax ? svargs[svix++] : &PL_sv_undef;
! 		}
  		dotstr = SvPVx(vecsv, dotstrlen);
  		if (DO_UTF8(vecsv))
  		    is_utf8 = TRUE;
***************
*** 8470,8481 ****
  		vecstr = (U8*)SvPVx(vecsv,veclen);
  		vec_utf8 = DO_UTF8(vecsv);
  	    }
! 	    else if (efix ? efix <= svmax : svix < svmax) {
  		vecsv = svargs[efix ? efix-1 : svix++];
  		vecstr = (U8*)SvPVx(vecsv,veclen);
  		vec_utf8 = DO_UTF8(vecsv);
  	    }
  	    else {
  		vecstr = (U8*)"";
  		veclen = 0;
  	    }
--- 8473,8485 ----
  		vecstr = (U8*)SvPVx(vecsv,veclen);
  		vec_utf8 = DO_UTF8(vecsv);
  	    }
! 	    else if (efix ? (efix > 0 && efix <= svmax) : svix < svmax) {
  		vecsv = svargs[efix ? efix-1 : svix++];
  		vecstr = (U8*)SvPVx(vecsv,veclen);
  		vec_utf8 = DO_UTF8(vecsv);
  	    }
  	    else {
+ 		vecsv = &PL_sv_undef;
  		vecstr = (U8*)"";
  		veclen = 0;
  	    }
***************
*** 8576,8584 ****
  
  	if (vectorize)
  	    argsv = vecsv;
! 	else if (!args)
! 	    argsv = (efix ? efix <= svmax : svix < svmax) ?
! 		    svargs[efix ? efix-1 : svix++] : &PL_sv_undef;
  
  	switch (c = *q++) {
  
--- 8580,8594 ----
  
  	if (vectorize)
  	    argsv = vecsv;
! 	else if (!args) {
! 	    if (efix) {
! 		const I32 i = efix-1;
! 		argsv = (i >= 0 && i < svmax) ? svargs[i] : &PL_sv_undef;
! 	    } else {
! 		argsv = (svix >= 0 && svix < svmax)
! 		    ? svargs[svix++] : &PL_sv_undef;
! 	    }
! 	}
  
  	switch (c = *q++) {
  
***************
*** 8820,8825 ****
--- 8830,8837 ----
  		    *--eptr = '0';
  		break;
  	    case 2:
+ 		if (!uv)
+ 		    alt = FALSE;
  		do {
  		    dig = uv & 1;
  		    *--eptr = '0' + dig;
***************
*** 9130,9138 ****
--- 9142,9154 ----
  			(PL_op->op_type == OP_PRTF) ? "" : "s");
  	
  	have = esignlen + zeros + elen;
+ 	if (have < zeros)
+ 	    Perl_croak_nocontext(PL_memory_wrap);
  	need = (have > width ? have : width);
  	gap = need - have;
  
+ 	if (need >= (((STRLEN)~0) - SvCUR(sv) - dotstrlen - 1))
+ 	    Perl_croak_nocontext(PL_memory_wrap);
  	SvGROW(sv, SvCUR(sv) + need + dotstrlen + 1);
  	p = SvEND(sv);
  	if (esignlen && fill == '0') {
diff -cr perl-5.8.2/t/lib/warnings/sv perl-5.8.2.patched/t/lib/warnings/sv
*** perl-5.8.2/t/lib/warnings/sv	Tue Sep 30 18:12:00 2003
--- perl-5.8.2.patched/t/lib/warnings/sv	Mon Dec 12 18:25:59 2005
***************
*** 281,292 ****
  printf F "%\x02" ;
  $a = sprintf "%\x02" ;
  EXPECT
- Invalid conversion in sprintf: "%z" at - line 5.
- Invalid conversion in sprintf: end of string at - line 7.
- Invalid conversion in sprintf: "%\002" at - line 9.
  Invalid conversion in printf: "%z" at - line 4.
  Invalid conversion in printf: end of string at - line 6.
  Invalid conversion in printf: "%\002" at - line 8.
  ########
  # sv.c
  use warnings 'misc' ;
--- 281,292 ----
  printf F "%\x02" ;
  $a = sprintf "%\x02" ;
  EXPECT
  Invalid conversion in printf: "%z" at - line 4.
+ Invalid conversion in sprintf: "%z" at - line 5.
  Invalid conversion in printf: end of string at - line 6.
+ Invalid conversion in sprintf: end of string at - line 7.
  Invalid conversion in printf: "%\002" at - line 8.
+ Invalid conversion in sprintf: "%\002" at - line 9.
  ########
  # sv.c
  use warnings 'misc' ;
diff -cr perl-5.8.2/t/op/sprintf.t perl-5.8.2.patched/t/op/sprintf.t
*** perl-5.8.2/t/op/sprintf.t	Tue Sep 30 18:12:05 2003
--- perl-5.8.2.patched/t/op/sprintf.t	Mon Dec 12 18:26:04 2005
***************
*** 385,387 ****
--- 385,392 ----
  >%4$K %d<	>[45, 67]<	>%4$K 45 INVALID<
  >%d %K %d<	>[23, 45]<	>23 %K 45 INVALID<
  >%*v*999\$d %d %d<	>[11, 22, 33]<	>%*v*999\$d 11 22 INVALID<
+ >%#b<		>0<	>0<
+ >%#o<		>0<	>0<
+ >%#x<		>0<	>0<
+ >%2918905856$v2d<	>''<	><
+ >%*2918905856$v2d<	>''<	> UNINIT<
*** perl-5.8.2/globvar.sym	Mon Aug 14 16:22:14 2000
--- perl-5.8.2.patched/globvar.sym	Mon Dec 12 21:04:34 2005
***************
*** 66,68 ****
--- 66,69 ----
  vtbl_collxfrm
  vtbl_amagic
  vtbl_amagicelem
+ memory_wrap