[ 
https://issues.apache.org/jira/browse/SUREFIRE-1522?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Rob Platt updated SUREFIRE-1522:
--------------------------------
    Description: 
There is a regression, I believe caused by SUREFIRE-1454. It can be easily 
reproduced with the following test:

 
{code:java}
import org.junit.jupiter.api.Test;

import java.nio.charset.StandardCharsets;

public class SurefireLoggingTest {

    private final byte[] aNiceString = "what fun times, standard out is 
broken\n".getBytes(StandardCharsets.US_ASCII);

    @Test
    public void fun() {
        System.out.write(aNiceString, 5, 3);
    }

    @Test
    public void fun_times() {
        System.out.write(aNiceString, 5, 9);
    }
}
{code}
Both tests will pass under Intellij, writing "fun" and "fun times" to 
System.out. Whereas, with Surefire capturing standard out when running from 
maven, only fun_times() passes. fun() will fail with:
{noformat}
java.lang.IndexOutOfBoundsException: off < 0 || len < 0 || off >= input.length 
|| len > input.length || off > len{noformat}
 

If you look at the contract for PrintStream.write(), you can see that len is 
"Number of bytes to write", so you can see that it should be fine to print the 
substring "fun", of length 3, at offset 5. And indeed that is what happens in 
Intellij.

 

I suspect that the failing test isolates the problem to when the offset 
"exceeds" the length of the substring. The wrong length is being checked in 
StringUtils.escapeBytesToPrintable(). I think that the check intended to ensure 
the offset didn't exceed the end of the byte array, not the length of the slice.

  was:
There is a regression, I believe caused by SUREFIRE-1454. It can be easily 
reproduced with the following test:

 
{code:java}
import org.junit.jupiter.api.Test;

import java.nio.charset.StandardCharsets;

public class SurefireLoggingTest {

    private final byte[] aNiceString = "what fun times, standard out it 
broken\n".getBytes(StandardCharsets.US_ASCII);

    @Test
    public void fun() {
        System.out.write(aNiceString, 5, 3);
    }

    @Test
    public void fun_times() {
        System.out.write(aNiceString, 5, 9);
    }
}
{code}
Both tests will pass under Intellij, writing "fun" and "fun times" to 
System.out. Whereas, with Surefire capturing standard out when running from 
maven, only fun_times() passes. fun() will fail with:
{noformat}
java.lang.IndexOutOfBoundsException: off < 0 || len < 0 || off >= input.length 
|| len > input.length || off > len{noformat}
 

If you look at the contract for PrintStream.write(), you can see that len is 
"Number of bytes to write", so you can see that it should be fine to print the 
substring "fun", of length 3, at offset 5. And indeed that is what happens in 
Intellij.

 

I suspect that the failing test isolates the problem to when the offset 
"exceeds" the length of the substring. The wrong length is being checked in 
StringUtils.escapeBytesToPrintable(). I think that the check intended to ensure 
the offset didn't exceed the end of the byte array, not the length of the slice.


> IndexOutOfBoundsException for System.out.write
> ----------------------------------------------
>
>                 Key: SUREFIRE-1522
>                 URL: https://issues.apache.org/jira/browse/SUREFIRE-1522
>             Project: Maven Surefire
>          Issue Type: Bug
>          Components: Maven Failsafe Plugin, Maven Surefire Plugin, process 
> forking
>    Affects Versions: 2.21.0
>            Reporter: Rob Platt
>            Priority: Major
>
> There is a regression, I believe caused by SUREFIRE-1454. It can be easily 
> reproduced with the following test:
>  
> {code:java}
> import org.junit.jupiter.api.Test;
> import java.nio.charset.StandardCharsets;
> public class SurefireLoggingTest {
>     private final byte[] aNiceString = "what fun times, standard out is 
> broken\n".getBytes(StandardCharsets.US_ASCII);
>     @Test
>     public void fun() {
>         System.out.write(aNiceString, 5, 3);
>     }
>     @Test
>     public void fun_times() {
>         System.out.write(aNiceString, 5, 9);
>     }
> }
> {code}
> Both tests will pass under Intellij, writing "fun" and "fun times" to 
> System.out. Whereas, with Surefire capturing standard out when running from 
> maven, only fun_times() passes. fun() will fail with:
> {noformat}
> java.lang.IndexOutOfBoundsException: off < 0 || len < 0 || off >= 
> input.length || len > input.length || off > len{noformat}
>  
> If you look at the contract for PrintStream.write(), you can see that len is 
> "Number of bytes to write", so you can see that it should be fine to print 
> the substring "fun", of length 3, at offset 5. And indeed that is what 
> happens in Intellij.
>  
> I suspect that the failing test isolates the problem to when the offset 
> "exceeds" the length of the substring. The wrong length is being checked in 
> StringUtils.escapeBytesToPrintable(). I think that the check intended to 
> ensure the offset didn't exceed the end of the byte array, not the length of 
> the slice.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to