diff options
Diffstat (limited to 'libfreerdp/codec/ncrush.c')
-rw-r--r-- | libfreerdp/codec/ncrush.c | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/libfreerdp/codec/ncrush.c b/libfreerdp/codec/ncrush.c index 4a7162c..28b98d9 100644 --- a/libfreerdp/codec/ncrush.c +++ b/libfreerdp/codec/ncrush.c @@ -2068,6 +2068,12 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSi return 1; } + if (SrcSize < 4) + { + WLog_ERR(TAG, "Input size short: SrcSize %" PRIu32 " < 4", SrcSize); + return -1; + } + const BYTE* SrcEnd = &pSrcData[SrcSize]; const BYTE* SrcPtr = pSrcData + 4; @@ -2119,7 +2125,7 @@ int ncrush_decompress(NCRUSH_CONTEXT* ncrush, const BYTE* pSrcData, UINT32 SrcSi CopyOffset = ncrush->OffsetCache[OffsetCacheIndex]; const UINT16 Mask = get_word(&HuffTableMask[21]); const UINT32 MaskedBits = bits & Mask; - if (MaskedBits > ARRAYSIZE(HuffTableLOM)) + if (MaskedBits >= ARRAYSIZE(HuffTableLOM)) return -1; LengthOfMatch = HuffTableLOM[MaskedBits] & 0xFFF; BitLength = HuffTableLOM[MaskedBits] >> 12; @@ -2480,50 +2486,39 @@ static int ncrush_find_best_match(NCRUSH_CONTEXT* ncrush, UINT16 HistoryOffset, static int ncrush_move_encoder_windows(NCRUSH_CONTEXT* ncrush, BYTE* HistoryPtr) { - int NewHash = 0; - int NewMatch = 0; - UINT32 HistoryOffset = 0; - WINPR_ASSERT(ncrush); WINPR_ASSERT(HistoryPtr); - if (HistoryPtr < &ncrush->HistoryBuffer[32768]) + const size_t history_half = ARRAYSIZE(ncrush->HistoryBuffer) / 2; + if (HistoryPtr < &ncrush->HistoryBuffer[history_half]) return -1; - if (HistoryPtr > &ncrush->HistoryBuffer[65536]) + if (HistoryPtr > &ncrush->HistoryBuffer[ARRAYSIZE(ncrush->HistoryBuffer)]) return -1; - MoveMemory(ncrush->HistoryBuffer, HistoryPtr - 32768, 32768); - const intptr_t hsize = HistoryPtr - 32768 - ncrush->HistoryBuffer; - WINPR_ASSERT(hsize <= UINT32_MAX); + MoveMemory(ncrush->HistoryBuffer, HistoryPtr - history_half, history_half * sizeof(BYTE)); + const intptr_t hsize = HistoryPtr - history_half - ncrush->HistoryBuffer; + WINPR_ASSERT(hsize <= UINT16_MAX); WINPR_ASSERT(hsize >= 0); - HistoryOffset = (UINT32)hsize; + INT32 HistoryOffset = (INT32)hsize; - for (int i = 0; i < 65536; i += 4) + for (size_t i = 0; i < ARRAYSIZE(ncrush->HashTable); i++) { - NewHash = ncrush->HashTable[i + 0] - HistoryOffset; - ncrush->HashTable[i + 0] = (NewHash <= 0) ? 0 : NewHash; - NewHash = ncrush->HashTable[i + 1] - HistoryOffset; - ncrush->HashTable[i + 1] = (NewHash <= 0) ? 0 : NewHash; - NewHash = ncrush->HashTable[i + 2] - HistoryOffset; - ncrush->HashTable[i + 2] = (NewHash <= 0) ? 0 : NewHash; - NewHash = ncrush->HashTable[i + 3] - HistoryOffset; - ncrush->HashTable[i + 3] = (NewHash <= 0) ? 0 : NewHash; + INT32 NewHash = ncrush->HashTable[i] - HistoryOffset; + ncrush->HashTable[i] = (NewHash <= 0) ? 0 : NewHash; } - for (int j = 0; j < 32768; j += 4) + const size_t match_half = ARRAYSIZE(ncrush->MatchTable) / 2; + for (size_t j = 0; j < match_half; j++) { - NewMatch = ncrush->MatchTable[HistoryOffset + j + 0] - HistoryOffset; - ncrush->MatchTable[j + 0] = (NewMatch <= 0) ? 0 : NewMatch; - NewMatch = ncrush->MatchTable[HistoryOffset + j + 1] - HistoryOffset; - ncrush->MatchTable[j + 1] = (NewMatch <= 0) ? 0 : NewMatch; - NewMatch = ncrush->MatchTable[HistoryOffset + j + 2] - HistoryOffset; - ncrush->MatchTable[j + 2] = (NewMatch <= 0) ? 0 : NewMatch; - NewMatch = ncrush->MatchTable[HistoryOffset + j + 3] - HistoryOffset; - ncrush->MatchTable[j + 3] = (NewMatch <= 0) ? 0 : NewMatch; + if (HistoryOffset + j >= ARRAYSIZE(ncrush->MatchTable)) + continue; + + INT32 NewMatch = ncrush->MatchTable[HistoryOffset + j] - HistoryOffset; + ncrush->MatchTable[j] = (NewMatch <= 0) ? 0 : NewMatch; } - ZeroMemory(&ncrush->MatchTable[32768], 65536); + ZeroMemory(&ncrush->MatchTable[match_half], match_half * sizeof(UINT16)); return 1; } |