【问题标题】:SWIG wrong encoded string crashes PythonSWIG 错误的编码字符串使 Python 崩溃
【发布时间】:2019-09-01 22:49:38
【问题描述】:

我有一个问题,我所有处理字符串的 SWIG 包装器都崩溃了UTF-8 无效。

在我的代码方面,我已经解决了将输入解析为宽字符串并将它们转换为 UTF-8 的问题,但我想用异常而不是崩溃来捕获这类错误,不应该 PyUnicode_Check 失败用那些字符串?

Swig 在调用 PyString_AsStringAndSize() 时实际上会在 SWIG_AsCharPtrAndSize() 中崩溃,这是 swig 生成的代码:

    SWIGINTERN int
SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
{
#if PY_VERSION_HEX>=0x03000000
#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
  if (PyBytes_Check(obj))
#else
  if (PyUnicode_Check(obj))
#endif
#else  
  if (PyString_Check(obj))
#endif
  {
    char *cstr; Py_ssize_t len;
#if PY_VERSION_HEX>=0x03000000
#if !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
    if (!alloc && cptr) {
        /* We can't allow converting without allocation, since the internal
           representation of string in Python 3 is UCS-2/UCS-4 but we require
           a UTF-8 representation.
           TODO(bhy) More detailed explanation */
        return SWIG_RuntimeError;
    }
    obj = PyUnicode_AsUTF8String(obj);
    if(alloc) *alloc = SWIG_NEWOBJ;
#endif
    PyBytes_AsStringAndSize(obj, &cstr, &len);
#else
    PyString_AsStringAndSize(obj, &cstr, &len);
#endif
    if (cptr) {

崩溃发生在最后一个可见的 PyString_AsStringAndSize 中。 我注意到字符串作为 std::string 传递,但也发生在 const char* 中,没有任何区别。

感谢您的建议!

【问题讨论】:

  • 你的目标是什么版本的python?你用的是什么版本的 swig?
  • python 3.3 和 swig 3.0.12
  • 所以你没有正确定义 PY_VERSION_HEX。
  • 你能举一个小例子来说明一个函数及其重现问题的 SWIG .i 文件吗?

标签: unicode utf-8 swig stdstring


【解决方案1】:

无法复制。如果此示例无法解决您的问题并需要进一步帮助,请编辑您的问题并添加 Minimal, Complete, Verifable Example

test.i

%module test

%include <std_string.i>

%inline %{
#include <string>

std::string func(std::string s)
{
    return '[' + s + ']';
}
%}

演示:

Python 3.3.5 (v3.3.5:62cf4e77f785, Mar  9 2014, 10:35:05) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> test.func('ábc')
'[ábc]'

【讨论】:

  • 这是回归的方式,我们调用一个基类(在 c++ 中),它被 Swig 主管覆盖。传递带有非 UTF8 有效字符的 const char* 会使 Python 崩溃。目前我们已经解决了使用 UTF8 检查例程清理缓冲区的问题,但在我看来这仍然是 Python 中的一个错误
【解决方案2】:

问题在于我们仍在使用的 3.3.0 版本,更新到 3.3.7 解决了这个问题,在 Python 发行说明中修复了几个关于 PyUnicode_Check 的错误

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-29
    • 1970-01-01
    • 2017-03-08
    • 2011-08-11
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多