linux系统下导入crypto的RSA报错,异常堆栈图如下:
最终导致python中使用re模块时报的这个异常,正常情况下bytes类型re也是能正常处理的。
正常写个简单的demo导入RSA是不报错的,说明源码是没问题的,那就从项目中找问题。
排查发现项目中对subprocess.Popen进行了重写,在执行execjs的时候一般中文乱码需要将编码固定,
subprocess.Popen = partial(subprocess.Popen, encoding="UTF-8")
这里用偏函数的方法对Popen进行了重新定义,但是后续很多库中是会使用subprocess.Popen去执行命令;这时候他们使用的就不再是原生Popen方法了,难免会有影响;
刚好这里ctype模块里util.py再次使用subprocess.Popen时,p.stdout.read()取出的数据类型就不正确了!!!
下面代码是ctype模块的util.py下的
# XXX assuming GLIBC's ldconfig (with option -p)
regex = r'\s+(lib%s\.[^\s]+)\s+\(%s'
regex = os.fsencode(regex % (re.escape(name), abi_type))
try:
with subprocess.Popen(['/sbin/ldconfig', '-p'],
stdin=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
stdout=subprocess.PIPE,
env={'LC_ALL': 'C', 'LANG': 'C'}) as p:
# Popen被重写后,p.stdout.read()应该返回字节,这里直接返回字符串了
res = re.search(regex, p.stdout.read())
if res:
return os.fsdecode(res.group(1))
except OSError:
pass
解决办法:
在使用完execjs后,还原subprocess.Popen即可;
可以先对其备份,在执行完execjs后再还原为原来的函数;
切记:关于系统函数,谨慎修改!