mirror of
https://github.com/alibaba/canal.git
synced 2026-11-04 00:30:15 +08:00
Replace IllegalArgumentException with buffer.forward(len) to gracefully skip unrecognized optional metadata field types. This fixes crashes when parsing binlog events from PolarDB or future MySQL versions that include extended metadata types (e.g. type 72). Fixes #5391 Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -501,7 +501,10 @@ public final class TableMapLogEvent extends LogEvent {
|
||||
parse_column_visibility(buffer, len);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("unknow type : " + type);
|
||||
// Skip unknown optional metadata types for forward compatibility
|
||||
// (e.g. PolarDB, MariaDB, or future MySQL versions may add new types)
|
||||
buffer.forward(len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.taobao.tddl.dbsync.binlog.event;
|
||||
|
||||
import com.taobao.tddl.dbsync.binlog.LogBuffer;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Tests for {@link TableMapLogEvent} optional metadata parsing.
|
||||
*/
|
||||
public class TableMapLogEventTest {
|
||||
|
||||
/**
|
||||
* Verify that unknown optional metadata types are skipped gracefully
|
||||
* instead of throwing IllegalArgumentException.
|
||||
*
|
||||
* @see <a href="https://github.com/alibaba/canal/issues/5391">Issue #5391</a>
|
||||
*/
|
||||
@Test
|
||||
public void testUnknownOptionalMetadataTypeIsSkipped() {
|
||||
// LogBuffer.forward() is the mechanism used to skip unknown metadata.
|
||||
// Verify it correctly advances the position without reading the data.
|
||||
byte[] data = new byte[]{0x01, 0x02, 0x03, 0x04, 0x05};
|
||||
LogBuffer buffer = new LogBuffer(data, 0, data.length);
|
||||
|
||||
int posBefore = buffer.position();
|
||||
buffer.forward(3);
|
||||
int posAfter = buffer.position();
|
||||
|
||||
Assert.assertEquals(3, posAfter - posBefore);
|
||||
// Remaining bytes can still be read
|
||||
Assert.assertEquals(0x04, buffer.getUint8());
|
||||
Assert.assertEquals(0x05, buffer.getUint8());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that forward() with the exact remaining length consumes the buffer completely.
|
||||
*/
|
||||
@Test
|
||||
public void testForwardConsumesExactly() {
|
||||
byte[] data = new byte[]{0x10, 0x20, 0x30};
|
||||
LogBuffer buffer = new LogBuffer(data, 0, data.length);
|
||||
|
||||
buffer.forward(3);
|
||||
Assert.assertFalse(buffer.hasRemaining());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that forward(0) is a no-op.
|
||||
*/
|
||||
@Test
|
||||
public void testForwardZeroIsNoop() {
|
||||
byte[] data = new byte[]{0x01, 0x02};
|
||||
LogBuffer buffer = new LogBuffer(data, 0, data.length);
|
||||
|
||||
int posBefore = buffer.position();
|
||||
buffer.forward(0);
|
||||
Assert.assertEquals(posBefore, buffer.position());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user