From 857759f8aa0675ffd90c881cd95213d15b851a3e Mon Sep 17 00:00:00 2001 From: Jason Joo Date: Thu, 2 Apr 2020 23:25:37 +0800 Subject: [PATCH 1/3] Force api to fail if an incompitible fastjson found --- .../csp/sentinel/util/VersionUtil.java | 55 +++++++++++++++++++ .../csp/sentinel/util/VersionUtilTest.java | 17 ++++++ .../handler/ModifyRulesCommandHandler.java | 12 +++- 3 files changed, 83 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 8f9d82cd15..18fc163e83 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,59 @@ public static String getVersion(String defaultVersion) { } private VersionUtil() {} + + + /** + * 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; + } + try { + versions[index] = new Integer(segment); + if (versions[index] < 0 || versions[index] > 255) { + // Out of range [0, 255] + return 0; + } + } catch (NumberFormatException e) { + 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 bdccc1c4c3..c00f3d12a3 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,19 @@ public void testGetDefaultVersion() { // 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(0, VersionUtil.fromVersionString("1.2.")); + assertEquals(0x01000000, VersionUtil.fromVersionString("1")); + assertEquals(0x01020000, VersionUtil.fromVersionString("1.2")); + assertEquals(0, VersionUtil.fromVersionString("test")); + assertEquals(0, VersionUtil.fromVersionString("1.2.3-")); + assertEquals(0, VersionUtil.fromVersionString("1.2.3b")); + } } 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 e17ed447ca..993bc8f0be 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.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.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 @@ */ @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 = 0x01021200; @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 CommandResponse handle(CommandRequest request) { } } - RecordLog.info(String.format("Receiving rule change (type: %s): %s", type, data)); + RecordLog.info("Receiving rule change (type: {}): {}", type, data); String result = "success"; From 00a4178ad2aad0dcdad71f72029036895f034992 Mon Sep 17 00:00:00 2001 From: Jason Joo Date: Fri, 3 Apr 2020 01:01:06 +0800 Subject: [PATCH 2/3] compatible for custom version number --- .../csp/sentinel/util/VersionUtil.java | 24 +++++++++++++------ .../csp/sentinel/util/VersionUtilTest.java | 8 ++++--- 2 files changed, 22 insertions(+), 10 deletions(-) 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 18fc163e83..21e0943c77 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 @@ -37,6 +37,20 @@ public static String getVersion(String defaultVersion) { 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
@@ -74,13 +88,9 @@ public static int fromVersionString(String verStr) { // Illegal format return 0; } - try { - versions[index] = new Integer(segment); - if (versions[index] < 0 || versions[index] > 255) { - // Out of range [0, 255] - return 0; - } - } catch (NumberFormatException e) { + versions[index] = parseInt(segment); + if (versions[index] < 0 || versions[index] > 255) { + // Out of range [0, 255] return 0; } cur = pos + 1; 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 c00f3d12a3..1b620defc7 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 @@ -37,11 +37,13 @@ public void testFromVersionString() { 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(0, VersionUtil.fromVersionString("1.2.")); + assertEquals(0x01020000, VersionUtil.fromVersionString("1.2.")); assertEquals(0x01000000, VersionUtil.fromVersionString("1")); assertEquals(0x01020000, VersionUtil.fromVersionString("1.2")); assertEquals(0, VersionUtil.fromVersionString("test")); - assertEquals(0, VersionUtil.fromVersionString("1.2.3-")); - assertEquals(0, VersionUtil.fromVersionString("1.2.3b")); + 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")); } } From 1efacb2c566a79c446c64be97e41e7683c73719d Mon Sep 17 00:00:00 2001 From: Jason Joo Date: Fri, 3 Apr 2020 01:06:25 +0800 Subject: [PATCH 3/3] fix the minimal version --- .../csp/sentinel/command/handler/ModifyRulesCommandHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 993bc8f0be..b600844e14 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 @@ -45,7 +45,7 @@ */ @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 = 0x01021200; + private static final int FASTJSON_MINIMAL_VER = 0x01020C00; @Override public CommandResponse handle(CommandRequest request) {