Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 36 additions & 7 deletions SharpCoreDB/DataStructures/Table.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,15 +193,44 @@ private List<Dictionary<string, object>> SelectInternal(string? where, string? o
using var reader = new BinaryReader(ms);
while (ms.Position < ms.Length)
{
var row = new Dictionary<string, object>();
bool valid = true;
for (int i = 0; i < this.Columns.Count; i++)
try
{
try { row[this.Columns[i]] = this.ReadTypedValue(reader, this.ColumnTypes[i]); }
catch { valid = false; break; }
// Read the length prefix that was written by AppendBytes
int recordLength = reader.ReadInt32();

// Validate length to prevent issues with corrupted data
if (recordLength < 0 || recordLength > data.Length)
{
break; // Corrupted record, stop scanning
}

// Read the record data
var recordData = reader.ReadBytes(recordLength);

// Deserialize the record
using var recordMs = new MemoryStream(recordData);
using var recordReader = new BinaryReader(recordMs);

var row = new Dictionary<string, object>();
bool valid = true;
for (int i = 0; i < this.Columns.Count; i++)
{
try { row[this.Columns[i]] = this.ReadTypedValue(recordReader, this.ColumnTypes[i]); }
catch { valid = false; break; }
}
if (valid && (string.IsNullOrEmpty(where) || EvaluateWhere(row, where)))
results.Add(row);
}
catch (EndOfStreamException)
{
// Reached end of file
break;
}
catch (Exception)
{
// Corrupted record, skip and continue
break;
}
if (valid && (string.IsNullOrEmpty(where) || EvaluateWhere(row, where)))
results.Add(row);
}
}
}
Expand Down
22 changes: 15 additions & 7 deletions SharpCoreDB/Services/Storage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,16 +199,24 @@ public long AppendBytes(string path, byte[] data)

using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
fs.Seek(position, SeekOrigin.Begin);
var buffer = new byte[maxLength];
int bytesRead = fs.Read(buffer, 0, maxLength);
if (bytesRead == 0)
using var reader = new BinaryReader(fs);

// Read the length prefix that was written by AppendBytes
int length = reader.ReadInt32();

// Validate length to prevent excessive memory allocation
if (length < 0 || length > maxLength * 10) // Allow some buffer but prevent abuse
{
return null;
throw new InvalidDataException($"Invalid record length: {length}");
}

if (bytesRead < maxLength)

// Read the actual data (maxLength is for the data portion, not including prefix)
int bytesToRead = Math.Min(length, maxLength);
var buffer = reader.ReadBytes(bytesToRead);

if (buffer.Length == 0)
{
Array.Resize(ref buffer, bytesRead);
return null;
}

var effectiveNoEncrypt = noEncrypt || this.noEncryption;
Expand Down
Loading