@@ -784,7 +784,7 @@ binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data)
784784{
785785 unsigned char * in_data , * out_data ;
786786 unsigned char in_byte , in_repeat ;
787- Py_ssize_t in_len , out_len , out_len_left ;
787+ Py_ssize_t in_len ;
788788 _PyBytesWriter writer ;
789789
790790 in_data = data -> buf ;
@@ -800,15 +800,12 @@ binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data)
800800 return PyErr_NoMemory ();
801801
802802 /* Allocate a buffer of reasonable size. Resized when needed */
803- out_len = in_len ;
804- out_data = _PyBytesWriter_Alloc (& writer , out_len );
803+ out_data = _PyBytesWriter_Alloc (& writer , in_len );
805804 if (out_data == NULL )
806805 return NULL ;
807806
808807 /* Use overallocation */
809808 writer .overallocate = 1 ;
810- out_len = writer .allocated ;
811- out_len_left = out_len ;
812809
813810 /*
814811 ** We need two macros here to get/put bytes and handle
@@ -823,24 +820,6 @@ binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data)
823820 b = *in_data++; \
824821 } while(0)
825822
826- #define OUTBYTE (b ) \
827- do { \
828- if ( --out_len_left < 0 ) { \
829- if (in_len <= 0) { \
830- /* We are done after this write, no need to \
831- overallocate the buffer anymore */ \
832- writer .overallocate = 0 ; \
833- } \
834- out_data = _PyBytesWriter_Resize (& writer , out_data , \
835- writer .allocated + 1 ); \
836- if (out_data == NULL ) \
837- goto error ; \
838- out_len_left = writer .allocated - out_len - 1 ; \
839- out_len = writer .allocated ; \
840- } \
841- * out_data ++ = b ; \
842- } while (0 )
843-
844823 /*
845824 ** Handle first byte separately (since we have to get angry
846825 ** in case of an orphaned RLE code).
@@ -849,35 +828,53 @@ binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data)
849828
850829 if (in_byte == RUNCHAR ) {
851830 INBYTE (in_repeat );
831+ /* only 1 byte will be written, but 2 bytes were preallocated:
832+ substract 1 byte to prevent overallocation */
833+ writer .min_size -- ;
834+
852835 if (in_repeat != 0 ) {
853836 /* Note Error, not Incomplete (which is at the end
854837 ** of the string only). This is a programmer error.
855838 */
856839 PyErr_SetString (Error , "Orphaned RLE code at start" );
857840 goto error ;
858841 }
859- OUTBYTE ( RUNCHAR ) ;
842+ * out_data ++ = RUNCHAR ;
860843 } else {
861- OUTBYTE ( in_byte ) ;
844+ * out_data ++ = in_byte ;
862845 }
863846
864847 while ( in_len > 0 ) {
865848 INBYTE (in_byte );
866849
867850 if (in_byte == RUNCHAR ) {
868851 INBYTE (in_repeat );
852+ /* only 1 byte will be written, but 2 bytes were preallocated:
853+ substract 1 byte to prevent overallocation */
854+ writer .min_size -- ;
855+
869856 if ( in_repeat == 0 ) {
870857 /* Just an escaped RUNCHAR value */
871- OUTBYTE ( RUNCHAR ) ;
858+ * out_data ++ = RUNCHAR ;
872859 } else {
873860 /* Pick up value and output a sequence of it */
874861 in_byte = out_data [-1 ];
862+
863+ /* enlarge the buffer if needed */
864+ if (in_repeat > 1 ) {
865+ /* -1 because we already preallocated 1 byte */
866+ out_data = _PyBytesWriter_Prepare (& writer , out_data ,
867+ in_repeat - 1 );
868+ if (out_data == NULL )
869+ goto error ;
870+ }
871+
875872 while ( -- in_repeat > 0 )
876- OUTBYTE ( in_byte ) ;
873+ * out_data ++ = in_byte ;
877874 }
878875 } else {
879876 /* Normal byte */
880- OUTBYTE ( in_byte ) ;
877+ * out_data ++ = in_byte ;
881878 }
882879 }
883880 return _PyBytesWriter_Finish (& writer , out_data );
0 commit comments