Affected version: 26.4.2 (confirmed still present in 26.5.1)
Component: com.arcadedb.engine.WALFile
Summary
getTransaction (a) calls channel.read(buffer, pos) without checking the return value (short reads leave the buffer partially populated) and (b) catches every Exception and returns null — the same sentinel used to signal "end of WAL". Any I/O hiccup mid-replay is treated as clean EOF.
Code
engine/com/arcadedb/engine/WALFile.java:203–221
final ByteBuffer buffer = ByteBuffer.allocate(deltaSize);
tx.pages[i].currentContent = new Binary(buffer);
channel.read(buffer, pos); // return value never checked
pos += deltaSize;
…
} catch (final Exception e) {
return null; // same value used for "truncated WAL"
}
Impact
A transient I/O error during recovery is indistinguishable from clean EOF.
Recovery stops mid-replay, silently dropping every committed transaction after the failing read. Short reads that escape Exception instead yield garbage page deltas applied to disk.
Suggested fix
Loop the read until the buffer is filled or end-of-file (read == -1);
distinguish genuine EOF from IOException by re-throwing the latter as a typed WALException.
Affected version: 26.4.2 (confirmed still present in 26.5.1)
Component:
com.arcadedb.engine.WALFileSummary
getTransaction(a) callschannel.read(buffer, pos)without checking the return value (short reads leave the buffer partially populated) and (b) catches everyExceptionand returnsnull— the same sentinel used to signal "end of WAL". Any I/O hiccup mid-replay is treated as clean EOF.Code
engine/com/arcadedb/engine/WALFile.java:203–221Impact
A transient I/O error during recovery is indistinguishable from clean EOF.
Recovery stops mid-replay, silently dropping every committed transaction after the failing read. Short reads that escape
Exceptioninstead yield garbage page deltas applied to disk.Suggested fix
Loop the read until the buffer is filled or end-of-file (
read == -1);distinguish genuine EOF from
IOExceptionby re-throwing the latter as a typedWALException.