diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c index 0b63b759242cc6a4bb9fb165ad22ba48a37395ad_c2ltcGxlanNvbi9fc3BlZWR1cHMuYw==..334258743b5cab7256a33cb304f7f209ea2c4c8b_c2ltcGxlanNvbi9fc3BlZWR1cHMuYw== 100644 --- a/simplejson/_speedups.c +++ b/simplejson/_speedups.c @@ -17,6 +17,13 @@ #define S_CHAR(c) (c >= ' ' && c <= '~' && c != '\\' && c != '/' && c != '"') +#define MIN_EXPANSION 6 +#ifdef Py_UNICODE_WIDE +#define MAX_EXPANSION (2 * MIN_EXPANSION) +#else +#define MAX_EXPANSION MIN_EXPANSION +#endif + static Py_ssize_t ascii_escape_char(Py_UNICODE c, char *output, Py_ssize_t chars) { Py_UNICODE x; @@ -75,7 +82,7 @@ input_chars = PyUnicode_GET_SIZE(pystr); input_unicode = PyUnicode_AS_UNICODE(pystr); /* One char input can be up to 6 chars output, estimate 4 of these */ - output_size = 32 + input_chars; + output_size = 2 + (MIN_EXPANSION * 4) + input_chars; rval = PyString_FromStringAndSize(NULL, output_size); if (rval == NULL) { return NULL; @@ -90,6 +97,6 @@ } else { chars = ascii_escape_char(c, output, chars); } - if (output_size - chars < 7) { + if (output_size - chars < (1 + MAX_EXPANSION)) { /* There's more than four, so let's resize by a lot */ output_size *= 2; @@ -94,7 +101,8 @@ /* There's more than four, so let's resize by a lot */ output_size *= 2; - if (output_size > 2 + (input_chars * 6)) { - output_size = 2 + (input_chars * 6); + /* This is an upper bound */ + if (output_size > 2 + (input_chars * MAX_EXPANSION)) { + output_size = 2 + (input_chars * MAX_EXPANSION); } if (_PyString_Resize(&rval, output_size) == -1) { return NULL; @@ -122,7 +130,7 @@ input_chars = PyString_GET_SIZE(pystr); input_str = PyString_AS_STRING(pystr); /* One char input can be up to 6 chars output, estimate 4 of these */ - output_size = 32 + input_chars; + output_size = 2 + (MIN_EXPANSION * 4) + input_chars; rval = PyString_FromStringAndSize(NULL, output_size); if (rval == NULL) { return NULL; @@ -148,6 +156,7 @@ } else { chars = ascii_escape_char(c, output, chars); } - if (output_size - chars < 7) { + /* An ASCII char can't possibly expand to a surrogate! */ + if (output_size - chars < (1 + MIN_EXPANSION)) { /* There's more than four, so let's resize by a lot */ output_size *= 2; @@ -152,7 +161,7 @@ /* There's more than four, so let's resize by a lot */ output_size *= 2; - if (output_size > 2 + (input_chars * 6)) { - output_size = 2 + (input_chars * 6); + if (output_size > 2 + (input_chars * MIN_EXPANSION)) { + output_size = 2 + (input_chars * MIN_EXPANSION); } if (_PyString_Resize(&rval, output_size) == -1) { return NULL;