- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
众所周知,那个小bytes
-objects 被 CPython 自动“interned”(类似于 intern 字符串的函数)。 更正:如 explained @abernert 它更像是整数池而不是内部字符串。
是否可以在内部字节对象被“实验性”第三方库损坏后恢复它们,或者是重新启动内核的唯一方法?
概念证明可以使用 Cython 功能(Cython>=0.28)完成:
%%cython
def do_bad_things():
cdef bytes b=b'a'
cdef const unsigned char[:] safe=b
cdef char *unsafe=<char *> &safe[0] #who needs const and type-safety anyway?
unsafe[0]=98 #replace through `b`
ctypes
:
import ctypes
import sys
def do_bad_things():
b = b'a';
(ctypes.c_ubyte * sys.getsizeof(b)).from_address(id(b))[-2] = 98
do_bad_things
更改不可变(或 CPython 认为)对象
b'a'
至
b'b'
因为这个
bytes
-object 被实习,我们可以看到之后发生了不好的事情:
>>> do_bad_things() #b'a' means now b'b'
>>> b'a'==b'b' #wait for a surprise
True
>>> print(b'a') #another one
b'b'
b'a'
意味着
b'a'
再次?
bytes
-创建进程正在使用这个池。例如:
>>> do_bad_things()
>>> print(b'a')
b'b'
>>> print((97).to_bytes(1, byteorder='little')) #ord('a')=97
b'a'
最佳答案
Python 3 不像 bytes
那样实习 str
对象。相反,它像使用 int
一样保留了它们的静态数组。
这在幕后是非常不同的。不利的一面是,这意味着没有要操作的表(带有 API)。从好的方面来说,这意味着如果你能找到静态数组,你就可以修复它,就像修复整数一样,因为数组索引和字符串的字符值应该是相同的。
如果您查看 bytesobject.c
,则会在顶部声明该数组:
static PyBytesObject *characters[UCHAR_MAX + 1];
PyBytes_FromStringAndSize
中:
if (size == 1 && str != NULL &&
(op = characters[*str & UCHAR_MAX]) != NULL)
{
#ifdef COUNT_ALLOCS
one_strings++;
#endif
Py_INCREF(op);
return (PyObject *)op;
}
static
,因此无法从该文件外部访问它,并且它仍在对对象进行引用计数,因此调用者(甚至解释器中的内部内容,更不用说您的 C API 扩展)无法判断有什么特别之处在。
bytes
并减去它应该是的字符。
PyBytes_FromStringAndSize("a", 1)
将返回应该是
'a'
的对象,即使它碰巧实际持有
'b'
。我们怎么知道?因为这正是您要解决的问题。
a
更不容易被破坏的字符,例如
\x80
:
PyBytesObject *byte80 = (PyBytesObject *)PyBytes_FromStringAndSize("\x80", 1);
PyBytesObject *characters = byte80 - 0x80;
ctypes
而不是 C 代码从 Python 执行此操作,则需要一些额外的小心,1 但由于您没有使用
ctypes
,所以我们不必担心。
characters
的指针,我们可以遍历它。我们不能只是删除对象来“取消实习”它们,因为这会使任何引用它们的人都感到沮丧,并可能导致段错误。但我们没有必要。表中的任何对象,我们都知道它应该是什么——
characters[i]
应该是一个单字符的
bytes
,其一个字符是
i
。所以只需将它设置回那个,循环如下:
for (size_t char i=0; i!=UCHAR_MAX; i++) {
if (characters[i]) {
// do the same hacky stuff you did to break the string in the first place
}
}
b'\x80'
参数进入 C 调用之前将它变成错误的东西。你会惊讶于所有你认为你正在传递
c_char_p
的地方,它实际上是神奇地与
bytes
相互转换。使用
POINTER(c_uint8)
可能更好。
b'a'
的代码,consts 数组应该有一个对
b'a'
的引用,这将得到修复。但是,由于
bytes
对编译器来说是不可变的,如果它知道
b'a' == b'b'
,它实际上可能会存储指向
b'b'
单例的指针,原因与
123456 is 123456
为真,在这种情况下,修复
b'a'
可能实际上并不能解决问题。
关于python - 是否可以恢复损坏的 “interned” 字节对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50708670/
有什么方法可以恢复删除的元素吗? 这是我删除元素的代码 myFunction() { var width = window.innerWidth; var February = doc
我有一个 TokuDB 表,由于某种原因缺少 ***_status.tokudb 文件。 我还不确定文件是否由于 TokuDB 崩溃而丢失。 问题是: 有没有办法从主要文件和关键文件(我可以从 tok
我正在 Windows 7 (x86) 上运行带有 Workbench 6.3.8 的 32 位 MySQL Server 5.7.22 本地实例(必须选择 32 位版本 - 所以,较旧的版本)。 我
1、备份 <% SQL="backup database 数据库名 to disk='"&Serve
1、ASP中怎么实现SQL数据库备份、恢复! 答:asp在线备份sql server数据库: 1、备份 <% SQL="ba
我在 R 中使用 stats::filter 函数来理解 R 中的 ARIMA 模拟(如在函数 stats::arima.sim 中)和估计。我知道 stats::filter 将线性过滤器应用于向量
我已经浏览了示例应用程序的文档和代码,并发现 files/objectbox/objectbox/data.mdb 是存储所有数据的默认文件。 假设我的理解是正确的,我有几个问题找不到文档: 我想在我
为了恢复非续订订阅类型的 InAppPurchase,我已经实现了服务器来处理此问题。 但在购买过程中,iTunes 有时不会要求用户验证他们的卡详细信息, 在这种情况下,它会在后台发送应用程序并显示
我的问题是寻找cocos2d游戏期间暂停/恢复状态(包括所有需要保存的数据信息)的设计解决方案。 包括但不限于以下情况: 1).用户选择退出,然后弹出一个对话框供用户选择“直接退出”、“暂停”; 2)
在 Mercurial 中,我有一个旧的变更集,除了对单个文件的更改外,它都很好。我将如何恢复对该单个文件的更改? 即使只是能够在上一个变更集中查看文件的状态也会很好,然后我可以剪切和粘贴。 我的 M
我的一项职能遇到了困难。我想做的是计时器在页面加载后立即启动,并且只有一个带有启动/恢复的按钮。我无法在代码中找出需要更改功能的位置。有人可以帮助我吗?谢谢! HTML: , Javascr
我正在阅读Scrap your type classes 。这为类型类提供了替代方案。然而,我被Paul Chiusano的评论所困扰。其中讨论了恢复 do 表示法 语法。 坦白说,我无法理解 ret
当 OrientDB 因某人重新启动机器而非正常关闭时,OrientDB 最终会处于数据恢复失败的状态。对于如何从这种不正常的关闭中正常恢复有什么建议吗?我们正在寻找系统在断电期间能够自行恢复的方法。
我正在构建一个 Electron 应用程序,如果发生崩溃,它必须重新加载渲染进程窗口。 目前我可以从主进程重新启动应用程序 app.relaunch(); app.quit(); 但我无法检测到窗口崩
我有 3 个 Activity ,比如说 MainActivity、 Activity 2 和 Activity 3。 在 MainActivity 中,我有一个按钮(开始/停止),当我单击此按钮时,
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 11 年前。 Improve thi
Twilio 是否支持暂停和恢复内容播放。换句话说,我有相当长的文件将播放给调用者,并且我正在尝试找到一种方法来实现暂停和恢复功能。在播放某些内容的过程中,我希望用户能够按数字暂停,然后再次按数字从音
我已经提交了 A、B、C、D 和 E。我意识到在提交 B 中发生了一些非常糟糕的事情,所以我想回到 A,这次正确地进行之前搞砸了 B 的更改,然后重新应用 C 、 D 和 E 自动。 您可能想知道为什
我的一个文件被“标记为文本”,图标也发生了变化。实际上这是一个 PHP 文件。我尝试过使用 Help -> Find Action -> Mark As 尝试将其恢复为 PHP 突出显示,但它不起作用
我有一些 SSE 程序,可以将循环中的内存归零,当指针未对齐时,它会引发 SIGSEGV进入我的处理程序。我可以在此类处理程序中获取更多信息吗例行公事,现在我不知道它是在哪里完成的,我也可以吗以某种可
我是一名优秀的程序员,十分优秀!