Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion lib/src/main/java/com/auth0/jwt/impl/PayloadDeserializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,20 @@ Instant getInstantFromSeconds(Map<String, JsonNode> tree, String claimName) {
if (node == null || node.isNull()) {
return null;
}
if (!node.canConvertToLong()) {
// A NumericDate per RFC 7519 is a JSON number and may be written in scientific notation
// (for example 1.7e9). Split the two failure modes so the thrown error is accurate: a
// genuinely non-numeric value, versus a numeric value that is out of the range a long can
// hold (such as 1.733162101e+26). Previously both produced "non-numeric date value", which
// is wrong for the second case and made large/scientific values look unsupported.
if (!node.isNumber()) {
throw new JWTDecodeException(
String.format("The claim '%s' contained a non-numeric date value.", claimName));
}
if (!node.canConvertToLong()) {
throw new JWTDecodeException(String.format(
"The claim '%s' value (%s) is out of the range representable as a NumericDate.",
claimName, node.asText()));
}
return Instant.ofEpochSecond(node.asLong());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,34 @@ public void shouldGetLargeInstantWhenParsingNumericNode() {
assertThat(instant.toEpochMilli(), is(2147493647L * 1000));
}

// https://github.com/auth0/java-jwt/issues/706 - a NumericDate may be written in scientific
// notation. An in-range value must still resolve to the right instant.
@Test
public void shouldGetInstantWhenParsingScientificNotationNode() {
Map<String, JsonNode> tree = new HashMap<>();
DoubleNode node = new DoubleNode(1.7e9);
tree.put("key", node);

Instant instant = deserializer.getInstantFromSeconds(tree, "key");
assertThat(instant, is(notNullValue()));
assertThat(instant, is(Instant.ofEpochSecond(1_700_000_000L)));
}

// A numeric value that does not fit a long (the exact value reported in issue #706) must be
// rejected as out of range, not mislabeled as non-numeric.
@Test
public void shouldThrowOutOfRangeWhenNumericDateExceedsLong() {
exception.expect(JWTDecodeException.class);
exception.expectMessage(
"The claim 'key' value (1.733162101E26) is out of the range representable as a NumericDate.");

Map<String, JsonNode> tree = new HashMap<>();
DoubleNode node = new DoubleNode(1.733162101e+26);
tree.put("key", node);

deserializer.getInstantFromSeconds(tree, "key");
}

@Test
public void shouldGetNullStringWhenParsingNullNode() {
Map<String, JsonNode> tree = new HashMap<>();
Expand Down