From 49e60a3e51619937b22e41566272d2b35064fb15 Mon Sep 17 00:00:00 2001 From: Jason Joo Date: Fri, 3 Apr 2020 15:32:42 +0800 Subject: [PATCH] Force modifyRule command handler to fail if an incompatible old fastjson found (#1377) * Note that this is only a temporary solution. --- .../csp/sentinel/util/VersionUtil.java | 65 +++++++++++++++++++ .../csp/sentinel/util/VersionUtilTest.java | 19 ++++++ .../handler/ModifyRulesCommandHandler.java | 12 +++- 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/VersionUtil.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/VersionUtil.java index 8f9d82cd..21e0943c 100644 --- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/VersionUtil.java +++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/util/VersionUtil.java @@ -36,4 +36,69 @@ public final class VersionUtil { } private VersionUtil() {} + + private static int parseInt(String str) { + if (str == null || str.length() < 1) { + return 0; + } + int num = 0; + for (int i = 0; i < str.length(); i ++) { + char ch = str.charAt(i); + if (ch < '0' || ch > '9') { + break; + } + num = num * 10 + (ch - '0'); + } + return num; + } + + /** + * Convert version in string like x.y.z or x.y.z.b into number
+ * Each segment has one byte space(unsigned)
+ * eg.
+ *
+     * 1.2.3.4 => 01 02 03 04
+     * 1.2.3   => 01 02 03 00
+     * 1.2     => 01 02 00 00
+     * 1       => 01 00 00 00
+     * 
+ * + * @return + */ + public static int fromVersionString(String verStr) { + if (verStr == null || verStr.length() < 1) { + return 0; + } + int[] versions = new int[] {0, 0, 0, 0}; + int index = 0; + String segment; + int cur = 0; + int pos; + do { + if (index >= versions.length) { + // More dots than "x.y.z.b" contains + return 0; + } + pos = verStr.indexOf('.', cur); + if (pos == -1) { + segment = verStr.substring(cur); + } else if (cur < pos) { + segment = verStr.substring(cur, pos); + } else { + // Illegal format + return 0; + } + versions[index] = parseInt(segment); + if (versions[index] < 0 || versions[index] > 255) { + // Out of range [0, 255] + return 0; + } + cur = pos + 1; + index ++; + } while (pos > 0); + return ((versions[0] & 0xff) << 24) + | ((versions[1] & 0xff) << 16) + | ((versions[2] & 0xff) << 8) + | (versions[3] & 0xff); + } } diff --git a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/VersionUtilTest.java b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/VersionUtilTest.java index bdccc1c4..1b620def 100644 --- a/sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/VersionUtilTest.java +++ b/sentinel-core/src/test/java/com/alibaba/csp/sentinel/util/VersionUtilTest.java @@ -15,6 +15,8 @@ */ package com.alibaba.csp.sentinel.util; +import static org.junit.Assert.*; + import org.junit.Assert; import org.junit.Test; @@ -27,4 +29,21 @@ public class VersionUtilTest { // Manifest cannot be load before package. Assert.assertEquals(defaultVersion, version); } + + @Test + public void testFromVersionString() { + assertEquals(0x01020300, VersionUtil.fromVersionString("1.2.3")); + assertEquals(0x01020304, VersionUtil.fromVersionString("1.2.3.4")); + assertEquals(0x0102ff04, VersionUtil.fromVersionString("1.2.255.4")); + assertEquals(0xffffffff, VersionUtil.fromVersionString("255.255.255.255")); + assertEquals(0, VersionUtil.fromVersionString("1.255.256.0")); + assertEquals(0x01020000, VersionUtil.fromVersionString("1.2.")); + assertEquals(0x01000000, VersionUtil.fromVersionString("1")); + assertEquals(0x01020000, VersionUtil.fromVersionString("1.2")); + assertEquals(0, VersionUtil.fromVersionString("test")); + assertEquals(0x01020300, VersionUtil.fromVersionString("1.2.3-")); + assertEquals(0x01020300, VersionUtil.fromVersionString("1.2.3b")); + assertEquals(0x01023c00, VersionUtil.fromVersionString("1.2.60.sec9")); + assertEquals(0x01023c00, VersionUtil.fromVersionString("1.2.60-internal")); + } } diff --git a/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyRulesCommandHandler.java b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyRulesCommandHandler.java index e17ed447..b600844e 100755 --- a/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyRulesCommandHandler.java +++ b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyRulesCommandHandler.java @@ -25,6 +25,7 @@ import com.alibaba.csp.sentinel.command.annotation.CommandMapping; import com.alibaba.csp.sentinel.datasource.WritableDataSource; import com.alibaba.csp.sentinel.log.RecordLog; import com.alibaba.csp.sentinel.util.StringUtil; +import com.alibaba.csp.sentinel.util.VersionUtil; import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule; import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager; import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule; @@ -33,6 +34,7 @@ import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.csp.sentinel.slots.system.SystemRuleManager; import com.alibaba.csp.sentinel.slots.system.SystemRule; +import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import static com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry.*; @@ -43,9 +45,17 @@ import static com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry */ @CommandMapping(name = "setRules", desc = "modify the rules, accept param: type={ruleType}&data={ruleJson}") public class ModifyRulesCommandHandler implements CommandHandler { + private static final int FASTJSON_MINIMAL_VER = 0x01020C00; @Override public CommandResponse handle(CommandRequest request) { + // XXX from 1.7.2, force to fail when fastjson is older than 1.2.12 + // We may need a better solution on this. + if (VersionUtil.fromVersionString(JSON.VERSION) < FASTJSON_MINIMAL_VER) { + // fastjson too old + return CommandResponse.ofFailure(new RuntimeException("The \"fastjson-" + JSON.VERSION + + "\" introduced in application is too old, you need fastjson-1.2.12 at least.")); + } String type = request.getParam("type"); // rule data in get parameter String data = request.getParam("data"); @@ -58,7 +68,7 @@ public class ModifyRulesCommandHandler implements CommandHandler { } } - RecordLog.info(String.format("Receiving rule change (type: %s): %s", type, data)); + RecordLog.info("Receiving rule change (type: {}): {}", type, data); String result = "success";