//====================================================================================================== // Copyright 2025, Rokoko Glove OptiTrack Integration //====================================================================================================== #include "LZ4Wrapper.h" #include "lz4.h" #include #include namespace RokokoIntegration { std::vector LZ4Wrapper::Decompress(const uint8_t* compressedData, int compressedSize) { try { // 입력 데이터 검증 if (!compressedData || compressedSize <= 0) { return {}; } // LZ4 데이터 유효성 검사 if (!IsValidLZ4Data(compressedData, compressedSize)) { return {}; } // 압축 해제된 크기 추정 int decompressedSize = GetDecompressedSize(compressedData, compressedSize); if (decompressedSize <= 0) { return {}; } // 크기 유효성 검사 if (!ValidateDecompressedSize(compressedSize, decompressedSize)) { return {}; } // 압축 해제 실행 std::vector decompressed(decompressedSize); int actualSize = LZ4_decompress_safe( reinterpret_cast(compressedData), reinterpret_cast(decompressed.data()), compressedSize, decompressedSize ); // 압축 해제 결과 검증 if (actualSize != decompressedSize) { return {}; } return decompressed; } catch (...) { // 모든 예외 상황에서 안전하게 빈 벡터 반환 return {}; } } bool LZ4Wrapper::IsValidLZ4Data(const uint8_t* data, int size) { if (!data || size < 4) { return false; } // LZ4 매직 넘버 확인 (간단한 검증) // 실제로는 더 정교한 검증이 필요할 수 있음 return true; } int LZ4Wrapper::GetDecompressedSize(const uint8_t* compressedData, int compressedSize) { try { // LZ4에서 압축 해제된 크기 추정 int decompressedSize = LZ4_decompress_safe( reinterpret_cast(compressedData), nullptr, compressedSize, 0 ); return decompressedSize; } catch (...) { return -1; } } bool LZ4Wrapper::ValidateDecompressedSize(int compressedSize, int decompressedSize) { // 압축 해제된 크기가 합리적인 범위인지 확인 if (decompressedSize <= 0 || decompressedSize > MAX_DECOMPRESSED_SIZE) { return false; } // 압축률이 합리적인지 확인 (일반적으로 1:1 ~ 1:10) if (decompressedSize < compressedSize || decompressedSize > compressedSize * 10) { return false; } return true; } }