1
0
Fork 0

issue #1409: fix NUL-byte handling

This commit is contained in:
jsteemann 2015-12-17 00:49:46 +01:00 committed by Jan Steemann
parent c4f5f69b01
commit ead2ee47e7
3 changed files with 95 additions and 5 deletions

View File

@ -1012,7 +1012,7 @@ AstNode* Ast::createNodeValueString (char const* value,
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
if (*value == '\0') {
if (length == 0) {
// performance optimization:
// return a pointer to the singleton empty string node
// note: these nodes are never registered nor freed

View File

@ -485,6 +485,87 @@ function AttributesSuite () {
assertEqual("foo\u0001bar\u0000baz", result[0].abc);
assertEqual("\u0000test\u0000test", result[0].def);
assertEqual("abc\u0000", result[0]["123"]);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test values containing NULL bytes
////////////////////////////////////////////////////////////////////////////////
testNullBytesValues : function () {
var docs = [
{ value: "\u0000zero\u0000", _key: "first" },
{ value: "\u0000\r\nnew line", _key: "second" },
{ value: "\u0000zero", _key: "third" },
{ value: "0\r\nxxx", _key: "fourth" }
];
docs.forEach(function(doc) {
c.insert(doc);
});
// test return value of document()
docs.forEach(function(doc) {
var d = c.document(doc._key);
assertEqual(doc.value, d.value);
});
// test return value of AQL, using literals
docs.forEach(function(doc) {
var result = db._query("FOR doc IN @@collection FILTER doc.value == " +
JSON.stringify(doc.value) + " RETURN doc", {
"@collection" : c.name()
}).toArray();
assertEqual(1, result.length, doc);
assertEqual(doc.value, result[0].value);
assertEqual(doc._key, result[0]._key);
});
// test return value of AQL, using bind parameters
docs.forEach(function(doc) {
var result = db._query("FOR doc IN @@collection FILTER doc.value == @value RETURN doc", {
"@collection" : c.name(),
value: doc.value
}).toArray();
assertEqual(1, result.length, doc);
assertEqual(doc.value, result[0].value);
assertEqual(doc._key, result[0]._key);
});
// test return value of AQL
var result;
result = db._query("FOR doc IN @@collection FILTER SUBSTRING(doc.value, 0, 5) == @value RETURN doc._key", {
"@collection" : c.name(),
value: "\u0000zero"
}).toArray().sort();
assertEqual(2, result.length);
assertEqual([ "first", "third" ], result);
result = db._query("FOR doc IN @@collection FILTER SUBSTRING(doc.value, 0, 6) == @value RETURN doc._key", {
"@collection" : c.name(),
value: "\u0000zero\u0000"
}).toArray();
assertEqual(1, result.length);
assertEqual([ "first" ], result);
result = db._query("FOR doc IN @@collection FILTER SUBSTRING(doc.value, 0, 1) == " +
JSON.stringify("\0") + " RETURN doc._key", {
"@collection" : c.name()
}).toArray().sort();
assertEqual(3, result.length);
assertEqual([ "first", "second", "third" ], result);
result = db._query("FOR doc IN @@collection FILTER SUBSTRING(doc.value, 0, 1) == @value RETURN doc._key", {
"@collection" : c.name(),
value: "\0",
}).toArray().sort();
assertEqual(3, result.length);
assertEqual([ "first", "second", "third" ], result);
}
};

View File

@ -244,14 +244,18 @@ int TRI_CompareValuesJson (TRI_json_t const* lhs,
case TRI_JSON_STRING_REFERENCE: {
// same for STRING and STRING_REFERENCE
int res;
size_t const nl = lhs->_value._string.length - 1;
size_t const nr = rhs->_value._string.length - 1;
if (useUTF8) {
res = TRI_compare_utf8(lhs->_value._string.data,
lhs->_value._string.length - 1,
nl,
rhs->_value._string.data,
rhs->_value._string.length - 1);
nr);
}
else {
res = strcmp(lhs->_value._string.data, rhs->_value._string.data);
// beware of strings containing NUL bytes
size_t len = nl < nr ? nl : nr;
res = memcmp(lhs->_value._string.data, rhs->_value._string.data, len);
}
if (res < 0) {
return -1;
@ -259,7 +263,12 @@ int TRI_CompareValuesJson (TRI_json_t const* lhs,
else if (res > 0) {
return 1;
}
return 0;
// res == 0
if (nl == nr) {
return 0;
}
// res == 0, but different string lengths
return nl < nr ? -1 : 1;
}
case TRI_JSON_ARRAY: {