55
66namespace SciSharp . MySQL . Replication . Types
77{
8+ /// <summary>
9+ /// Options specific to BLOB data type.
10+ /// </summary>
11+ class BlobOptions
12+ {
13+ /// <summary>
14+ /// Gets or sets the number of bytes used to store the BLOB length (1, 2, 3, or 4).
15+ /// </summary>
16+ public int LengthBytes { get ; set ; }
17+ }
18+
819 /// <summary>
920 /// Represents the MySQL BLOB data type.
1021 /// </summary>
1122 /// <remarks>
1223 /// Handles the reading and conversion of MySQL BLOB values.
1324 /// </remarks>
14- class BlobType : IMySQLDataType
25+ class BlobType : IMySQLDataType , IColumnMetadataLoader
1526 {
27+ /// <summary>
28+ /// Loads metadata for BLOB type.
29+ /// </summary>
30+ /// <param name="columnMetadata">The column metadata object.</param>
31+ public void LoadMetadataValue ( ColumnMetadata columnMetadata )
32+ {
33+ // The metadata value for BLOB is the length of the size field in bytes (1, 2, 3, or 4)
34+ columnMetadata . Options = new BlobOptions
35+ {
36+ LengthBytes = columnMetadata . MetadataValue [ 0 ]
37+ } ;
38+ }
39+
1640 /// <summary>
1741 /// Reads a BLOB value from the binary log.
1842 /// </summary>
@@ -21,16 +45,34 @@ class BlobType : IMySQLDataType
2145 /// <returns>A byte array representing the MySQL BLOB value.</returns>
2246 public object ReadValue ( ref SequenceReader < byte > reader , ColumnMetadata columnMetadata )
2347 {
24- int blobLength = reader . ReadInteger ( columnMetadata . MetadataValue [ 0 ] ) ;
25-
26- try
48+ // Get metadata length (bytes used for size field: 1, 2, 3, or 4) from Options
49+ int lengthBytes = columnMetadata . Options is BlobOptions options ? options . LengthBytes : 0 ;
50+
51+ // Read the length of the BLOB based on metadata
52+ int blobLength = reader . ReadInteger ( lengthBytes ) ;
53+
54+ // Validate blob length to prevent out-of-memory issues
55+ if ( blobLength < 0 || blobLength > 1_000_000_000 ) // 1GB limit as safety check
2756 {
28- return reader . Sequence . Slice ( reader . Consumed , blobLength ) . ToArray ( ) ;
57+ throw new InvalidOperationException ( $ "Invalid BLOB length: { blobLength } " ) ;
2958 }
30- finally
59+
60+ // Handle empty BLOB
61+ if ( blobLength == 0 )
3162 {
32- reader . Advance ( blobLength ) ;
63+ return Array . Empty < byte > ( ) ;
3364 }
65+
66+ // Read the BLOB data
67+ byte [ ] blobData = new byte [ blobLength ] ;
68+
69+ if ( ! reader . TryCopyTo ( blobData . AsSpan ( ) ) )
70+ {
71+ throw new InvalidOperationException ( $ "Failed to read complete BLOB data (expected { blobLength } bytes)") ;
72+ }
73+
74+ reader . Advance ( blobLength ) ;
75+ return blobData ;
3476 }
3577 }
3678}
0 commit comments