Fix the NPE bug when passing null args to SphU.entry() and paramIdx is negative (#642)

- Also rearrangement of some code

Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
Eric Zhao 2019-04-04 09:40:23 +08:00 committed by GitHub
parent fc550343c7
commit 29f22e370b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 34 deletions

View File

@ -38,8 +38,7 @@ import com.alibaba.csp.sentinel.util.StringUtil;
*/ */
public class ParamFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> { public class ParamFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
private static final Map<ResourceWrapper, ParameterMetric> metricsMap private static final Map<ResourceWrapper, ParameterMetric> metricsMap = new ConcurrentHashMap<>();
= new ConcurrentHashMap<ResourceWrapper, ParameterMetric>();
/** /**
* Lock for a specific resource. * Lock for a specific resource.
@ -63,24 +62,29 @@ public class ParamFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
fireExit(context, resourceWrapper, count, args); fireExit(context, resourceWrapper, count, args);
} }
void checkFlow(ResourceWrapper resourceWrapper, int count, Object... args) void applyRealParamIdx(/*@NonNull*/ ParamFlowRule rule, int length) {
throws BlockException {
if (ParamFlowRuleManager.hasRules(resourceWrapper.getName())) {
List<ParamFlowRule> rules = ParamFlowRuleManager.getRulesOfResource(resourceWrapper.getName());
if (rules == null) {
return;
}
for (ParamFlowRule rule : rules) {
int paramIdx = rule.getParamIdx(); int paramIdx = rule.getParamIdx();
if (paramIdx < 0) { if (paramIdx < 0) {
if (-paramIdx <= args.length) { if (-paramIdx <= length) {
rule.setParamIdx(args.length + paramIdx); rule.setParamIdx(length + paramIdx);
} else { } else {
// illegal index, give it a illegal positive value, latter rule check will pass // illegal index, give it a illegal positive value, latter rule check will pass
rule.setParamIdx(-paramIdx); rule.setParamIdx(-paramIdx);
} }
} }
}
void checkFlow(ResourceWrapper resourceWrapper, int count, Object... args) throws BlockException {
if (args == null) {
return;
}
if (!ParamFlowRuleManager.hasRules(resourceWrapper.getName())) {
return;
}
List<ParamFlowRule> rules = ParamFlowRuleManager.getRulesOfResource(resourceWrapper.getName());
for (ParamFlowRule rule : rules) {
applyRealParamIdx(rule, args.length);
// Initialize the parameter metrics. // Initialize the parameter metrics.
initHotParamMetricsFor(resourceWrapper, rule.getParamIdx()); initHotParamMetricsFor(resourceWrapper, rule.getParamIdx());
@ -99,7 +103,6 @@ public class ParamFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
} }
} }
} }
}
private void addBlockCount(ResourceWrapper resourceWrapper, int count, Object... args) { private void addBlockCount(ResourceWrapper resourceWrapper, int count, Object... args) {
ParameterMetric parameterMetric = ParamFlowSlot.getParamMetric(resourceWrapper); ParameterMetric parameterMetric = ParamFlowSlot.getParamMetric(resourceWrapper);
@ -161,7 +164,7 @@ public class ParamFlowSlot extends AbstractLinkedProcessorSlot<DefaultNode> {
RecordLog.info("[ParamFlowSlot] Clearing parameter metric for: " + resourceName); RecordLog.info("[ParamFlowSlot] Clearing parameter metric for: " + resourceName);
} }
public static Map<ResourceWrapper, ParameterMetric> getMetricsMap() { static Map<ResourceWrapper, ParameterMetric> getMetricsMap() {
return metricsMap; return metricsMap;
} }
} }

View File

@ -50,6 +50,12 @@ public class ParamFlowSlotTest {
paramFlowSlot.entry(null, resourceWrapper, null, 1, false, "abc", "def", "ghi"); paramFlowSlot.entry(null, resourceWrapper, null, 1, false, "abc", "def", "ghi");
assertEquals(2, rule.getParamIdx().longValue()); assertEquals(2, rule.getParamIdx().longValue());
rule.setParamIdx(-1);
ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
paramFlowSlot.entry(null, resourceWrapper, null, 1, false, null);
// Null args will not trigger conversion.
assertEquals(-1, rule.getParamIdx().intValue());
rule.setParamIdx(-100); rule.setParamIdx(-100);
ParamFlowRuleManager.loadRules(Collections.singletonList(rule)); ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
paramFlowSlot.entry(null, resourceWrapper, null, 1, false, "abc", "def", "ghi"); paramFlowSlot.entry(null, resourceWrapper, null, 1, false, "abc", "def", "ghi");