Repository: amzn/ion-java (java)

Issue:
Timestamp with negative fraction in binary notation should throw error
Example: https://github.com/amzn/ion-tests/blob/master/iontestdata/bad/timestamp/timestampNegativeFraction.10n

Spec also needs to be updated to clarify this https://amzn.github.io/ion-docs/binary.html

Pull request description:
Timestamp fractional seconds outside of [0, 1) now cause an exception.
Fixes #102.

Timestamps whose fractional seconds are outside of the range 0 (inclusive) to 1 (exclusive) will now cause an exception to be thrown.

The original issue indicated that the spec itself needed to be updated to clarify this. However, it already states:

> The fractional seconds’ value is coefficient * 10 ^ exponent. **It must be greater than or equal to zero and less than 1.**

(emphasis mine) which I think is pretty clear.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.


Patch:
diff --git a/.travis.yml b/.travis.yml
index cc409f79..363db65d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,9 +1,23 @@
+sudo: false
 language: java
 jdk:
-  - openjdk8
-  - openjdk9
-  - openjdk10
-  - openjdk11
-  - oraclejdk8
-  - oraclejdk9
-  - oraclejdk11
+- openjdk8
+- openjdk9
+- openjdk10
+- openjdk11
+- oraclejdk8
+- oraclejdk9
+- oraclejdk11
+after_success:
+    # enable once we get authorization with codecov.io sorted out
+    # - bash <(curl -s https://codecov.io/bash) 
+- mvn site
+deploy:
+  provider: pages
+  local-dir: "./target/site/"
+  skip-cleanup: true
+  github-token: "$GITHUB_TOKEN"
+  keep-history: true # keeps commit history of gh-pages branch
+  on:
+    branch: master
+    jdk: openjdk11
diff --git a/pom.xml b/pom.xml
index defe6f67..d23bc976 100644
--- a/pom.xml
+++ b/pom.xml
@@ -208,6 +208,29 @@
           </reportSet>
         </reportSets>
       </plugin>
+      <!-- Findbugs -->
+      <plugin>
+        <groupId>org.codehaus.mojo</groupId>
+        <artifactId>findbugs-maven-plugin</artifactId>
+        <version>3.0.5</version>
+      </plugin>
+      <!-- PMD -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-pmd-plugin</artifactId>
+        <version>3.11.0</version>
+        <configuration>
+          <linkXref>true</linkXref>
+          <sourceEncoding>utf-8</sourceEncoding>
+          <minimumTokens>100</minimumTokens>
+        </configuration>
+      </plugin>
+      <!-- XLR to add links in reports to code -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jxr-plugin</artifactId>
+        <version>3.0.0</version>
+      </plugin>
     </plugins>
   </reporting>
 
diff --git a/src/software/amazon/ion/impl/IonReaderBinaryRawX.java b/src/software/amazon/ion/impl/IonReaderBinaryRawX.java
index 92470bb5..aca36e5d 100644
--- a/src/software/amazon/ion/impl/IonReaderBinaryRawX.java
+++ b/src/software/amazon/ion/impl/IonReaderBinaryRawX.java
@@ -1115,12 +1115,12 @@ abstract class IonReaderBinaryRawX
         year  = readVarUInt();
         Precision p = Precision.YEAR; // our lowest significant option
 
-        // now we look for hours and minutes
+        // now we look for months
         if (_local_remaining > 0) {
             month = readVarUInt();
             p = Precision.MONTH;
 
-            // now we look for hours and minutes
+            // now we look for days
             if (_local_remaining > 0) {
                 day   = readVarUInt();
                 p = Precision.DAY; // our lowest significant option
@@ -1136,6 +1136,12 @@ abstract class IonReaderBinaryRawX
                         if (_local_remaining > 0) {
                             // now we read in our actual "milliseconds since the epoch"
                             frac = readDecimal(_local_remaining);
+                            if (frac.compareTo(BigDecimal.ZERO) < 0 || frac.compareTo(BigDecimal.ONE) >= 0) {
+                                throwErrorAt(
+                                    "The fractional seconds value in a timestamp must be greater than or "
+                                        + "equal to zero and less than one."
+                                );
+                            }
                         }
                     }
                 }


Test patch:
diff --git a/test/software/amazon/ion/TestUtils.java b/test/software/amazon/ion/TestUtils.java
index 44552098..f50ff042 100644
--- a/test/software/amazon/ion/TestUtils.java
+++ b/test/software/amazon/ion/TestUtils.java
@@ -132,7 +132,6 @@ public class TestUtils
              "bad/clobWithNullCharacter.ion"                // TODO amzn/ion-java#43
             , "bad/clobWithNonAsciiCharacter.ion"           // TODO amzn/ion-java#99
             , "bad/emptyAnnotatedInt.10n"                   // TODO amzn/ion-java#55
-            , "bad/timestamp/timestampNegativeFraction.10n" // TODO amzn/ion-java#102
             , "bad/utf8/surrogate_5.ion"                    // TODO amzn/ion-java#60
             , "bad/utf8/surrogate_1.ion"                    // TODO amzn/ion-java#105
             , "bad/utf8/surrogate_2.ion"                    // TODO amzn/ion-java#105