From 37379a2974190ab0fc97f840112d5a40c907368b Mon Sep 17 00:00:00 2001
From: Paul Sokolovsky <pfalcon@users.sourceforge.net>
Date: Tue, 29 Aug 2017 00:06:21 +0300
Subject: [PATCH] py/objstr: startswith, endswith: Check arg to be a string.

Otherwise, it will silently get incorrect result on other values types,
including CPython tuple form like "foo.png".endswith(("png", "jpg"))
(which MicroPython doesn't support for unbloatedness).
---
 py/objstr.c                               | 6 ++++--
 tests/basics/string_endswith.py           | 5 +++++
 tests/basics/string_endswith_upy.py       | 6 ++++++
 tests/basics/string_endswith_upy.py.exp   | 1 +
 tests/basics/string_startswith.py         | 5 +++++
 tests/basics/string_startswith_upy.py     | 6 ++++++
 tests/basics/string_startswith_upy.py.exp | 1 +
 7 files changed, 28 insertions(+), 2 deletions(-)
 create mode 100644 tests/basics/string_endswith_upy.py
 create mode 100644 tests/basics/string_endswith_upy.py.exp
 create mode 100644 tests/basics/string_startswith_upy.py
 create mode 100644 tests/basics/string_startswith_upy.py.exp

diff --git a/py/objstr.c b/py/objstr.c
index d4c038a68..f04bd90be 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -726,7 +726,8 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rindex_obj, 2, 4, str_rindex);
 STATIC mp_obj_t str_startswith(size_t n_args, const mp_obj_t *args) {
     const mp_obj_type_t *self_type = mp_obj_get_type(args[0]);
     GET_STR_DATA_LEN(args[0], str, str_len);
-    GET_STR_DATA_LEN(args[1], prefix, prefix_len);
+    size_t prefix_len;
+    const char *prefix = mp_obj_str_get_data(args[1], &prefix_len);
     const byte *start = str;
     if (n_args > 2) {
         start = str_index_to_ptr(self_type, str, str_len, args[2], true);
@@ -740,7 +741,8 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_startswith_obj, 2, 3, str_startswith);
 
 STATIC mp_obj_t str_endswith(size_t n_args, const mp_obj_t *args) {
     GET_STR_DATA_LEN(args[0], str, str_len);
-    GET_STR_DATA_LEN(args[1], suffix, suffix_len);
+    size_t suffix_len;
+    const char *suffix = mp_obj_str_get_data(args[1], &suffix_len);
     if (n_args > 2) {
         mp_raise_NotImplementedError("start/end indices");
     }
diff --git a/tests/basics/string_endswith.py b/tests/basics/string_endswith.py
index 3e8fba925..683562d10 100644
--- a/tests/basics/string_endswith.py
+++ b/tests/basics/string_endswith.py
@@ -10,3 +10,8 @@ print("foobar".endswith("foobarbaz"))
 #print("1foo".startswith("1foo", 1))
 #print("1fo".startswith("foo", 1))
 #print("1fo".startswith("foo", 10))
+
+try:
+    "foobar".endswith(1)
+except TypeError:
+    print("TypeError")
diff --git a/tests/basics/string_endswith_upy.py b/tests/basics/string_endswith_upy.py
new file mode 100644
index 000000000..06a4e71d2
--- /dev/null
+++ b/tests/basics/string_endswith_upy.py
@@ -0,0 +1,6 @@
+# MicroPython doesn't support tuple argument
+
+try:
+    "foobar".endswith(("bar", "sth"))
+except TypeError:
+    print("TypeError")
diff --git a/tests/basics/string_endswith_upy.py.exp b/tests/basics/string_endswith_upy.py.exp
new file mode 100644
index 000000000..6002b71c5
--- /dev/null
+++ b/tests/basics/string_endswith_upy.py.exp
@@ -0,0 +1 @@
+TypeError
diff --git a/tests/basics/string_startswith.py b/tests/basics/string_startswith.py
index 5cf730c03..e63ae3c18 100644
--- a/tests/basics/string_startswith.py
+++ b/tests/basics/string_startswith.py
@@ -9,3 +9,8 @@ print("1foo".startswith("foo", 1))
 print("1foo".startswith("1foo", 1))
 print("1fo".startswith("foo", 1))
 print("1fo".startswith("foo", 10))
+
+try:
+    "foobar".startswith(1)
+except TypeError:
+    print("TypeError")
diff --git a/tests/basics/string_startswith_upy.py b/tests/basics/string_startswith_upy.py
new file mode 100644
index 000000000..9ea1796c2
--- /dev/null
+++ b/tests/basics/string_startswith_upy.py
@@ -0,0 +1,6 @@
+# MicroPython doesn't support tuple argument
+
+try:
+    "foobar".startswith(("foo", "sth"))
+except TypeError:
+    print("TypeError")
diff --git a/tests/basics/string_startswith_upy.py.exp b/tests/basics/string_startswith_upy.py.exp
new file mode 100644
index 000000000..6002b71c5
--- /dev/null
+++ b/tests/basics/string_startswith_upy.py.exp
@@ -0,0 +1 @@
+TypeError
-- 
GitLab