title: Java scanner usage with \R pattern (issue with buffer boundary)
body: <p><strong>Executive summary:</strong> Are there any caveats/known issues with <code>\R</code> (or other regex pattern) usage in Java's <code>Scanner</code> (especially regarding internal buffer's boundary conditions)?</p>
  
  <p><strong>Details:</strong> Since I wanted to do some multi-line pattern matching on potentially multi-platform input files, I used patterns with <code>\R</code>, which according to <code>Pattern</code> javadoc is:</p>
  
  <blockquote>
    <p>Any Unicode linebreak sequence, is equivalent to
    <code>\u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]</code></p>
  </blockquote>
  
  <p>Anyhow, I noticed in one of my test files that the loop that's supposed to parse a block of a hex-dump was cut short. After some debugging, I noticed that the line that it was ending on was the end of Scanner's internal buffer.</p>
  
  <p>Here's a test program I wrote to simulate the situation:</p>
  
  <pre><code>public static void main(String[] args) throws IOException {
      testString(1);
      testString(1022);
  }
  
  private static void testString(int prefixLen) {
      String suffix = "b\r\nX";
      String buffer = new String(new char[prefixLen]).replace("\0", "a") + suffix;
  
      Scanner scanner = new Scanner(buffer);
      String pattern = "b\\R";
      System.out.printf("=================\nTest String (Len=%d): '%s'\n'%s' found with horizon=0 (w/o bound): %s\n", buffer.length(), convertLineEndings(
          buffer), pattern, convertLineEndings(scanner.findWithinHorizon(pattern, 0)));
      System.out.printf("'X' found with horizon=1: %b\n", scanner.findWithinHorizon("X", 1) != null);
      scanner.close();
  }
  
  private static String convertLineEndings(String string) {
      return string.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r");
  }
  </code></pre>
  
  <p>... which produces this output (edited for formatting/brevity):</p>
  
  <pre class="lang-none prettyprint-override"><code>=================
  Test String (Len=5): 'ab\r\nX'
  'b\R' found with horizon=0 (w/o bound): b\r\n
  'X' found with horizon=1: true
  =================
  Test String (Len=1026): 'a ... ab\r\nX'
  'b\R' found with horizon=0 (w/o bound): b\r
  'X' found with horizon=1: false
  </code></pre>
  
  <p>To me, this looks like a bug! I think the scanner should match that <code>suffix</code> with the patterns the same way independent of where they show up in the input text (as long as the <code>prefix</code> doesn't get involved with the patterns). (I have also found possibly relevant <strong>Open</strong> JDK Bugs <a href="https://bugs.openjdk.java.net/browse/JDK-8176407" rel="noreferrer">8176407</a>, and <a href="https://bugs.openjdk.java.net/browse/JDK-8072582" rel="noreferrer">8072582</a>, but this was with regular Oracle JDK 8u111).</p>
  
  <p>But I may have missed some recommendations regarding scanner or particular <code>\R</code> pattern usage (or that Open JDK, and Oracle have identical(??) implementations for relevant classes here?)... hence the question!</p>