1
0
Fork 0

additionally allow the following characters in document keys:

`(` `)` `+` `,` `=` `;` `$` `!` `*` `'` `%`
This commit is contained in:
jsteemann 2015-09-15 00:16:08 +02:00
parent 57f617c9a4
commit 22e17814e3
9 changed files with 135 additions and 27 deletions

View File

@ -1,6 +1,14 @@
v2.7.0 (XXXX-XX-XX)
-------------------
* additionally allow the following characters in document keys:
`(` `)` `+` `,` `=` `;` `$` `!` `*` `'` `%`
v2.7.0-rc1 (XXXX-XX-XX)
-----------------------
* added extra AQL functions for date and time calculation and manipulation.
These functions were contributed by GitHub users @CoDEmanX and @friday.
A big thanks for their work!

View File

@ -8,9 +8,9 @@ restrictions:
* The key must be at least 1 byte and at most 254 bytes long. Empty keys are
disallowed when specified (though it may be valid to completely omit the
*_key* attribute from a document)
* It must consist of the letters a-z (lower or upper case), the digits 0-9,
the underscore (`_`), dash (`-`), colon (`:`), dot (.) or at-mark (`@`) characters
only
* It must consist of the letters a-z (lower or upper case), the digits 0-9
or any of the following punctuation characters:
`_` `-` `:` `.` `@` `(` `)` `+` `,` `=` `;` `$` `!` `*` `'` `%`
* Any other characters, especially multi-byte sequences, whitespace or punctuation
characters cannot be used inside key values
* The key must be unique within the collection it is used

View File

@ -119,24 +119,17 @@ describe ArangoDB do
"\\rabcd",
"abcd defg",
"abcde/bdbg",
"a/a",
"/a",
"adbfbgb/",
"öööää",
"müller",
"m+ller",
"\\\"invalid",
"'invalid",
"\\\\invalid",
"\\\\\\\\invalid",
";invalid",
",invalid",
"!invalid",
"?invalid",
"$invalid",
"#invalid",
"%invalid",
"&invalid",
"(invalid)",
"[invalid]",
"a" * 255
]
@ -183,12 +176,57 @@ describe ArangoDB do
"-foobar",
"_foobar",
"@foobar",
"(valid)",
"%valid",
"$valid",
"$$bill,y'all",
"'valid",
"'a-key-is-a-key-is-a-key'",
"m+ller",
";valid",
",valid",
"!valid!",
":",
":::",
":-:-:",
";",
";;;;;;;;;;",
"(",
")",
"()xoxo()",
"%",
"%-%-%-%",
":-)",
"!",
"!!!!",
"'",
"''''",
"this-key's-valid.",
"=",
"==================================================",
"-=-=-=___xoxox-",
"*",
"(*)",
"****",
".",
"...",
"-",
"--",
"_",
"__",
"(" * 254, # 254 bytes is the maximum allowed length
")" * 254, # 254 bytes is the maximum allowed length
"," * 254, # 254 bytes is the maximum allowed length
":" * 254, # 254 bytes is the maximum allowed length
";" * 254, # 254 bytes is the maximum allowed length
"*" * 254, # 254 bytes is the maximum allowed length
"=" * 254, # 254 bytes is the maximum allowed length
"-" * 254, # 254 bytes is the maximum allowed length
"%" * 254, # 254 bytes is the maximum allowed length
"@" * 254, # 254 bytes is the maximum allowed length
"'" * 254, # 254 bytes is the maximum allowed length
"." * 254, # 254 bytes is the maximum allowed length
"!" * 254, # 254 bytes is the maximum allowed length
"_" * 254, # 254 bytes is the maximum allowed length
"a" * 254 # 254 bytes is the maximum allowed length
]

View File

@ -90,6 +90,7 @@
#include "V8/v8-utils.h"
#include "V8Server/ApplicationV8.h"
#include "VocBase/auth.h"
#include "VocBase/KeyGenerator.h"
#include "VocBase/server.h"
#include "Wal/LogfileManager.h"
@ -856,10 +857,13 @@ int ArangoServer::startupServer () {
LOG_FATAL_AND_EXIT("unable to start WAL logfile manager");
}
// .............................................................................
// prepare the various parts of the Arango server
// .............................................................................
KeyGenerator::Initialize();
if (_dispatcherThreads < 1) {
_dispatcherThreads = 1;
}

View File

@ -39,6 +39,49 @@
#include "VocBase/vocbase.h"
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief lookup table for key checks
////////////////////////////////////////////////////////////////////////////////
std::array<bool, 256> KeyGenerator::LookupTable;
////////////////////////////////////////////////////////////////////////////////
/// @brief initialize the lookup table for key checks
////////////////////////////////////////////////////////////////////////////////
void KeyGenerator::Initialize () {
for (int c = 0; c < 256; ++c) {
if ((c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '_' ||
c == ':' ||
c == '-' ||
c == '@' ||
c == '.' ||
c == '(' ||
c == ')' ||
c == '+' ||
c == ',' ||
c == '=' ||
c == ';' ||
c == '$' ||
c == '!' ||
c == '*' ||
c == '\'' ||
c == '%') {
LookupTable[c] = true;
}
else {
LookupTable[c] = false;
}
}
}
// -----------------------------------------------------------------------------
// --SECTION-- GENERAL KEY GENERATOR
// -----------------------------------------------------------------------------
@ -233,24 +276,18 @@ TraditionalKeyGenerator::~TraditionalKeyGenerator () {
////////////////////////////////////////////////////////////////////////////////
bool TraditionalKeyGenerator::validateKey (char const* key) {
char const* p = key;
unsigned char const* p = reinterpret_cast<unsigned char const*>(key);
unsigned char const* s = p;
while (true) {
char c = *p;
unsigned char c = *p;
if (c == '\0') {
return ((p - key) > 0) &&
((p - key) <= TRI_VOC_KEY_MAX_LENGTH);
return ((p - s) > 0) &&
((p - s) <= TRI_VOC_KEY_MAX_LENGTH);
}
if ((c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '_' ||
c == ':' ||
c == '-' ||
c == '@' ||
c == '.') {
if (LookupTable[c]) {
++p;
continue;
}

View File

@ -103,6 +103,12 @@ class KeyGenerator {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief initialize the lookup table for key checks
////////////////////////////////////////////////////////////////////////////////
static void Initialize ();
////////////////////////////////////////////////////////////////////////////////
/// @brief get the generator type from JSON
////////////////////////////////////////////////////////////////////////////////
@ -168,6 +174,13 @@ class KeyGenerator {
////////////////////////////////////////////////////////////////////////////////
bool _allowUserKeys;
////////////////////////////////////////////////////////////////////////////////
/// @brief lookup table for key checks
////////////////////////////////////////////////////////////////////////////////
static std::array<bool, 256> LookupTable;
};
// -----------------------------------------------------------------------------

View File

@ -78,7 +78,7 @@ ArangoDatabase.indexRegex = /^([a-zA-Z0-9\-_]+)\/([0-9]+)$/;
/// @brief key regex
////////////////////////////////////////////////////////////////////////////////
ArangoDatabase.keyRegex = /^([a-zA-Z0-9_:\-@\.])+$/;
ArangoDatabase.keyRegex = /^([a-zA-Z0-9_:\-@\.\(\)\+,=;\$!\*'%])+$/;
////////////////////////////////////////////////////////////////////////////////
/// @brief append the waitForSync parameter to a URL

View File

@ -77,7 +77,7 @@ ArangoDatabase.indexRegex = /^([a-zA-Z0-9\-_]+)\/([0-9]+)$/;
/// @brief key regex
////////////////////////////////////////////////////////////////////////////////
ArangoDatabase.keyRegex = /^([a-zA-Z0-9_:\-@\.])+$/;
ArangoDatabase.keyRegex = /^([a-zA-Z0-9_:\-@\.\(\)\+,=;\$!\*'%])+$/;
////////////////////////////////////////////////////////////////////////////////
/// @brief append the waitForSync parameter to a URL

View File

@ -294,7 +294,7 @@ function CollectionDocumentSuite () {
////////////////////////////////////////////////////////////////////////////////
testSaveInvalidDocumentKeyValue : function () {
[ "", " ", " a", "a ", "/", "|", "#", "a/a" ].forEach(function (key) {
[ "", " ", " ", " a", "a ", "/", "|", "#", "a/a", "\0", "\r", "\n", "\t", "\"", "[", "]", "{", "}", "\\" ].forEach(function (key) {
try {
collection.save({ _key: key });
fail();
@ -310,7 +310,15 @@ function CollectionDocumentSuite () {
////////////////////////////////////////////////////////////////////////////////
testSaveSpecialCharsDocumentKey : function () {
[ ":", "-", "_", "@", "a@b", "a@b.c", "a-b-c", "_a", "@a", "@a-b", ":80", ":_", "@:_" ].forEach(function (key) {
[ ":", "-", "_", "@", "a@b", "a@b.c", "a-b-c", "_a", "@a", "@a-b", ":80", ":_", "@:_",
"0", "1", "123456", "0123456", "true", "false", "a", "A", "a1", "A1", "01ab01", "01AB01",
"abcd-efgh", "abcd_efgh", "Abcd_Efgh", "@", "@@", "abc@foo.bar", "@..abc-@-foo__bar",
".foobar", "-foobar", "_foobar", "@foobar", "(valid)", "%valid", "$valid",
"$$bill,y'all", "'valid", "'a-key-is-a-key-is-a-key'", "m+ller", ";valid", ",valid", "!valid!",
":", ":::", ":-:-:", ";", ";;;;;;;;;;", "(", ")", "()xoxo()", "%",
"%-%-%-%", ":-)", "!", "!!!!", "'", "''''", "this-key's-valid.", "=",
"==================================================", "-=-=-=___xoxox-",
"*", "(*)", "****", ".", "...", "-", "--", "_", "__" ].forEach(function (key) {
var doc1 = collection.save({ _key: key, value: key });
assertEqual(key, doc1._key);
assertEqual(cn + "/" + key, doc1._id);