self.assertEqual(buildvalue('((OO))', 1, 2), ((1, 2),))
self.assertEqual(buildvalue(' \t,:'), None)
+ self.assertEqual(buildvalue('O,', 1), 1)
self.assertEqual(buildvalue(' O ', 1), 1)
self.assertEqual(buildvalue('\tO\t', 1), 1)
self.assertEqual(buildvalue('O,O', 1, 2), (1, 2))
self.assertEqual(buildvalue('O O', 1, 2), (1, 2))
self.assertEqual(buildvalue('O\tO', 1, 2), (1, 2))
self.assertEqual(buildvalue('(O,O)', 1, 2), (1, 2))
- self.assertEqual(buildvalue('(O, O)', 1, 2), (1, 2))
- self.assertEqual(buildvalue(' ( O O) ', 1, 2), (1, 2))
- self.assertEqual(buildvalue('\t(\tO\tO)\t', 1, 2), (1, 2))
+ self.assertEqual(buildvalue('(O, O,)', 1, 2), (1, 2))
+ self.assertEqual(buildvalue(' ( O O ) ', 1, 2), (1, 2))
+ self.assertEqual(buildvalue('\t(\tO\tO\t)\t', 1, 2), (1, 2))
self.assertEqual(buildvalue('[O,O]', 1, 2), [1, 2])
- self.assertEqual(buildvalue('[O, O]', 1, 2), [1, 2])
- self.assertEqual(buildvalue(' [ O O] ', 1, 2), [1, 2])
+ self.assertEqual(buildvalue('[O, O,]', 1, 2), [1, 2])
+ self.assertEqual(buildvalue(' [ O O ] ', 1, 2), [1, 2])
+ self.assertEqual(buildvalue(' [\tO\tO\t] ', 1, 2), [1, 2])
self.assertEqual(buildvalue('{O:O}', 1, 2), {1: 2})
self.assertEqual(buildvalue('{O:O,O:O}', 1, 2, 3, 4), {1: 2, 3: 4})
- self.assertEqual(buildvalue('{O: O, O: O}', 1, 2, 3, 4), {1: 2, 3: 4})
- self.assertEqual(buildvalue(' { O O O O} ', 1, 2, 3, 4), {1: 2, 3: 4})
- self.assertEqual(buildvalue('\t{\tO\tO\tO\tO}\t', 1, 2, 3, 4), {1: 2, 3: 4})
+ self.assertEqual(buildvalue('{O: O, O: O,}', 1, 2, 3, 4), {1: 2, 3: 4})
+ self.assertEqual(buildvalue(' { O O O O } ', 1, 2, 3, 4), {1: 2, 3: 4})
+ self.assertEqual(buildvalue('\t{\tO\tO\tO\tO\t}\t', 1, 2, 3, 4), {1: 2, 3: 4})
self.assertRaises(SystemError, buildvalue, 'O', NULL)
self.assertRaises(SystemError, buildvalue, '(O)', NULL)
self.assertEqual(buildvalue('C', sys.maxunicode), chr(sys.maxunicode))
self.assertRaises(ValueError, buildvalue, 'C', -1)
self.assertRaises(ValueError, buildvalue, 'C', sys.maxunicode+1)
+
+ # gh-84489
+ self.assertRaises(ValueError, buildvalue, '(C )i', -1, 2)
+ self.assertRaises(ValueError, buildvalue, '[C ]i', -1, 2)
+ self.assertRaises(ValueError, buildvalue, '{Ci }i', -1, 2, 3)
+
def test_buildvalue_N(self):
_testcapi.test_buildvalue_N()
static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t);
static PyObject *do_mkvalue(const char**, va_list *);
+static int
+check_end(const char **p_format, char endchar)
+{
+ const char *f = *p_format;
+ while (*f != endchar) {
+ if (*f != ' ' && *f != '\t' && *f != ',' && *f != ':') {
+ PyErr_SetString(PyExc_SystemError,
+ "Unmatched paren in format");
+ return 0;
+ }
+ f++;
+ }
+ if (endchar) {
+ f++;
+ }
+ *p_format = f;
+ return 1;
+}
static void
do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n)
}
}
Py_XDECREF(v);
- if (**p_format != endchar) {
- PyErr_SetString(PyExc_SystemError,
- "Unmatched paren in format");
+ if (!check_end(p_format, endchar)) {
return;
}
- if (endchar) {
- ++*p_format;
- }
}
static PyObject *
Py_DECREF(k);
Py_DECREF(v);
}
- if (**p_format != endchar) {
+ if (!check_end(p_format, endchar)) {
Py_DECREF(d);
- PyErr_SetString(PyExc_SystemError,
- "Unmatched paren in format");
return NULL;
}
- if (endchar)
- ++*p_format;
return d;
}
}
PyList_SET_ITEM(v, i, w);
}
- if (**p_format != endchar) {
+ if (!check_end(p_format, endchar)) {
Py_DECREF(v);
- PyErr_SetString(PyExc_SystemError,
- "Unmatched paren in format");
return NULL;
}
- if (endchar)
- ++*p_format;
return v;
}
}
stack[i] = w;
}
- if (**p_format != endchar) {
- PyErr_SetString(PyExc_SystemError,
- "Unmatched paren in format");
+ if (!check_end(p_format, endchar)) {
goto error;
}
- if (endchar) {
- ++*p_format;
- }
return 0;
error:
}
PyTuple_SET_ITEM(v, i, w);
}
- if (**p_format != endchar) {
+ if (!check_end(p_format, endchar)) {
Py_DECREF(v);
- PyErr_SetString(PyExc_SystemError,
- "Unmatched paren in format");
return NULL;
}
- if (endchar)
- ++*p_format;
return v;
}