Fix `DurationUtils.convertToTimeBucket` missed verify date format (#9586)
diff --git a/docs/en/changes/changes.md b/docs/en/changes/changes.md
index 49d72f6..af1e9e2 100644
--- a/docs/en/changes/changes.md
+++ b/docs/en/changes/changes.md
@@ -8,6 +8,7 @@
* Add component ID(133) for impala JDBC Java agent plugin and component ID(134) for impala server
* Use prepareStatement in H2SQLExecutor#getByIDs.(No function change).
* Bump up snakeyaml to 1.31 for fixing CVE-2022-25857
+* Fix `DurationUtils.convertToTimeBucket` missed verify date format.
#### UI
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/DurationUtils.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/DurationUtils.java
index db14658..d74c98e 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/DurationUtils.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/DurationUtils.java
@@ -46,48 +46,41 @@
* Convert date in `yyyy-MM-dd HHmmss` style to `yyyyMMddHHmmss` no matter the precision. Such as, in day precision,
* this covert `yyyy-MM-dd` style to `yyyyMMdd`.
*/
- public long convertToTimeBucket(String dateStr) {
+ public long convertToTimeBucket(Step step, String dateStr) {
+ verifyDateTimeString(step, dateStr);
dateStr = dateStr.replaceAll(Const.LINE, Const.EMPTY_STRING);
dateStr = dateStr.replaceAll(Const.SPACE, Const.EMPTY_STRING);
return Long.parseLong(dateStr);
}
public long startTimeDurationToSecondTimeBucket(Step step, String dateStr) {
- long secondTimeBucket = 0;
+ long secondTimeBucket = convertToTimeBucket(step, dateStr);
switch (step) {
case DAY:
- secondTimeBucket = convertToTimeBucket(dateStr) * 100 * 100 * 100;
- break;
+ return secondTimeBucket * 100 * 100 * 100;
case HOUR:
- secondTimeBucket = convertToTimeBucket(dateStr) * 100 * 100;
- break;
+ return secondTimeBucket * 100 * 100;
case MINUTE:
- secondTimeBucket = convertToTimeBucket(dateStr) * 100;
- break;
+ return secondTimeBucket * 100;
case SECOND:
- secondTimeBucket = convertToTimeBucket(dateStr);
- break;
+ return secondTimeBucket;
}
- return secondTimeBucket;
+ throw new UnexpectedException("Unsupported step " + step.name());
}
public long endTimeDurationToSecondTimeBucket(Step step, String dateStr) {
- long secondTimeBucket = 0;
+ long secondTimeBucket = convertToTimeBucket(step, dateStr);
switch (step) {
case DAY:
- secondTimeBucket = ((convertToTimeBucket(dateStr) * 100 + 99) * 100 + 99) * 100 + 99;
- break;
+ return ((secondTimeBucket * 100 + 23) * 100 + 59) * 100 + 59;
case HOUR:
- secondTimeBucket = (convertToTimeBucket(dateStr) * 100 + 99) * 100 + 99;
- break;
+ return (secondTimeBucket * 100 + 59) * 100 + 59;
case MINUTE:
- secondTimeBucket = convertToTimeBucket(dateStr) * 100 + 99;
- break;
+ return secondTimeBucket * 100 + 59;
case SECOND:
- secondTimeBucket = convertToTimeBucket(dateStr);
- break;
+ return secondTimeBucket;
}
- return secondTimeBucket;
+ throw new UnexpectedException("Unsupported step " + step.name());
}
public List<PointOfTime> getDurationPoints(Step step, long startTimeBucket, long endTimeBucket) {
@@ -163,7 +156,7 @@
throw new UnexpectedException("Unsupported step " + step.name());
}
- private DateTime parseToDateTime(Step step, long time) {
+ public DateTime parseToDateTime(Step step, long time) {
switch (step) {
case DAY:
return YYYYMMDD.parseDateTime(String.valueOf(time));
@@ -176,4 +169,23 @@
}
throw new UnexpectedException("Unexpected downsampling: " + step.name());
}
+
+ public void verifyDateTimeString(Step step, String dateStr) {
+ switch (step) {
+ case DAY:
+ YYYY_MM_DD.parseDateTime(dateStr);
+ return;
+ case HOUR:
+ YYYY_MM_DD_HH.parseDateTime(dateStr);
+ return;
+ case MINUTE:
+ YYYY_MM_DD_HHMM.parseDateTime(dateStr);
+ return;
+ case SECOND:
+ YYYY_MM_DD_HHMMSS.parseDateTime(dateStr);
+ return;
+ }
+ throw new UnexpectedException("Unsupported step " + step.name());
+ }
+
}
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Duration.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Duration.java
index 600b4db..a9d16ba 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Duration.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/query/input/Duration.java
@@ -33,17 +33,17 @@
private Step step;
/**
- * See {@link DurationUtils#convertToTimeBucket(String)}
+ * See {@link DurationUtils#convertToTimeBucket(Step, String)}
*/
public long getStartTimeBucket() {
- return DurationUtils.INSTANCE.convertToTimeBucket(start);
+ return DurationUtils.INSTANCE.convertToTimeBucket(step, start);
}
/**
- * See {@link DurationUtils#convertToTimeBucket(String)}
+ * See {@link DurationUtils#convertToTimeBucket(Step, String)}
*/
public long getEndTimeBucket() {
- return DurationUtils.INSTANCE.convertToTimeBucket(end);
+ return DurationUtils.INSTANCE.convertToTimeBucket(step, end);
}
public long getStartTimestamp() {
diff --git a/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/query/DurationTest.java b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/query/DurationTest.java
new file mode 100644
index 0000000..a51cea7
--- /dev/null
+++ b/oap-server/server-core/src/test/java/org/apache/skywalking/oap/server/core/query/DurationTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.oap.server.core.query;
+
+import org.apache.skywalking.oap.server.core.query.enumeration.Step;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DurationTest {
+
+ @Test
+ public void testConvertToTimeBucket() {
+ Assert.assertEquals(20220908L, DurationUtils.INSTANCE.convertToTimeBucket(Step.DAY, "2022-09-08"));
+ Assert.assertEquals(2022090810L, DurationUtils.INSTANCE.convertToTimeBucket(Step.HOUR, "2022-09-08 10"));
+ Assert.assertEquals(202209081010L, DurationUtils.INSTANCE.convertToTimeBucket(Step.MINUTE, "2022-09-08 1010"));
+ Assert.assertEquals(
+ 20220908101010L, DurationUtils.INSTANCE.convertToTimeBucket(Step.SECOND, "2022-09-08 101010"));
+ try {
+ DurationUtils.INSTANCE.convertToTimeBucket(Step.DAY, "2022-09-08 10");
+ Assert.fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testStartTimeDurationToSecondTimeBucket() {
+ Assert.assertEquals(
+ 20220908000000L, DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(Step.DAY, "2022-09-08"));
+ Assert.assertEquals(
+ 20220908100000L, DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(Step.HOUR, "2022-09-08 10"));
+ Assert.assertEquals(
+ 20220908101000L,
+ DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(Step.MINUTE, "2022-09-08 1010")
+ );
+ Assert.assertEquals(
+ 20220908101010L,
+ DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(Step.SECOND, "2022-09-08 101010")
+ );
+ try {
+ DurationUtils.INSTANCE.startTimeDurationToSecondTimeBucket(Step.HOUR, "2022-09-08 30");
+ Assert.fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue(true);
+ }
+ }
+
+ @Test
+ public void testEndTimeDurationToSecondTimeBucket() {
+ Assert.assertEquals(
+ 20220908235959L, DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(Step.DAY, "2022-09-08"));
+ Assert.assertEquals(
+ 20220908105959L, DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(Step.HOUR, "2022-09-08 10"));
+ Assert.assertEquals(
+ 20220908101059L, DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(Step.MINUTE, "2022-09-08 1010"));
+ Assert.assertEquals(
+ 20220908101010L,
+ DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(Step.SECOND, "2022-09-08 101010")
+ );
+ try {
+ DurationUtils.INSTANCE.endTimeDurationToSecondTimeBucket(Step.HOUR, "2022-09-08 30");
+ Assert.fail("Should throw IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ Assert.assertTrue(true);
+ }
+ }
+}