Update buffer readerIndex after XML parsing error 18/108818/2
authorSangwook Ha <sangwook.ha@verizon.com>
Thu, 2 Nov 2023 08:40:52 +0000 (01:40 -0700)
committerIvan Hrasko <ivan.hrasko@pantheon.tech>
Fri, 3 Nov 2023 08:18:34 +0000 (09:18 +0100)
The readerIndex of the input buffer may have not reached the end
of the message when XML parsing fails. And in this case unnecessary
decoding may get repeatedly triggered for the unread partial message.

Make sure that readerIndex advances to writerIndex so that the next
decoding can start for a new message and add a test case to show this
parsing error scenario.

It means that we can skip all readable bytes counted by:
(ByteBuff.writerIndex - ByteBuff.readerIndex).

JIRA: NETCONF-1194
Change-Id: I01b668eb0c995ff01435e983cdbba1490645909e
Signed-off-by: Sangwook Ha <sangwook.ha@verizon.com>
Signed-off-by: Ivan Hrasko <ivan.hrasko@pantheon.tech>
netconf/netconf-netty-util/src/main/java/org/opendaylight/netconf/nettyutil/handler/NetconfXMLToMessageDecoder.java
netconf/netconf-netty-util/src/test/java/org/opendaylight/netconf/nettyutil/handler/NetconfXMLToMessageDecoderTest.java

index 9244d8ee1993ae84ff0f56ae661fb3cd264fbff0..0a1e44f264d7e69521fc0bcda4de08798f0ee70a 100644 (file)
@@ -74,6 +74,7 @@ public final class NetconfXMLToMessageDecoder extends ByteToMessageDecoder {
             } catch (SAXParseException e) {
                 LOG.error("Failed to parse received message", e);
                 out.add(e);
+                in.skipBytes(in.readableBytes());
             }
         } else {
             LOG.debug("No more content in incoming buffer.");
index 44f718807fbef2c745cdd25973bd2ccacc05d750..6a0d79f0d07d282017c59325e1f070a3c887f5d7 100644 (file)
@@ -7,12 +7,15 @@
  */
 package org.opendaylight.netconf.nettyutil.handler;
 
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
 import org.junit.Test;
+import org.opendaylight.netconf.api.messages.NetconfMessage;
 import org.xml.sax.SAXParseException;
 
 public class NetconfXMLToMessageDecoderTest {
@@ -89,5 +92,23 @@ public class NetconfXMLToMessageDecoderTest {
                 out);
         assertEquals(1, out.size());
     }
-}
 
+    @Test
+    public void testDecodeAfterInvalidXml() throws Exception {
+        /* Test that decoding of the next message after an invalid XML is successful.
+        */
+        final var out = new ArrayList<>();
+        final var decoder = new NetconfXMLToMessageDecoder();
+        final var buffer = Unpooled.buffer();
+
+        buffer.writeBytes("<?xml version=\"1.0\"\u0006 encoding=\"UTF-8\"?><msg/>".getBytes());
+        decoder.decode(null, buffer, out);
+        assertEquals(1, out.size());
+        assertThat(out.get(0), instanceOf(SAXParseException.class));
+
+        buffer.writeBytes("<msg/>".getBytes());
+        decoder.decode(null, buffer, out);
+        assertEquals(2, out.size());
+        assertThat(out.get(1), instanceOf(NetconfMessage.class));
+    }
+}