summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc-André Lemburg <mal@egenix.com>2001-01-16 11:54:12 (GMT)
committerMarc-André Lemburg <mal@egenix.com>2001-01-16 11:54:12 (GMT)
commit3a645e4dd4eebbfbbfad8443558bb3b879e23896 (patch)
tree97fdb22065892ae35ce0f25bf62fbae5718df32d
parent1c5aa6901fb13f8112ead1786868f0f8ed4c9e2d (diff)
downloadcpython-3a645e4dd4eebbfbbfad8443558bb3b879e23896.zip
cpython-3a645e4dd4eebbfbbfad8443558bb3b879e23896.tar.gz
cpython-3a645e4dd4eebbfbbfad8443558bb3b879e23896.tar.bz2
Added checks to prevent PyUnicode_Count() from dumping core
in case the parameters are out of bounds and fixes error handling for .count(), .startswith() and .endswith() for the case of mixed string/Unicode objects. This patch adds Python style index semantics to PyUnicode_Count() indices (including the special handling of negative indices). The patch is an extended version of patch #103249 submitted by Michael Hudson (mwh) on SF. It also includes new test cases.
-rw-r--r--Lib/test/string_tests.py4
-rw-r--r--Lib/test/test_unicode.py7
-rw-r--r--Objects/stringobject.c37
-rw-r--r--Objects/unicodeobject.c27
4 files changed, 56 insertions, 19 deletions
diff --git a/Lib/test/string_tests.py b/Lib/test/string_tests.py
index d4041be..067ccca 100644
--- a/Lib/test/string_tests.py
+++ b/Lib/test/string_tests.py
@@ -53,6 +53,10 @@ def run_method_tests(test):
test('capitalize', ' hello ', ' hello ')
test('capitalize', 'hello ', 'Hello ')
+
+ test('count', 'aaa', 3, 'a')
+ test('count', 'aaa', 0, 'b')
+
test('find', 'abcdefghiabc', 0, 'abc')
test('find', 'abcdefghiabc', 9, 'abc', 1)
test('find', 'abcdefghiabc', -1, 'def', 4)
diff --git a/Lib/test/test_unicode.py b/Lib/test/test_unicode.py
index 579bab1..c71f927 100644
--- a/Lib/test/test_unicode.py
+++ b/Lib/test/test_unicode.py
@@ -32,6 +32,13 @@ def test(method, input, output, *args):
test('capitalize', u' hello ', u' hello ')
test('capitalize', u'hello ', u'Hello ')
+test('count', u'aaa', 3, u'a')
+test('count', u'aaa', 0, u'b')
+test('count', 'aaa', 3, u'a')
+test('count', 'aaa', 0, u'b')
+test('count', u'aaa', 3, 'a')
+test('count', u'aaa', 0, 'b')
+
test('title', u' hello ', u' Hello ')
test('title', u'hello ', u'Hello ')
test('title', u"fOrMaT thIs aS titLe String", u'Format This As Title String')
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 091ede7..eed4687 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -1236,9 +1236,14 @@ string_count(PyStringObject *self, PyObject *args)
sub = PyString_AS_STRING(subobj);
n = PyString_GET_SIZE(subobj);
}
- else if (PyUnicode_Check(subobj))
- return PyInt_FromLong(
- PyUnicode_Count((PyObject *)self, subobj, i, last));
+ else if (PyUnicode_Check(subobj)) {
+ int count;
+ count = PyUnicode_Count((PyObject *)self, subobj, i, last);
+ if (count == -1)
+ return NULL;
+ else
+ return PyInt_FromLong((long) count);
+ }
else if (PyObject_AsCharBuffer(subobj, &sub, &n))
return NULL;
@@ -1637,10 +1642,15 @@ string_startswith(PyStringObject *self, PyObject *args)
prefix = PyString_AS_STRING(subobj);
plen = PyString_GET_SIZE(subobj);
}
- else if (PyUnicode_Check(subobj))
- return PyInt_FromLong(
- PyUnicode_Tailmatch((PyObject *)self,
- subobj, start, end, -1));
+ else if (PyUnicode_Check(subobj)) {
+ int rc;
+ rc = PyUnicode_Tailmatch((PyObject *)self,
+ subobj, start, end, -1);
+ if (rc == -1)
+ return NULL;
+ else
+ return PyInt_FromLong((long) rc);
+ }
else if (PyObject_AsCharBuffer(subobj, &prefix, &plen))
return NULL;
@@ -1690,10 +1700,15 @@ string_endswith(PyStringObject *self, PyObject *args)
suffix = PyString_AS_STRING(subobj);
slen = PyString_GET_SIZE(subobj);
}
- else if (PyUnicode_Check(subobj))
- return PyInt_FromLong(
- PyUnicode_Tailmatch((PyObject *)self,
- subobj, start, end, +1));
+ else if (PyUnicode_Check(subobj)) {
+ int rc;
+ rc = PyUnicode_Tailmatch((PyObject *)self,
+ subobj, start, end, +1);
+ if (rc == -1)
+ return NULL;
+ else
+ return PyInt_FromLong((long) rc);
+ }
else if (PyObject_AsCharBuffer(subobj, &suffix, &slen))
return NULL;
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 8f7b354..a3678d5 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -1976,7 +1976,7 @@ PyObject *PyUnicode_DecodeCharmap(const char *s,
x = Py_None;
Py_INCREF(x);
} else
- goto onError;
+ goto onError;
}
/* Apply mapping */
@@ -2014,9 +2014,9 @@ PyObject *PyUnicode_DecodeCharmap(const char *s,
(targetsize << 2);
extrachars += needed;
if (_PyUnicode_Resize(v, PyUnicode_GET_SIZE(v) + needed)) {
- Py_DECREF(x);
- goto onError;
- }
+ Py_DECREF(x);
+ goto onError;
+ }
p = PyUnicode_AS_UNICODE(v) + oldpos;
}
Py_UNICODE_COPY(p,
@@ -2112,7 +2112,7 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
x = Py_None;
Py_INCREF(x);
} else
- goto onError;
+ goto onError;
}
/* Apply mapping */
@@ -2150,9 +2150,9 @@ PyObject *PyUnicode_EncodeCharmap(const Py_UNICODE *p,
(targetsize << 2);
extrachars += needed;
if (_PyString_Resize(&v, PyString_GET_SIZE(v) + needed)) {
- Py_DECREF(x);
- goto onError;
- }
+ Py_DECREF(x);
+ goto onError;
+ }
s = PyString_AS_STRING(v) + oldpos;
}
memcpy(s,
@@ -2392,6 +2392,17 @@ int count(PyUnicodeObject *self,
{
int count = 0;
+ if (start < 0)
+ start += self->length;
+ if (start < 0)
+ start = 0;
+ if (end > self->length)
+ end = self->length;
+ if (end < 0)
+ end += self->length;
+ if (end < 0)
+ end = 0;
+
if (substring->length == 0)
return (end - start + 1);