Skip to content

Commit 5a07f4a

Browse files
not a perfect solution. right now only serves as a soft cap at 128 and hard cap at 256.
1 parent 5972c8a commit 5a07f4a

File tree

4 files changed

+20
-18
lines changed

4 files changed

+20
-18
lines changed

src/commands.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -625,24 +625,14 @@ pub fn json_set<M: Manager>(manager: M, ctx: &Context, args: Vec<RedisString>) -
625625
let mut res = false;
626626
if update_info.len() == 1 {
627627
res = match update_info.pop().unwrap() {
628-
UpdateInfo::SUI(sui) => {
629-
if sui.path.len() < 128 {
630-
redis_key.set_value(sui.path, val)?
631-
} else {
632-
return Err(RedisError::Str("recursion limit exceeded"));
633-
}
634-
}
628+
UpdateInfo::SUI(sui) => redis_key.set_value(sui.path, val)?,
635629
UpdateInfo::AUI(aui) => redis_key.dict_add(aui.path, &aui.key, val)?,
636630
}
637631
} else {
638632
for ui in update_info {
639633
res = match ui {
640634
UpdateInfo::SUI(sui) => {
641-
if sui.path.len() < 128 {
642-
redis_key.set_value(sui.path, val.clone())?
643-
} else {
644-
return Err(RedisError::Str("recursion limit exceeded"));
645-
}
635+
redis_key.set_value(sui.path, val.clone())?
646636
}
647637
UpdateInfo::AUI(aui) => {
648638
redis_key.dict_add(aui.path, &aui.key, val.clone())?

src/ivalue_manager.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,10 @@ impl<'a> WriteHolder<IValue, IValue> for IValueKeyHolderWrite<'a> {
322322

323323
fn set_value(&mut self, path: Vec<String>, mut v: IValue) -> Result<bool, RedisError> {
324324
let mut updated = false;
325-
if path.is_empty() {
325+
326+
if path.len() > 127 {
327+
return Err(RedisError::Str("recursion limit exceeded"));
328+
} else if path.is_empty() {
326329
// update the root
327330
self.set_root(Some(v))?;
328331
updated = true;
@@ -342,7 +345,10 @@ impl<'a> WriteHolder<IValue, IValue> for IValueKeyHolderWrite<'a> {
342345
mut v: IValue,
343346
) -> Result<bool, RedisError> {
344347
let mut updated = false;
345-
if path.is_empty() {
348+
349+
if path.len() > 127 {
350+
return Err(RedisError::Str("recursion limit exceeded"));
351+
} else if path.is_empty() {
346352
// update the root
347353
let root = self.get_value().unwrap().unwrap();
348354
if let Some(o) = root.as_object_mut() {

src/manager.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,10 @@ impl<'a> WriteHolder<Value, Value> for KeyHolderWrite<'a> {
304304

305305
fn set_value(&mut self, path: Vec<String>, mut v: Value) -> Result<bool, RedisError> {
306306
let mut updated = false;
307-
if path.is_empty() {
307+
308+
if path.len() > 127 {
309+
return Err(RedisError::Str("recursion limit exceeded"));
310+
} else if path.is_empty() {
308311
// update the root
309312
self.set_root(Some(v))?;
310313
updated = true;
@@ -319,7 +322,9 @@ impl<'a> WriteHolder<Value, Value> for KeyHolderWrite<'a> {
319322

320323
fn dict_add(&mut self, path: Vec<String>, key: &str, mut v: Value) -> Result<bool, RedisError> {
321324
let mut updated = false;
322-
if path.is_empty() {
325+
if path.len() > 127 {
326+
return Err(RedisError::Str("recursion limit exceeded"));
327+
} else if path.is_empty() {
323328
// update the root
324329
let root = self.get_value().unwrap().unwrap();
325330
let val = if let Value::Object(mut o) = root.take() {

tests/pytest/test.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -1131,19 +1131,20 @@ def testNesting(env):
11311131
""" Test JSONPath Object nesting depth """
11321132
r = env
11331133

1134-
# Max nesting level for a single JSON value
1134+
# Max nesting level for a single JSON value is 128
11351135
depth = 128
11361136
doc = nest_object(depth, 5, "__leaf", 42)
11371137
r.assertOk(r.execute_command('JSON.SET', 'test', '$', doc))
11381138
res = r.execute_command('JSON.GET', 'test', '$..__leaf')
11391139
r.assertEqual(res, '[42]')
11401140

1141-
# Max nesting level of nested objects cannot exceed 128
1141+
# Max nesting level (can exceeded the single value max nesting level)
11421142
doc = nest_object(depth, 5, "__deep_leaf", 420)
11431143
r.execute_command('JSON.SET', 'test', '$..__leaf', doc)
11441144
res = r.execute_command('JSON.GET', 'test', '$..__deep_leaf')
11451145
r.assertEqual(res, '[420]')
11461146

1147+
# But the overall max nesting level, 256, cannot be exceeded
11471148
doc = nest_object(depth, 5, "__helms_deep_leaf", 42000)
11481149
r.expect('JSON.SET', 'test', '$..__deep_leaf', doc).raiseError().contains("recursion limit exceeded")
11491150

0 commit comments

Comments
 (0)