mirror of https://github.com/python/cpython
Added limits to the replace code so it does not count all of the matching
patterns in a string, only the number needed by the max limit.
This commit is contained in:
parent
e4e023c4d3
commit
5132407868
|
@ -2477,7 +2477,7 @@ return_self(PyStringObject *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_LOCAL(Py_ssize_t)
|
Py_LOCAL(Py_ssize_t)
|
||||||
countchar(char *target, int target_len, char c)
|
countchar(char *target, int target_len, char c, Py_ssize_t maxcount)
|
||||||
{
|
{
|
||||||
Py_ssize_t count=0;
|
Py_ssize_t count=0;
|
||||||
char *start=target;
|
char *start=target;
|
||||||
|
@ -2485,9 +2485,10 @@ countchar(char *target, int target_len, char c)
|
||||||
|
|
||||||
while ( (start=findchar(start, end-start, c)) != NULL ) {
|
while ( (start=findchar(start, end-start, c)) != NULL ) {
|
||||||
count++;
|
count++;
|
||||||
|
if (count >= maxcount)
|
||||||
|
break;
|
||||||
start += 1;
|
start += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2534,7 +2535,7 @@ countstring(char *target, Py_ssize_t target_len,
|
||||||
char *pattern, Py_ssize_t pattern_len,
|
char *pattern, Py_ssize_t pattern_len,
|
||||||
Py_ssize_t start,
|
Py_ssize_t start,
|
||||||
Py_ssize_t end,
|
Py_ssize_t end,
|
||||||
int direction)
|
int direction, Py_ssize_t maxcount)
|
||||||
{
|
{
|
||||||
Py_ssize_t count=0;
|
Py_ssize_t count=0;
|
||||||
|
|
||||||
|
@ -2552,21 +2553,26 @@ countstring(char *target, Py_ssize_t target_len,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* zero-length substrings match everywhere */
|
/* zero-length substrings match everywhere */
|
||||||
if (pattern_len == 0)
|
if (pattern_len == 0 || maxcount == 0) {
|
||||||
return target_len+1;
|
if (target_len+1 < maxcount)
|
||||||
|
return target_len+1;
|
||||||
|
return maxcount;
|
||||||
|
}
|
||||||
|
|
||||||
end -= pattern_len;
|
end -= pattern_len;
|
||||||
|
|
||||||
if (direction < 0) {
|
if (direction < 0) {
|
||||||
for (; end >= start; end--)
|
for (; (end >= start); end--)
|
||||||
if (Py_STRING_MATCH(target, end, pattern, pattern_len)) {
|
if (Py_STRING_MATCH(target, end, pattern, pattern_len)) {
|
||||||
count++;
|
count++;
|
||||||
|
if (--maxcount <= 0) break;
|
||||||
end -= pattern_len-1;
|
end -= pattern_len-1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (; start <= end; start++)
|
for (; (start <= end); start++)
|
||||||
if (Py_STRING_MATCH(target, start, pattern, pattern_len)) {
|
if (Py_STRING_MATCH(target, start, pattern, pattern_len)) {
|
||||||
count++;
|
count++;
|
||||||
|
if (--maxcount <= 0)
|
||||||
|
break;
|
||||||
start += pattern_len-1;
|
start += pattern_len-1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2653,12 +2659,10 @@ replace_delete_single_character(PyStringObject *self,
|
||||||
self_len = PyString_GET_SIZE(self);
|
self_len = PyString_GET_SIZE(self);
|
||||||
self_s = PyString_AS_STRING(self);
|
self_s = PyString_AS_STRING(self);
|
||||||
|
|
||||||
count = countchar(self_s, self_len, from_c);
|
count = countchar(self_s, self_len, from_c, maxcount);
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
return return_self(self);
|
return return_self(self);
|
||||||
}
|
}
|
||||||
if (count > maxcount)
|
|
||||||
count = maxcount;
|
|
||||||
|
|
||||||
result_len = self_len - count; /* from_len == 1 */
|
result_len = self_len - count; /* from_len == 1 */
|
||||||
assert(result_len>=0);
|
assert(result_len>=0);
|
||||||
|
@ -2701,10 +2705,8 @@ replace_delete_substring(PyStringObject *self, PyStringObject *from,
|
||||||
|
|
||||||
count = countstring(self_s, self_len,
|
count = countstring(self_s, self_len,
|
||||||
from_s, from_len,
|
from_s, from_len,
|
||||||
0, self_len, 1);
|
0, self_len, 1,
|
||||||
|
maxcount);
|
||||||
if (count > maxcount)
|
|
||||||
count = maxcount;
|
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
/* no matches */
|
/* no matches */
|
||||||
|
@ -2857,9 +2859,7 @@ replace_single_character(PyStringObject *self,
|
||||||
self_s = PyString_AS_STRING(self);
|
self_s = PyString_AS_STRING(self);
|
||||||
self_len = PyString_GET_SIZE(self);
|
self_len = PyString_GET_SIZE(self);
|
||||||
|
|
||||||
count = countchar(self_s, self_len, from_c);
|
count = countchar(self_s, self_len, from_c, maxcount);
|
||||||
if (count > maxcount)
|
|
||||||
count = maxcount;
|
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
/* no matches, return unchanged */
|
/* no matches, return unchanged */
|
||||||
|
@ -2933,10 +2933,7 @@ replace_substring(PyStringObject *self,
|
||||||
|
|
||||||
count = countstring(self_s, self_len,
|
count = countstring(self_s, self_len,
|
||||||
from_s, from_len,
|
from_s, from_len,
|
||||||
0, self_len, FORWARD);
|
0, self_len, FORWARD, maxcount);
|
||||||
if (count > maxcount)
|
|
||||||
count = maxcount;
|
|
||||||
|
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
/* no matches, return unchanged */
|
/* no matches, return unchanged */
|
||||||
return return_self(self);
|
return return_self(self);
|
||||||
|
|
Loading…
Reference in New Issue