diff options
Diffstat (limited to 'Modules/binascii.c')
| -rw-r--r-- | Modules/binascii.c | 287 | 
1 files changed, 137 insertions, 150 deletions
diff --git a/Modules/binascii.c b/Modules/binascii.c index d920d23871..a306acde32 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -74,7 +74,7 @@ static PyObject *Incomplete;  #define SKIP 0x7E  #define FAIL 0x7D -static unsigned char table_a2b_hqx[256] = { +static const unsigned char table_a2b_hqx[256] = {  /*       ^@    ^A    ^B    ^C    ^D    ^E    ^F    ^G   */  /* 0*/  FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  /*       \b    \t    \n    ^K    ^L    \r    ^N    ^O   */ @@ -125,10 +125,10 @@ static unsigned char table_a2b_hqx[256] = {      FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,  }; -static unsigned char table_b2a_hqx[] = +static const unsigned char table_b2a_hqx[] =  "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr"; -static char table_a2b_base64[] = { +static const char table_a2b_base64[] = {      -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,      -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,      -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, @@ -144,12 +144,12 @@ static char table_a2b_base64[] = {  /* Max binary chunk size; limited only by available memory */  #define BASE64_MAXBIN ((PY_SSIZE_T_MAX - 3) / 2) -static unsigned char table_b2a_base64[] = +static const unsigned char table_b2a_base64[] =  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; -static unsigned short crctab_hqx[256] = { +static const unsigned short crctab_hqx[256] = {      0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,      0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,      0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, @@ -256,7 +256,8 @@ static PyObject *  binascii_a2b_uu_impl(PyModuleDef *module, Py_buffer *data)  /*[clinic end generated code: output=5779f39b0b48459f input=7cafeaf73df63d1c]*/  { -    unsigned char *ascii_data, *bin_data; +    const unsigned char *ascii_data; +    unsigned char *bin_data;      int leftbits = 0;      unsigned char this_ch;      unsigned int leftchar = 0; @@ -342,13 +343,15 @@ static PyObject *  binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data)  /*[clinic end generated code: output=181021b69bb9a414 input=00fdf458ce8b465b]*/  { -    unsigned char *ascii_data, *bin_data; +    unsigned char *ascii_data; +    const unsigned char *bin_data;      int leftbits = 0;      unsigned char this_ch;      unsigned int leftchar = 0; -    PyObject *rv; -    Py_ssize_t bin_len; +    Py_ssize_t bin_len, out_len; +    _PyBytesWriter writer; +    _PyBytesWriter_Init(&writer);      bin_data = data->buf;      bin_len = data->len;      if ( bin_len > 45 ) { @@ -358,9 +361,10 @@ binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data)      }      /* We're lazy and allocate to much (fixed up later) */ -    if ( (rv=PyBytes_FromStringAndSize(NULL, 2 + (bin_len+2)/3*4)) == NULL ) +    out_len = 2 + (bin_len + 2) / 3 * 4; +    ascii_data = _PyBytesWriter_Alloc(&writer, out_len); +    if (ascii_data == NULL)          return NULL; -    ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);      /* Store the length */      *ascii_data++ = ' ' + (bin_len & 077); @@ -382,17 +386,12 @@ binascii_b2a_uu_impl(PyModuleDef *module, Py_buffer *data)      }      *ascii_data++ = '\n';       /* Append a courtesy newline */ -    if (_PyBytes_Resize(&rv, -                       (ascii_data - -                        (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { -        Py_CLEAR(rv); -    } -    return rv; +    return _PyBytesWriter_Finish(&writer, ascii_data);  }  static int -binascii_find_valid(unsigned char *s, Py_ssize_t slen, int num) +binascii_find_valid(const unsigned char *s, Py_ssize_t slen, int num)  {      /* Finds & returns the (num+1)th      ** valid character for base64, or -1 if none. @@ -429,13 +428,14 @@ static PyObject *  binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *data)  /*[clinic end generated code: output=3e351b702bed56d2 input=5872acf6e1cac243]*/  { -    unsigned char *ascii_data, *bin_data; +    const unsigned char *ascii_data; +    unsigned char *bin_data;      int leftbits = 0;      unsigned char this_ch;      unsigned int leftchar = 0; -    PyObject *rv;      Py_ssize_t ascii_len, bin_len;      int quad_pos = 0; +    _PyBytesWriter writer;      ascii_data = data->buf;      ascii_len = data->len; @@ -447,11 +447,12 @@ binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *data)      bin_len = ((ascii_len+3)/4)*3; /* Upper bound, corrected later */ +    _PyBytesWriter_Init(&writer); +      /* Allocate the buffer */ -    if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len)) == NULL ) +    bin_data = _PyBytesWriter_Alloc(&writer, bin_len); +    if (bin_data == NULL)          return NULL; -    bin_data = (unsigned char *)PyBytes_AS_STRING(rv); -    bin_len = 0;      for( ; ascii_len > 0; ascii_len--, ascii_data++) {          this_ch = *ascii_data; @@ -496,31 +497,17 @@ binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *data)          if ( leftbits >= 8 ) {              leftbits -= 8;              *bin_data++ = (leftchar >> leftbits) & 0xff; -            bin_len++;              leftchar &= ((1 << leftbits) - 1);          }      }      if (leftbits != 0) {          PyErr_SetString(Error, "Incorrect padding"); -        Py_DECREF(rv); +        _PyBytesWriter_Dealloc(&writer);          return NULL;      } -    /* And set string size correctly. If the result string is empty -    ** (because the input was all invalid) return the shared empty -    ** string instead; _PyBytes_Resize() won't do this for us. -    */ -    if (bin_len > 0) { -        if (_PyBytes_Resize(&rv, bin_len) < 0) { -            Py_CLEAR(rv); -        } -    } -    else { -        Py_DECREF(rv); -        rv = PyBytes_FromStringAndSize("", 0); -    } -    return rv; +    return _PyBytesWriter_Finish(&writer, bin_data);  } @@ -528,24 +515,27 @@ binascii_a2b_base64_impl(PyModuleDef *module, Py_buffer *data)  binascii.b2a_base64      data: Py_buffer -    / +    * +    newline: int(c_default="1") = True  Base64-code line of data.  [clinic start generated code]*/  static PyObject * -binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data) -/*[clinic end generated code: output=3cd61fbee2913285 input=14ec4e47371174a9]*/ +binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data, int newline) +/*[clinic end generated code: output=19e1dd719a890b50 input=7b2ea6fa38d8924c]*/  { -    unsigned char *ascii_data, *bin_data; +    unsigned char *ascii_data; +    const unsigned char *bin_data;      int leftbits = 0;      unsigned char this_ch;      unsigned int leftchar = 0; -    PyObject *rv; -    Py_ssize_t bin_len; +    Py_ssize_t bin_len, out_len; +    _PyBytesWriter writer;      bin_data = data->buf;      bin_len = data->len; +    _PyBytesWriter_Init(&writer);      assert(bin_len >= 0); @@ -555,11 +545,14 @@ binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data)      }      /* We're lazy and allocate too much (fixed up later). -       "+3" leaves room for up to two pad characters and a trailing -       newline.  Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */ -    if ( (rv=PyBytes_FromStringAndSize(NULL, bin_len*2 + 3)) == NULL ) +       "+2" leaves room for up to two pad characters. +       Note that 'b' gets encoded as 'Yg==\n' (1 in, 5 out). */ +    out_len = bin_len*2 + 2; +    if (newline) +        out_len++; +    ascii_data = _PyBytesWriter_Alloc(&writer, out_len); +    if (ascii_data == NULL)          return NULL; -    ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);      for( ; bin_len > 0 ; bin_len--, bin_data++ ) {          /* Shift the data into our buffer */ @@ -581,14 +574,10 @@ binascii_b2a_base64_impl(PyModuleDef *module, Py_buffer *data)          *ascii_data++ = table_b2a_base64[(leftchar&0xf) << 2];          *ascii_data++ = BASE64_PAD;      } -    *ascii_data++ = '\n';       /* Append a courtesy newline */ +    if (newline) +        *ascii_data++ = '\n';       /* Append a courtesy newline */ -    if (_PyBytes_Resize(&rv, -                       (ascii_data - -                        (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { -        Py_CLEAR(rv); -    } -    return rv; +    return _PyBytesWriter_Finish(&writer, ascii_data);  }  /*[clinic input] @@ -604,16 +593,19 @@ static PyObject *  binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *data)  /*[clinic end generated code: output=60bcdbbd28b105cd input=0d914c680e0eed55]*/  { -    unsigned char *ascii_data, *bin_data; +    const unsigned char *ascii_data; +    unsigned char *bin_data;      int leftbits = 0;      unsigned char this_ch;      unsigned int leftchar = 0; -    PyObject *rv; +    PyObject *res;      Py_ssize_t len;      int done = 0; +    _PyBytesWriter writer;      ascii_data = data->buf;      len = data->len; +    _PyBytesWriter_Init(&writer);      assert(len >= 0); @@ -623,9 +615,9 @@ binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *data)      /* Allocate a string that is too big (fixed later)         Add two to the initial length to prevent interning which         would preclude subsequent resizing.  */ -    if ( (rv=PyBytes_FromStringAndSize(NULL, len+2)) == NULL ) +    bin_data = _PyBytesWriter_Alloc(&writer, len + 2); +    if (bin_data == NULL)          return NULL; -    bin_data = (unsigned char *)PyBytes_AS_STRING(rv);      for( ; len > 0 ; len--, ascii_data++ ) {          /* Get the byte and look it up */ @@ -634,7 +626,7 @@ binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *data)              continue;          if ( this_ch == FAIL ) {              PyErr_SetString(Error, "Illegal char"); -            Py_DECREF(rv); +            _PyBytesWriter_Dealloc(&writer);              return NULL;          }          if ( this_ch == DONE ) { @@ -656,21 +648,14 @@ binascii_a2b_hqx_impl(PyModuleDef *module, Py_buffer *data)      if ( leftbits && !done ) {          PyErr_SetString(Incomplete,                          "String has incomplete number of bytes"); -        Py_DECREF(rv); +        _PyBytesWriter_Dealloc(&writer);          return NULL;      } -    if (_PyBytes_Resize(&rv, -                       (bin_data - -                        (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { -        Py_CLEAR(rv); -    } -    if (rv) { -        PyObject *rrv = Py_BuildValue("Oi", rv, done); -        Py_DECREF(rv); -        return rrv; -    } -    return NULL; +    res = _PyBytesWriter_Finish(&writer, bin_data); +    if (res == NULL) +        return NULL; +    return Py_BuildValue("Ni", res, done);  } @@ -687,11 +672,13 @@ static PyObject *  binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data)  /*[clinic end generated code: output=0905da344dbf0648 input=e1f1712447a82b09]*/  { -    unsigned char *in_data, *out_data; -    PyObject *rv; +    const unsigned char *in_data; +    unsigned char *out_data;      unsigned char ch;      Py_ssize_t in, inend, len; +    _PyBytesWriter writer; +    _PyBytesWriter_Init(&writer);      in_data = data->buf;      len = data->len; @@ -701,9 +688,9 @@ binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data)          return PyErr_NoMemory();      /* Worst case: output is twice as big as input (fixed later) */ -    if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) +    out_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2); +    if (out_data == NULL)          return NULL; -    out_data = (unsigned char *)PyBytes_AS_STRING(rv);      for( in=0; in<len; in++) {          ch = in_data[in]; @@ -729,12 +716,8 @@ binascii_rlecode_hqx_impl(PyModuleDef *module, Py_buffer *data)              }          }      } -    if (_PyBytes_Resize(&rv, -                       (out_data - -                        (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { -        Py_CLEAR(rv); -    } -    return rv; + +    return _PyBytesWriter_Finish(&writer, out_data);  } @@ -751,15 +734,17 @@ static PyObject *  binascii_b2a_hqx_impl(PyModuleDef *module, Py_buffer *data)  /*[clinic end generated code: output=5a987810d5e3cdbb input=9596ebe019fe12ba]*/  { -    unsigned char *ascii_data, *bin_data; +    unsigned char *ascii_data; +    const unsigned char *bin_data;      int leftbits = 0;      unsigned char this_ch;      unsigned int leftchar = 0; -    PyObject *rv;      Py_ssize_t len; +    _PyBytesWriter writer;      bin_data = data->buf;      len = data->len; +    _PyBytesWriter_Init(&writer);      assert(len >= 0); @@ -767,9 +752,9 @@ binascii_b2a_hqx_impl(PyModuleDef *module, Py_buffer *data)          return PyErr_NoMemory();      /* Allocate a buffer that is at least large enough */ -    if ( (rv=PyBytes_FromStringAndSize(NULL, len*2+2)) == NULL ) +    ascii_data = _PyBytesWriter_Alloc(&writer, len * 2 + 2); +    if (ascii_data == NULL)          return NULL; -    ascii_data = (unsigned char *)PyBytes_AS_STRING(rv);      for( ; len > 0 ; len--, bin_data++ ) {          /* Shift into our buffer, and output any 6bits ready */ @@ -786,12 +771,8 @@ binascii_b2a_hqx_impl(PyModuleDef *module, Py_buffer *data)          leftchar <<= (6-leftbits);          *ascii_data++ = table_b2a_hqx[leftchar & 0x3f];      } -    if (_PyBytes_Resize(&rv, -                       (ascii_data - -                        (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { -        Py_CLEAR(rv); -    } -    return rv; + +    return _PyBytesWriter_Finish(&writer, ascii_data);  } @@ -808,13 +789,15 @@ static PyObject *  binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data)  /*[clinic end generated code: output=f7afd89b789946ab input=54cdd49fc014402c]*/  { -    unsigned char *in_data, *out_data; +    const unsigned char *in_data; +    unsigned char *out_data;      unsigned char in_byte, in_repeat; -    PyObject *rv; -    Py_ssize_t in_len, out_len, out_len_left; +    Py_ssize_t in_len; +    _PyBytesWriter writer;      in_data = data->buf;      in_len = data->len; +    _PyBytesWriter_Init(&writer);      assert(in_len >= 0); @@ -825,59 +808,48 @@ binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data)          return PyErr_NoMemory();      /* Allocate a buffer of reasonable size. Resized when needed */ -    out_len = in_len*2; -    if ( (rv=PyBytes_FromStringAndSize(NULL, out_len)) == NULL ) +    out_data = _PyBytesWriter_Alloc(&writer, in_len); +    if (out_data == NULL)          return NULL; -    out_len_left = out_len; -    out_data = (unsigned char *)PyBytes_AS_STRING(rv); + +    /* Use overallocation */ +    writer.overallocate = 1;      /*      ** We need two macros here to get/put bytes and handle      ** end-of-buffer for input and output strings.      */ -#define INBYTE(b) \ -    do { \ -             if ( --in_len < 0 ) { \ -                       PyErr_SetString(Incomplete, ""); \ -                       Py_DECREF(rv); \ -                       return NULL; \ -             } \ -             b = *in_data++; \ +#define INBYTE(b)                                                       \ +    do {                                                                \ +         if ( --in_len < 0 ) {                                          \ +           PyErr_SetString(Incomplete, "");                             \ +           goto error;                                                  \ +         }                                                              \ +         b = *in_data++;                                                \      } while(0) -#define OUTBYTE(b) \ -    do { \ -             if ( --out_len_left < 0 ) { \ -                      if ( out_len > PY_SSIZE_T_MAX / 2) return PyErr_NoMemory(); \ -                      if (_PyBytes_Resize(&rv, 2*out_len) < 0) \ -                        { Py_XDECREF(rv); return NULL; } \ -                      out_data = (unsigned char *)PyBytes_AS_STRING(rv) \ -                                                             + out_len; \ -                      out_len_left = out_len-1; \ -                      out_len = out_len * 2; \ -             } \ -             *out_data++ = b; \ -    } while(0) - -        /* -        ** Handle first byte separately (since we have to get angry -        ** in case of an orphaned RLE code). -        */ -        INBYTE(in_byte); +    /* +    ** Handle first byte separately (since we have to get angry +    ** in case of an orphaned RLE code). +    */ +    INBYTE(in_byte);      if (in_byte == RUNCHAR) {          INBYTE(in_repeat); +        /* only 1 byte will be written, but 2 bytes were preallocated: +           substract 1 byte to prevent overallocation */ +        writer.min_size--; +          if (in_repeat != 0) {              /* Note Error, not Incomplete (which is at the end              ** of the string only). This is a programmer error.              */              PyErr_SetString(Error, "Orphaned RLE code at start"); -            Py_DECREF(rv); -            return NULL; +            goto error;          } -        OUTBYTE(RUNCHAR); +        *out_data++ = RUNCHAR;      } else { -        OUTBYTE(in_byte); +        *out_data++ = in_byte;      }      while( in_len > 0 ) { @@ -885,26 +857,39 @@ binascii_rledecode_hqx_impl(PyModuleDef *module, Py_buffer *data)          if (in_byte == RUNCHAR) {              INBYTE(in_repeat); +            /* only 1 byte will be written, but 2 bytes were preallocated: +               substract 1 byte to prevent overallocation */ +            writer.min_size--; +              if ( in_repeat == 0 ) {                  /* Just an escaped RUNCHAR value */ -                OUTBYTE(RUNCHAR); +                *out_data++ = RUNCHAR;              } else {                  /* Pick up value and output a sequence of it */                  in_byte = out_data[-1]; + +                /* enlarge the buffer if needed */ +                if (in_repeat > 1) { +                    /* -1 because we already preallocated 1 byte */ +                    out_data = _PyBytesWriter_Prepare(&writer, out_data, +                                                      in_repeat - 1); +                    if (out_data == NULL) +                        goto error; +                } +                  while ( --in_repeat > 0 ) -                    OUTBYTE(in_byte); +                    *out_data++ = in_byte;              }          } else {              /* Normal byte */ -            OUTBYTE(in_byte); +            *out_data++ = in_byte;          }      } -    if (_PyBytes_Resize(&rv, -                       (out_data - -                        (unsigned char *)PyBytes_AS_STRING(rv))) < 0) { -        Py_CLEAR(rv); -    } -    return rv; +    return _PyBytesWriter_Finish(&writer, out_data); + +error: +    _PyBytesWriter_Dealloc(&writer); +    return NULL;  } @@ -922,7 +907,7 @@ static unsigned int  binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc)  /*[clinic end generated code: output=167c2dac62625717 input=add8c53712ccceda]*/  { -    unsigned char *bin_data; +    const unsigned char *bin_data;      Py_ssize_t len;      crc &= 0xffff; @@ -1000,7 +985,7 @@ binascii_crc_hqx_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc)       using byte-swap instructions.  ********************************************************************/ -static unsigned int crc_32_tab[256] = { +static const unsigned int crc_32_tab[256] = {  0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,  0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,  0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, @@ -1073,7 +1058,7 @@ binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc)  #ifdef USE_ZLIB_CRC32  /* This was taken from zlibmodule.c PyZlib_crc32 (but is PY_SSIZE_T_CLEAN) */  { -    Byte *buf; +    const Byte *buf;      Py_ssize_t len;      int signed_val; @@ -1084,7 +1069,7 @@ binascii_crc32_impl(PyModuleDef *module, Py_buffer *data, unsigned int crc)  }  #else  /* USE_ZLIB_CRC32 */  { /* By Jim Ahlstrom; All rights transferred to CNRI */ -    unsigned char *bin_data; +    const unsigned char *bin_data;      Py_ssize_t len;      unsigned int result; @@ -1167,7 +1152,7 @@ static PyObject *  binascii_a2b_hex_impl(PyModuleDef *module, Py_buffer *hexstr)  /*[clinic end generated code: output=d61da452b5c6d290 input=9e1e7f2f94db24fd]*/  { -    char* argbuf; +    const char* argbuf;      Py_ssize_t arglen;      PyObject *retval;      char* retbuf; @@ -1224,7 +1209,7 @@ binascii_unhexlify_impl(PyModuleDef *module, Py_buffer *hexstr)      return binascii_a2b_hex_impl(module, hexstr);  } -static int table_hex[128] = { +static const int table_hex[128] = {    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, @@ -1255,7 +1240,8 @@ binascii_a2b_qp_impl(PyModuleDef *module, Py_buffer *data, int header)  {      Py_ssize_t in, out;      char ch; -    unsigned char *ascii_data, *odata; +    const unsigned char *ascii_data; +    unsigned char *odata;      Py_ssize_t datalen = 0;      PyObject *rv; @@ -1361,13 +1347,14 @@ binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs,  /*[clinic end generated code: output=a87ca9ccb94e2a9f input=7f2a9aaa008e92b2]*/  {      Py_ssize_t in, out; -    unsigned char *databuf, *odata; +    const unsigned char *databuf; +    unsigned char *odata;      Py_ssize_t datalen = 0, odatalen = 0;      PyObject *rv;      unsigned int linelen = 0;      unsigned char ch;      int crlf = 0; -    unsigned char *p; +    const unsigned char *p;      databuf = data->buf;      datalen = data->len; @@ -1376,7 +1363,7 @@ binascii_b2a_qp_impl(PyModuleDef *module, Py_buffer *data, int quotetabs,      /* XXX: this function has the side effect of converting all of       * the end of lines to be the same depending on this detection       * here */ -    p = (unsigned char *) memchr(databuf, '\n', datalen); +    p = (const unsigned char *) memchr(databuf, '\n', datalen);      if ((p != NULL) && (p > databuf) && (*(p-1) == '\r'))          crlf = 1;  | 
