config service: avoid raising a json exception on non json input
The config service accepts in strings instead of json strings, however this causes the normal control flow to throw a json parsing exception. Since this happens so frequently it is using a measurable amount of CPU time, so avoid it in the common case by testing if the string is json first
This commit is contained in:
@@ -47,6 +47,7 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.http.api.config.ConfigEntry;
|
||||
@@ -60,6 +61,7 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class ConfigService
|
||||
{
|
||||
private static final Pattern MAYBE_JSON = Pattern.compile("^[\\-0-9{\\[\"]|true|false");
|
||||
private static final int MAX_DEPTH = 8;
|
||||
private static final int MAX_VALUE_LENGTH = 262144;
|
||||
|
||||
@@ -184,12 +186,25 @@ public class ConfigService
|
||||
return unset(dbKey);
|
||||
}
|
||||
|
||||
if (!validateJson(value))
|
||||
Object jsonValue;
|
||||
if (!isMaybeJson(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!validateStr(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Object jsonValue = parseJsonString(value);
|
||||
jsonValue = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!validateJson(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
jsonValue = parseJsonString(value);
|
||||
}
|
||||
return set(dbKey, jsonValue);
|
||||
}
|
||||
|
||||
@@ -268,6 +283,17 @@ public class ConfigService
|
||||
return jsonValue;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean isMaybeJson(String value)
|
||||
{
|
||||
return MAYBE_JSON.matcher(value).find();
|
||||
}
|
||||
|
||||
private static boolean validateStr(String value)
|
||||
{
|
||||
return value.length() < MAX_VALUE_LENGTH;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean validateJson(String value)
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@ package net.runelite.http.service.config;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import org.junit.Test;
|
||||
|
||||
@@ -53,4 +54,19 @@ public class ConfigServiceTest
|
||||
assertTrue(ConfigService.validateJson("{\"key\": \"value\"}"));
|
||||
assertTrue(ConfigService.validateJson("\n"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMaybeJson()
|
||||
{
|
||||
assertFalse(ConfigService.isMaybeJson("string"));
|
||||
assertFalse(ConfigService.isMaybeJson("string with spaces"));
|
||||
|
||||
assertTrue(ConfigService.isMaybeJson("true"));
|
||||
assertTrue(ConfigService.isMaybeJson("false"));
|
||||
assertTrue(ConfigService.isMaybeJson("1"));
|
||||
assertTrue(ConfigService.isMaybeJson("1.2"));
|
||||
assertTrue(ConfigService.isMaybeJson("\"quote\""));
|
||||
assertTrue(ConfigService.isMaybeJson("{\"key\": \"value\"}"));
|
||||
assertTrue(ConfigService.isMaybeJson("[42]"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user