Skip to content

Commit 259d417

Browse files
authored
[2.10] MOD-7864: Obfuscation API (#5487)
MOD-7864: Obfuscation API (#5060) * MOD-7864: initial commit * * modify object obfuscate api * * compilation fixes * * fix tests * * add query node obfuscation test * * Code Review - Round #1 * * add field path obfuscation * update tests * * Code Review - Round #2 * * Code Review - Round #3 * * Code Review - Round #4 * * add MAX_UNIQUE_ID_TEXT_LENGTH_UPPER_BOUND, compute it based on sizeof t_uniqueId * * add copyright (cherry picked from commit 9235579)
1 parent 196ace3 commit 259d417

6 files changed

Lines changed: 239 additions & 1 deletion

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ file(GLOB SOURCES
100100
"src/util/*.c"
101101
"src/trie/*.c"
102102
"src/info/*.c"
103+
"src/obfuscation/*.c"
103104

104105
"deps/cndict/cndict_data.c"
105106
"deps/libnu/*.c"

src/obfuscation/obfuscation_api.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#include "obfuscation_api.h"
2+
#include "rmalloc.h"
3+
#include "query_node.h"
4+
5+
#include <string.h>
6+
7+
void Obfuscate_Index(t_uniqueId indexId, char* buffer) {
8+
sprintf(buffer, "Index@%zu", indexId);
9+
}
10+
11+
void Obfuscate_Field(t_uniqueId fieldId, char* buffer) {
12+
sprintf(buffer, "Field@%zu", fieldId);
13+
}
14+
15+
void Obfuscate_FieldPath(t_uniqueId fieldId, char* buffer) {
16+
sprintf(buffer, "FieldPath@%zu", fieldId);
17+
}
18+
19+
void Obfuscate_Document(t_uniqueId docId, char* buffer) {
20+
sprintf(buffer, "Document@%zu", docId);
21+
}
22+
23+
char *Obfuscate_Text(const char* text) {
24+
return "Text";
25+
}
26+
27+
char *Obfuscate_Number(size_t number) {
28+
return "Number";
29+
}
30+
31+
char *Obfuscate_Vector(const char* vector, size_t dim) {
32+
return "Vector";
33+
}
34+
35+
char *Obfuscate_Tag(const char* tag) {
36+
return "Tag";
37+
}
38+
39+
char *Obfuscate_Geo(uint16_t longitude, uint16_t latitude) {
40+
return "Geo";
41+
}
42+
43+
char *Obfuscate_GeoShape() {
44+
return "GeoShape";
45+
}
46+
47+
char *Obfuscate_QueryNode(struct RSQueryNode *node) {
48+
switch (node->type) {
49+
case QN_PHRASE:
50+
return "Phrase";
51+
case QN_UNION:
52+
return "Union";
53+
case QN_TOKEN:
54+
return "Token";
55+
case QN_NUMERIC:
56+
return "Numeric";
57+
case QN_NOT:
58+
return "Not";
59+
case QN_OPTIONAL:
60+
return "Optional";
61+
case QN_GEO:
62+
return "Geo";
63+
case QN_GEOMETRY:
64+
return "Geometry";
65+
case QN_PREFIX:
66+
return "Prefix";
67+
case QN_IDS:
68+
return "Ids";
69+
case QN_WILDCARD:
70+
return "Wildcard";
71+
case QN_TAG:
72+
return "Tag";
73+
case QN_FUZZY:
74+
return "Fuzzy";
75+
case QN_LEXRANGE:
76+
return "LexRange";
77+
case QN_VECTOR:
78+
return "Vector";
79+
case QN_NULL:
80+
return "Null";
81+
case QN_MISSING:
82+
return "Missing";
83+
case QN_WILDCARD_QUERY:
84+
return "WildcardQuery";
85+
}
86+
}

src/obfuscation/obfuscation_api.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright Redis Ltd. 2016 - present
3+
* Licensed under your choice of the Redis Source Available License 2.0 (RSALv2) or
4+
* the Server Side Public License v1 (SSPLv1).
5+
*/
6+
7+
#ifndef OBFUSCATION_API_H
8+
#define OBFUSCATION_API_H
9+
#include "redisearch.h"
10+
11+
#define MAX_OBFUSCATED_INDEX_NAME 6/*strlen("Index@")*/ + MAX_UNIQUE_ID_TEXT_LENGTH_UPPER_BOUND + 1/*null terminator*/
12+
#define MAX_OBFUSCATED_FIELD_NAME 6/*strlen("Field@")*/ + MAX_UNIQUE_ID_TEXT_LENGTH_UPPER_BOUND + 1/*null terminator*/
13+
#define MAX_OBFUSCATED_PATH_NAME MAX_OBFUSCATED_FIELD_NAME
14+
#define MAX_OBFUSCATED_DOCUMENT_NAME 9/*strlen("Document@")*/ + MAX_UNIQUE_ID_TEXT_LENGTH_UPPER_BOUND + 1/*null terminator*/
15+
16+
void Obfuscate_Index(t_uniqueId indexId, char* buffer);
17+
void Obfuscate_Field(t_uniqueId fieldId, char* buffer);
18+
void Obfuscate_FieldPath(t_uniqueId fieldId, char* buffer);
19+
void Obfuscate_Document(t_uniqueId docId, char* buffer);
20+
21+
char *Obfuscate_Text(const char* text);
22+
char *Obfuscate_Number(size_t number);
23+
char *Obfuscate_Vector(const char* vector, size_t dim);
24+
char *Obfuscate_Tag(const char* tag);
25+
char *Obfuscate_Geo(uint16_t longitude, uint16_t latitude);
26+
char *Obfuscate_GeoShape();
27+
28+
struct RSQueryNode;
29+
char *Obfuscate_QueryNode(struct RSQueryNode *node);
30+
31+
#endif //OBFUSCATION_API_H

src/query_node.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,10 @@ typedef enum {
6868
QN_NULL,
6969

7070
/* Missing query */
71-
QN_MISSING
71+
QN_MISSING,
72+
73+
/* Max value, should be last */
74+
QN_MAX
7275
} QueryNodeType;
7376

7477
/* A phrase node represents a list of nodes with intersection between them, or a phrase in the case

src/redisearch.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ typedef uint64_t t_offset;
2020
// to produce a field mask we calculate 2^fieldId
2121
typedef uint16_t t_fieldId;
2222

23+
typedef uint64_t t_uniqueId;
24+
#define SIGN_CHAR_LENGTH 0 // t_uniqueId is unsigned
25+
#define LOG_10_ON_256_UPPER_BOUND 3 // 2^8 = 10 ^ y, 2^16 = 2^8 * 2^8 = 10^y * 10^y = 10^2y -> y == 2.40824 -> upper bound for y is 3
26+
#define MAX_UNIQUE_ID_TEXT_LENGTH_UPPER_BOUND ((sizeof(t_uniqueId) * LOG_10_ON_256_UPPER_BOUND) + SIGN_CHAR_LENGTH)
27+
2328
#define DOCID_MAX UINT64_MAX
2429

2530
#if (defined(__x86_64__) || defined(__aarch64__) || defined(__arm64__)) && !defined(RS_NO_U128)

tests/ctests/test_obfuscation.c

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#include "test_util.h"
2+
#include "src/query_node.h"
3+
#include "src/obfuscation/obfuscation_api.h"
4+
5+
#include <stdlib.h>
6+
#include <string.h>
7+
8+
struct RSQueryNode;
9+
char *Obfuscate_QueryNode(struct RSQueryNode *node);
10+
11+
enum {
12+
IndexSize = MAX_OBFUSCATED_INDEX_NAME,
13+
FieldSize = MAX_OBFUSCATED_FIELD_NAME,
14+
FieldPathSize = MAX_OBFUSCATED_PATH_NAME,
15+
DocumentSize = MAX_OBFUSCATED_DOCUMENT_NAME
16+
};
17+
18+
#define DEFINE_OBJECT_OBFUSCATION_TESTS(name) \
19+
int testSimple ## name ## Obfuscation() { \
20+
char obfuscated[name##Size]; \
21+
Obfuscate_##name(1, obfuscated); \
22+
return strcmp(obfuscated, #name"@1"); \
23+
} \
24+
int testMax ## name ## Obfuscation() { \
25+
char obfuscated[name##Size]; \
26+
Obfuscate_##name(UINT64_MAX, obfuscated); \
27+
return strcmp(obfuscated, #name"@18446744073709551615"); \
28+
}
29+
30+
DEFINE_OBJECT_OBFUSCATION_TESTS(Index)
31+
DEFINE_OBJECT_OBFUSCATION_TESTS(Field)
32+
DEFINE_OBJECT_OBFUSCATION_TESTS(FieldPath)
33+
DEFINE_OBJECT_OBFUSCATION_TESTS(Document)
34+
35+
int testTextObfuscation() {
36+
char *obfuscated = Obfuscate_Text("hello");
37+
return strcmp(obfuscated, "Text");
38+
}
39+
40+
int testNumberObfuscation() {
41+
char *obfuscated = Obfuscate_Number(rand());
42+
return strcmp(obfuscated, "Number");
43+
}
44+
45+
int testVectorObfuscation() {
46+
char *obfuscated = Obfuscate_Vector("hello", 5);
47+
return strcmp(obfuscated, "Vector");
48+
}
49+
50+
int testTagObfuscation() {
51+
char *obfuscated = Obfuscate_Tag("hello");
52+
return strcmp(obfuscated, "Tag");
53+
}
54+
55+
int testGeoObfuscation() {
56+
char *obfuscated = Obfuscate_Geo(1, 2);
57+
return strcmp(obfuscated, "Geo");
58+
}
59+
60+
int testGeoShapeObfuscation() {
61+
char *obfuscated = Obfuscate_GeoShape();
62+
return strcmp(obfuscated, "GeoShape");
63+
}
64+
65+
int testQueryNodeObfuscation() {
66+
const char* expected[] = {
67+
"Phrase",
68+
"Union",
69+
"Token",
70+
"Numeric",
71+
"Not",
72+
"Optional",
73+
"Geo",
74+
"Geometry",
75+
"Prefix",
76+
"Ids",
77+
"Wildcard",
78+
"Tag",
79+
"Fuzzy",
80+
"LexRange",
81+
"Vector",
82+
"WildcardQuery",
83+
"Null",
84+
"Missing"
85+
};
86+
for (int i = QN_PHRASE; i < QN_MAX; ++i) {
87+
struct RSQueryNode node = {
88+
.type = i,
89+
};
90+
char *obfuscated = Obfuscate_QueryNode(&node);
91+
ASSERT(strcmp(obfuscated, expected[i - 1]) == 0);
92+
}
93+
return 0;
94+
}
95+
96+
TEST_MAIN({
97+
TESTFUNC(testSimpleIndexObfuscation);
98+
TESTFUNC(testMaxIndexObfuscation);
99+
TESTFUNC(testSimpleFieldObfuscation);
100+
TESTFUNC(testMaxFieldObfuscation);
101+
TESTFUNC(testSimpleFieldPathObfuscation);
102+
TESTFUNC(testMaxFieldPathObfuscation);
103+
TESTFUNC(testSimpleDocumentObfuscation);
104+
TESTFUNC(testMaxDocumentObfuscation);
105+
TESTFUNC(testTextObfuscation);
106+
TESTFUNC(testNumberObfuscation);
107+
TESTFUNC(testVectorObfuscation);
108+
TESTFUNC(testTagObfuscation);
109+
TESTFUNC(testGeoObfuscation);
110+
TESTFUNC(testGeoShapeObfuscation);
111+
TESTFUNC(testQueryNodeObfuscation);
112+
})

0 commit comments

Comments
 (0)