diff --git a/pom.xml b/pom.xml
index 324a4af..324c446 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,6 +60,12 @@ limitations under the License.
5.10.1
test
+
+ com.code-intelligence
+ jazzer-junit
+ 0.22.1
+ test
+
diff --git a/src/main/java/com/ethlo/time/internal/EthloITU.java b/src/main/java/com/ethlo/time/internal/EthloITU.java
index 1983ca7..2035092 100644
--- a/src/main/java/com/ethlo/time/internal/EthloITU.java
+++ b/src/main/java/com/ethlo/time/internal/EthloITU.java
@@ -308,7 +308,6 @@ private static Object handleTime(int year, int month, int day, int hour, int min
if (remaining == 2)
{
final int seconds = parsePositiveInt(chars, 17, 19);
- leapSecondCheck(year, month, day, hour, minute, 0, 0, null);
if (raw)
{
return new DateTime(Field.SECOND, year, month, day, hour, minute, seconds, 0, null, 0);
@@ -389,10 +388,10 @@ else if (c == PLUS || c == MINUS)
}
final int second = parsePositiveInt(chars, 17, 19);
- leapSecondCheck(year, month, day, hour, minute, second, fractions, offset);
if (!raw)
{
+ leapSecondCheck(year, month, day, hour, minute, second, fractions, offset);
return OffsetDateTime.of(year, month, day, hour, minute, second, fractions, offset.toZoneOffset());
}
return fractionDigits > 0 ? DateTime.of(year, month, day, hour, minute, second, fractions, offset, fractionDigits) : DateTime.of(year, month, day, hour, minute, second, offset);
@@ -415,8 +414,8 @@ private static void leapSecondCheck(int year, int month, int day, int hour, int
final boolean isValidLeapYearMonth = leapSecondHandler.isValidLeapSecondDate(needle);
if (isValidLeapYearMonth || needle.isAfter(leapSecondHandler.getLastKnownLeapSecond()))
{
- final int utcHour = hour - (offset.getTotalSeconds() / 3_600);
- final int utcMinute = minute - ((offset.getTotalSeconds() % 3_600) / 60);
+ final int utcHour = hour - offset.getTotalSeconds() / 3_600;
+ final int utcMinute = minute - (offset.getTotalSeconds() % 3_600) / 60;
if (((month == Month.DECEMBER.getValue() && day == 31) || (month == Month.JUNE.getValue() && day == 30))
&& utcHour == 23
&& utcMinute == 59)
diff --git a/src/test/java/com/ethlo/time/CorrectnessTest.java b/src/test/java/com/ethlo/time/CorrectnessTest.java
index 4962a9c..d04a052 100644
--- a/src/test/java/com/ethlo/time/CorrectnessTest.java
+++ b/src/test/java/com/ethlo/time/CorrectnessTest.java
@@ -470,4 +470,10 @@ void testTemporalAccessorNanos()
assertThat(parsed.getLong(ChronoField.NANO_OF_SECOND)).isEqualTo(987654321);
}
+
+ @Test
+ void testParseLeapSecondWhenNoTimeOffsetPresent()
+ {
+ ITU.parseLenient("3011-10-02T22:00:60.003");
+ }
}
diff --git a/src/test/java/com/ethlo/time/fuzzer/ParseDateTimeFuzzTest.java b/src/test/java/com/ethlo/time/fuzzer/ParseDateTimeFuzzTest.java
new file mode 100644
index 0000000..312c4cb
--- /dev/null
+++ b/src/test/java/com/ethlo/time/fuzzer/ParseDateTimeFuzzTest.java
@@ -0,0 +1,42 @@
+package com.ethlo.time.fuzzer;
+
+/*-
+ * #%L
+ * Internet Time Utility
+ * %%
+ * Copyright (C) 2017 - 2024 Morten Haraldsen (ethlo)
+ * %%
+ * Licensed 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.
+ * #L%
+ */
+
+import java.time.DateTimeException;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import com.ethlo.time.ITU;
+
+public class ParseDateTimeFuzzTest
+{
+ @com.code_intelligence.jazzer.junit.FuzzTest(maxDuration = "2m")
+ void parse(FuzzedDataProvider data)
+ {
+ try
+ {
+ ITU.parseDateTime(data.consumeRemainingAsAsciiString());
+ }
+ catch (DateTimeException ignored)
+ {
+
+ }
+ }
+}
diff --git a/src/test/java/com/ethlo/time/fuzzer/ParseLenientFuzzTest.java b/src/test/java/com/ethlo/time/fuzzer/ParseLenientFuzzTest.java
new file mode 100644
index 0000000..18fcb90
--- /dev/null
+++ b/src/test/java/com/ethlo/time/fuzzer/ParseLenientFuzzTest.java
@@ -0,0 +1,51 @@
+package com.ethlo.time.fuzzer;
+
+/*-
+ * #%L
+ * Internet Time Utility
+ * %%
+ * Copyright (C) 2017 - 2024 Morten Haraldsen (ethlo)
+ * %%
+ * Licensed 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.
+ * #L%
+ */
+
+import java.time.DateTimeException;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import com.ethlo.time.DateTime;
+import com.ethlo.time.ITU;
+
+public class ParseLenientFuzzTest
+{
+ @com.code_intelligence.jazzer.junit.FuzzTest(maxDuration = "2m")
+ void parse(FuzzedDataProvider data)
+ {
+ DateTime d = null;
+ try
+ {
+ d = ITU.parseLenient(data.consumeRemainingAsString());
+ }
+ catch (DateTimeException ignored)
+ {
+
+ }
+
+ if (d != null)
+ {
+ d.toInstant();
+ System.out.println(d);
+ d.toString();
+ }
+ }
+}