[ 
https://issues.apache.org/jira/browse/IGNITE-28747?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18091245#comment-18091245
 ] 

Egor Baranov commented on IGNITE-28747:
---------------------------------------

Additional test cases:
{code:java}
@Test
public void reproduceRecursionThrowsNPE() {
    // it's in the tail
    RecursivePayload recursivePayload1 = new RecursivePayload('1', 1, null);
    String identity = identity(recursivePayload1);
    RecursivePayload recursivePayload2 = new RecursivePayload('2', 1, 
recursivePayload1);
    recursivePayload1.setChild(recursivePayload2);
    RecursivePayload recursivePayload0 = new RecursivePayload(7868 + 27, 
recursivePayload1);
    String result = recursivePayload0.toString();    
info(String.valueOf(result.length()));
    info(result);
    assertTrue(result.matches("^.*" + identity + ".*" + identity + ".*$"));
}

@Test
public void reproduceRecursionThrowsStringIndexOutOfBoundsException() {
    // it's in the tail
    RecursivePayload recursivePayload1 = new RecursivePayload('1', 1, null);
    String identity = identity(recursivePayload1);
    RecursivePayload recursivePayload2 = new RecursivePayload('2', 1, 
recursivePayload1);
    recursivePayload1.setChild(recursivePayload2);
    RecursivePayload recursivePayload0 = new RecursivePayload(8_001, 
recursivePayload1);
    String result = recursivePayload0.toString();
    info(result);
    assertTrue(result.matches("^.*" + identity + ".*" + identity + ".*$"));
}

@Test
public void reproduceRecursionIssue() {
    RecursivePayload recursivePayload1 = new RecursivePayload(8_000, null);
    RecursivePayload recursivePayload2 = new RecursivePayload(4_000, 
recursivePayload1);
    recursivePayload1.setChild(recursivePayload2);
    String result;
    result = recursivePayload1.toString();
    info(result);
    String identity = identity(recursivePayload1);
    assertTrue(result.matches("^.*" + identity + ".*" + identity + ".*$"));
}/** */
private static class RecursivePayload {
    /** */
    private final String payload;    /** */
    private RecursivePayload child;    /**
     * Constructor
     * @param payloadLength Payload length.
     * @param child         Child (nullable)
     */
    private RecursivePayload(int payloadLength, RecursivePayload child) {
        this('a', payloadLength, child);
    }    /**
     * Constructor
     * @param payloadChar   PayloadChar
     * @param payloadLength Payload length.
     * @param child         Child (nullable)
     */
    private RecursivePayload(char payloadChar, int payloadLength, 
RecursivePayload child) {
        payload = String.valueOf(payloadChar).repeat(payloadLength);
        this.child = child;
    }    /** */
    public String getPayload() {
        return payload;
    }    /** */
    public RecursivePayload getChild() {
        return child;
    }    /** */
    public void setChild(RecursivePayload child) {
        this.child = child;
    }    /** {@inheritDoc} */
    @Override public String toString() {
        return S.toString(RecursivePayload.class, this);
    }
}{code}
 

> GridToStringBuilder#handleRecursion may cause NPE
> -------------------------------------------------
>
>                 Key: IGNITE-28747
>                 URL: https://issues.apache.org/jira/browse/IGNITE-28747
>             Project: Ignite
>          Issue Type: Bug
>            Reporter: Egor Baranov
>            Assignee: Egor Baranov
>            Priority: Major
>              Labels: ise
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> When recursion occurs on the end of string builder it may cause NPE.
> Possible solution: override #i in class SBLimitedLength to execute the same 
> logic as in methods #a
> Here is exception stack trace:
> {code:java}
> [2026-06-03T11:53:10,217][ERROR][test-runner-#181143%internal.IgniteDiscoveryMassiveNodeFailTest%][IgniteDiscoveryMassiveNodeFailTest0]
>  Got exception while starting (will rollback startup routine).
>   class org.apache.ignite.IgniteException: Cannot invoke 
> "org.apache.ignite.internal.util.tostring.CircularStringBuilder.append(String)"
>  because "this.tail" is null
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toStringImpl0(GridToStringBuilder.java:1174)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toStringImpl(GridToStringBuilder.java:1057)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toString(GridToStringBuilder.java:843)
>     at 
> org.apache.ignite.spi.checkpoint.sharedfs.SharedFsCheckpointSpi.toString(SharedFsCheckpointSpi.java:552)
>     at java.base/java.lang.String.valueOf(String.java:4220)
>     at 
> org.apache.ignite.internal.managers.GridManagerAdapter.startSpi(GridManagerAdapter.java:262)
>     at 
> org.apache.ignite.internal.managers.checkpoint.GridCheckpointManager.start(GridCheckpointManager.java:112)
>     at 
> org.apache.ignite.internal.IgniteKernal.startManager(IgniteKernal.java:1690)
>     at org.apache.ignite.internal.IgniteKernal.start(IgniteKernal.java:1015)
>     at 
> org.apache.ignite.internal.IgnitionEx$IgniteNamedInstance.start0(IgnitionEx.java:1714)
>     at 
> org.apache.ignite.internal.IgnitionEx$IgniteNamedInstance.start(IgnitionEx.java:1636)
>     at org.apache.ignite.internal.IgnitionEx.start0(IgnitionEx.java:1078)
>     at org.apache.ignite.internal.IgnitionEx.start(IgnitionEx.java:588)
>     at 
> org.apache.ignite.testframework.junits.GridAbstractTest.startGrid(GridAbstractTest.java:1323)
>     at 
> org.apache.ignite.testframework.junits.GridAbstractTest.startGrid(GridAbstractTest.java:1240)
>     at 
> org.apache.ignite.testframework.junits.GridAbstractTest.startGrid(GridAbstractTest.java:1216)
>     at 
> org.apache.ignite.testframework.junits.GridAbstractTest.startGrid(GridAbstractTest.java:1047)
>     at 
> org.apache.ignite.testframework.junits.GridAbstractTest.startGrids(GridAbstractTest.java:887)
>     at 
> org.apache.ignite.internal.IgniteDiscoveryMassiveNodeFailTest.doFailNodes(IgniteDiscoveryMassiveNodeFailTest.java:122)
>     at 
> org.apache.ignite.internal.IgniteDiscoveryMassiveNodeFailTest.testMassiveFail(IgniteDiscoveryMassiveNodeFailTest.java:258)
>     at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native 
> Method)
>     at 
> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
>     at 
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>     at java.base/java.lang.reflect.Method.invoke(Method.java:569)
>     at 
> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
>     at 
> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
>     at 
> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
>     at 
> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
>     at 
> org.apache.ignite.testframework.junits.GridAbstractTest$6.run(GridAbstractTest.java:2486)
>     at java.base/java.lang.Thread.run(Thread.java:840)
>   Caused by: class org.apache.ignite.IgniteException: Cannot invoke 
> "org.apache.ignite.internal.util.tostring.CircularStringBuilder.append(String)"
>  because "this.tail" is null
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toStringImpl0(GridToStringBuilder.java:1174)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toStringImpl(GridToStringBuilder.java:1057)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toString(GridToStringBuilder.java:843)
>     at 
> org.apache.ignite.internal.IgniteKernal.toString(IgniteKernal.java:3546)
>     at java.base/java.lang.String.valueOf(String.java:4220)
>     at 
> org.apache.ignite.internal.util.GridStringBuilder.a(GridStringBuilder.java:101)
>     at 
> org.apache.ignite.internal.util.tostring.SBLimitedLength.a(SBLimitedLength.java:100)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toString(GridToStringBuilder.java:912)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toStringImpl0(GridToStringBuilder.java:1123)
>     ... 29 more
>   Caused by: class org.apache.ignite.IgniteException: Cannot invoke 
> "org.apache.ignite.internal.util.tostring.CircularStringBuilder.append(String)"
>  because "this.tail" is null
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toStringImpl0(GridToStringBuilder.java:1174)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toStringImpl(GridToStringBuilder.java:1057)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toString(GridToStringBuilder.java:843)
>     at 
> org.apache.ignite.internal.IgniteKernal$ReconnectState.toString(IgniteKernal.java:3540)
>     at java.base/java.lang.String.valueOf(String.java:4220)
>     at 
> org.apache.ignite.internal.util.GridStringBuilder.a(GridStringBuilder.java:101)
>     at 
> org.apache.ignite.internal.util.tostring.SBLimitedLength.a(SBLimitedLength.java:100)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toString(GridToStringBuilder.java:912)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toStringImpl0(GridToStringBuilder.java:1123)
>     ... 37 more
>   Caused by: java.lang.NullPointerException: Cannot invoke 
> "org.apache.ignite.internal.util.tostring.CircularStringBuilder.append(String)"
>  because "this.tail" is null
>     at 
> org.apache.ignite.internal.util.tostring.SBLimitedLength.a(SBLimitedLength.java:108)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.handleRecursion(GridToStringBuilder.java:2037)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toString(GridToStringBuilder.java:899)
>     at 
> org.apache.ignite.internal.util.tostring.GridToStringBuilder.toStringImpl0(GridToStringBuilder.java:1123)
>     ... 45 more
> {code}



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to