Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -2387,22 +2387,35 @@ else if(prevPacket.getDotCode() == 3)
int position = pack.getDataRangeInt( 7, 1 );
NLog.d( "[CommProcessor20] received RES_OfflineChunk(0x24) command. packetId=" + packetId + ";position=" + position);
int sizeBeforeCompress = pack.getDataRangeInt( 3, 2 );
NLog.d( "[CommProcessor20] Chunk sizeBeforeCompress=" + sizeBeforeCompress + ", oRcvDataSize before=" + oRcvDataSize + ", oTotalDataSize=" + oTotalDataSize);
OfflineByteParser parser = new OfflineByteParser( pack.getData() , maxPress);
if(factor != null)
parser.setCalibrate( factor );
try
{
offlineStrokes.addAll( parser.parse() );
// Always increment received size, even if some strokes were corrupted
// This allows progress to reach 100%
oRcvDataSize += sizeBeforeCompress;

// If this is the last chunk and we haven't reached 100%, force it to complete
if (position == 2 && oRcvDataSize < oTotalDataSize) {
int remaining = oTotalDataSize - oRcvDataSize;
NLog.w("[CommProcessor20] Last chunk but " + remaining + " bytes remaining. Forcing completion to 100%.");
oRcvDataSize = oTotalDataSize;
}

NLog.d( "[CommProcessor20] Chunk processed. position=" + position + ", oRcvDataSize after=" + oRcvDataSize + ", progress=" + (oRcvDataSize * 100 / oTotalDataSize) + "%");
}
catch ( Exception e )
{
NLog.e( "[CommProcessor20] deCompress parse Error !!!" );
NLog.e( "[CommProcessor20] Fatal deCompression error. Error: " + e.getMessage() );
e.printStackTrace();
// Only reject chunk if decompression fails completely
write( ProtocolParser20.buildOfflineChunkResponse( 1, packetId, position ) );
mHandler.postDelayed( mChkOfflineFailRunnable, OFFLINE_SEND_FAIL_TIME );
return;
}

oRcvDataSize += sizeBeforeCompress;
// If you have received the chunk, process the offline data.
if ( position == 2 )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class OfflineByteParser implements IFilterListener
private int sectionId, ownerId, noteId, pageId;
private int strokeCount, sizeAfterCompress, sizeBeforeCompress;
private boolean isCompressed = false;
private boolean hasCorruptedData = false;

private final static int STROKE_HEADER_LENGTH = 27;
private final static int BYTE_DOT_SIZE = 16;
Expand Down Expand Up @@ -83,6 +84,7 @@ public ArrayList<Stroke> parse() throws Exception

stroke = null;
strokes.clear();
hasCorruptedData = false;


// Header parsing
Expand All @@ -105,6 +107,12 @@ public ArrayList<Stroke> parse() throws Exception

data = null;

// Don't throw exception - just return whatever strokes we successfully parsed
// Corrupted strokes are skipped but process continues
if (hasCorruptedData) {
NLog.w("[OfflineByteParser] Chunk had corrupted data but continuing with valid strokes.");
}

// if ( strokes == null || strokes.size() <= 0 )
// {
// return null;
Expand Down Expand Up @@ -194,6 +202,26 @@ private void parseBody() throws Exception
strokeIndex += STROKE_HEADER_LENGTH;
int dotIndex = 0;
tempDots = new ArrayList<Fdot>();

// Validate dotCount is not negative (corrupted header)
if (dotCount < 0) {
NLog.e("[OfflineByteParser] Invalid negative dotCount " + dotCount + " for stroke " + i + ". Corrupted header detected.");
checksumFailCount++;
hasCorruptedData = true;
break OUTER_STROKE_LOOP;
}

// Validate that we have enough data for all dots in this stroke
int requiredBytes = strokeIndex + (dotCount * BYTE_DOT_SIZE);
if (requiredBytes > data.length) {
NLog.e("[OfflineByteParser] Insufficient data for stroke " + i + ": need "
+ requiredBytes + " bytes but only have " + data.length
+ " (dotCount=" + dotCount + "). Marking chunk as corrupted.");
checksumFailCount++;
hasCorruptedData = true;
break OUTER_STROKE_LOOP;
}

for(int j = 0; j < dotCount; j++)
{
int sectionId = this.sectionId;
Expand Down Expand Up @@ -288,8 +316,9 @@ else if ( j == dotCount - 1 )
}
else
{
NLog.e( "[OfflineByteParser] lhCheckSum Fail Stroke cs : " + Integer.toHexString( (int) (lhCheckSum & 0xFF) ) + ", calc : " + Integer.toHexString( (int) (dotCalcCs & 0xFF) ) );
NLog.e( "[OfflineByteParser] lhCheckSum Fail Stroke cs : " + Integer.toHexString( (int) (lhCheckSum & 0xFF) ) + ", calc : " + Integer.toHexString( (int) (dotCalcCs & 0xFF) ) + ". Skipping this stroke and continuing.");
checksumFailCount++;
// Don't add this stroke's dots - just skip it and continue with next stroke
}

tempDots = new ArrayList<Fdot>();
Expand All @@ -298,8 +327,11 @@ else if ( j == dotCount - 1 )
strokeIndex += dotIndex;

}
if(checksumFailCount > 3)
throw new CheckSumException( "lhCheckSum Fail Count="+ checksumFailCount);
if(checksumFailCount > 0) {
NLog.w("[OfflineByteParser] Parsing completed with " + checksumFailCount + " checksum failures. Successfully parsed " + strokes.size() + " valid strokes out of " + strokeCount + " total.");
} else {
NLog.i("[OfflineByteParser] Parsing completed successfully. Parsed " + strokes.size() + " strokes.");
}


}
Expand Down