用一个名字不好的字段崩溃MongoDB,它有什么特别之处?



使用Java驱动程序,我们今天发现有可能使MongoDB实例因分段错误而关闭。

new Mongo().getDB("test").getCollection("test").
    insert(new BasicDBObject("u0000Žö", ""));

这将在mongod死亡之前从它产生以下输出:

Fri Nov 16 18:53:18 Invalid access at address: 0xbac3c5fe from thread: conn5
Fri Nov 16 18:53:18 Got signal: 11 (Segmentation fault: 11).
Fri Nov 16 18:53:18 Backtrace:
0x10004241b 0x10005628b 0x100056941 0x7fff828afcfa 0x1 0x100281611 0x100288c91 0x10006c501 0x10058e50c 0x1005e31d3 0x7fff8285b8bf 0x7fff8285eb75 
 0   mongod                              0x000000010004241b _ZN5mongo15printStackTraceERSo + 43
 1   mongod                              0x000000010005628b _ZN5mongo10abruptQuitEi + 987
 2   mongod                              0x0000000100056941 _ZN5mongo24abruptQuitWithAddrSignalEiP9__siginfoPv + 673
 3   libsystem_c.dylib                   0x00007fff828afcfa _sigtramp + 26
 4   ???                                 0x0000000000000001 0x0 + 1
 5   mongod                              0x0000000100281611 _ZN5mongo14receivedInsertERNS_7MessageERNS_5CurOpE + 1841
 6   mongod                              0x0000000100288c91 _ZN5mongo16assembleResponseERNS_7MessageERNS_10DbResponseERKNS_11HostAndPortE + 4705
 7   mongod                              0x000000010006c501 _ZN5mongo16MyMessageHandler7processERNS_7MessageEPNS_21AbstractMessagingPortEPNS_9LastErrorE + 257
 8   mongod                              0x000000010058e50c _ZN5mongo3pms9threadRunEPNS_13MessagingPortE + 1084
 9   mongod                              0x00000001005e31d3 thread_proxy + 163
 10  libsystem_c.dylib                   0x00007fff8285b8bf _pthread_start + 335
 11  libsystem_c.dylib                   0x00007fff8285eb75 thread_start + 13

我一直在试图了解到底是什么让这个神奇的领域名称与众不同。删除任何涉及的角色都会使mongodb存活得很好,而堆栈跟踪并没有让我变得更聪明。

我已经写了一篇关于这个问题的简短博客文章,并在 mongodb.org 提交了JIRA票,但我的好奇心正在杀死我。谁能弄清楚是什么让u0000Žö与众不同?

编辑以澄清u0000u0000Ž很好,u0000Žsomerandomtext也是如此

它不能正常工作的原因是 unicode 文字语句损坏的方式。可能存在 java 驱动程序没有正确检查可能性的可能性,Unicode 文字语句中可能存在 unicode;)在 mongo shell 上,使用这样的键创建对象(复制到基于 UTF8 的终端)抛出错误:BSONElement: bad type -59

Java String s 只能用 ASCII 编码表示,要获得 unicode 文字,您必须获取每个 unicode 代码并构建字符串:

String unicode = "u1123u5678hello";

将导致:

ᄣ噸hello

最新更新