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:
Adam
2021-12-07 12:49:12 -05:00
parent a05655f412
commit 9cd7060035
2 changed files with 46 additions and 4 deletions

View File

@@ -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)
{

View File

@@ -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]"));
}
}