Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Marsev <alex.marsev@gmail.com>2013-05-07 23:21:15 +0400
committerAlex Marsev <alex.marsev@gmail.com>2013-05-14 00:02:41 +0400
commita54e281559b559b2a2c09a0ffaa17cdd591de2da (patch)
tree51d258c819f4efec61f7cbc1bcf1ea4f39124767 /src
parentf5e5b806fade4f017c47611427343e7da8e8d7b5 (diff)
CIfo: more safe file opening
Check all functions' returns and reject certainly invalid IFO files now. We could easily crash here before.
Diffstat (limited to 'src')
-rw-r--r--src/mpc-hc/Ifo.cpp64
1 files changed, 43 insertions, 21 deletions
diff --git a/src/mpc-hc/Ifo.cpp b/src/mpc-hc/Ifo.cpp
index 228437114..b19d2b3e4 100644
--- a/src/mpc-hc/Ifo.cpp
+++ b/src/mpc-hc/Ifo.cpp
@@ -77,11 +77,11 @@ uint32_t get4bytes(const BYTE* buf)
// VMG files
-#define OFF_VMGM_PGCI_UT(buf) get4bytes (buf + 200)
+#define OFF_VMGM_PGCI_UT(buf) get4bytes (buf + 0xC8)
// VTS files
-#define OFF_VTSM_PGCI_UT(buf) get4bytes (buf + 208)
-#define OFF_VTS_PGCIT(buf) get4bytes (buf + 204)
+#define OFF_VTSM_PGCI_UT(buf) get4bytes (buf + 0xD0)
+#define OFF_VTS_PGCIT(buf) get4bytes (buf + 0xCC)
CIfo::CIfo()
@@ -187,26 +187,48 @@ bool CIfo::IsVMG()
bool CIfo::OpenFile(LPCTSTR strFile)
{
bool bRet = false;
- HANDLE hFile;
- LARGE_INTEGER size;
- hFile = Real_CreateFileW((LPTSTR) strFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
- ASSERT(hFile != INVALID_HANDLE_VALUE);
-
- if (hFile != INVALID_HANDLE_VALUE && GetFileSizeEx(hFile, &size) &&
- size.QuadPart <= 0x800000) { // max size of the ifo file = 8 MB (taken with reserve. need a more correct info)
- m_pBuffer = DEBUG_NEW BYTE [size.QuadPart];
- ReadFile(hFile, m_pBuffer, size.QuadPart, &m_dwSize, nullptr);
- CloseHandle(hFile);
-
- if (IsVTS() && (OFF_VTSM_PGCI_UT(m_pBuffer) != 0)) {
- m_pPGCI = (ifo_hdr_t*)(m_pBuffer + OFF_VTSM_PGCI_UT(m_pBuffer) * DVD_VIDEO_LB_LEN);
- m_pPGCIT = (ifo_hdr_t*)(m_pBuffer + OFF_VTS_PGCIT(m_pBuffer) * DVD_VIDEO_LB_LEN);
- } else if (IsVMG() && (OFF_VMGM_PGCI_UT(m_pBuffer) != 0)) {
- m_pPGCI = (ifo_hdr_t*)(m_pBuffer + OFF_VMGM_PGCI_UT(m_pBuffer) * DVD_VIDEO_LB_LEN);
+ HANDLE hFile = Real_CreateFileW(strFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
+ if (hFile != INVALID_HANDLE_VALUE) {
+ LARGE_INTEGER size;
+ // min size of the ifo file comes from dvd sector size,
+ // max size we allow is 8 MB (taken with reserve),
+ // also the file size must a multiple of dvd sector size
+ if (GetFileSizeEx(hFile, &size) && (size.QuadPart >= DVD_VIDEO_LB_LEN) &&
+ (size.QuadPart <= 0x800000) && !(size.QuadPart % DVD_VIDEO_LB_LEN)) {
+ ASSERT(!m_pBuffer);
+ m_pBuffer = DEBUG_NEW BYTE [(size_t)size.QuadPart];
+ if (ReadFile(hFile, m_pBuffer, (DWORD)size.QuadPart, &m_dwSize, nullptr)) {
+ ASSERT(!m_pPGCI);
+ ASSERT(!m_pPGCIT);
+ uint32_t sector, sectorCount = (uint32_t)size.QuadPart / DVD_VIDEO_LB_LEN;
+ if (IsVTS()) {
+ sector = OFF_VTSM_PGCI_UT(m_pBuffer);
+ if (sector && (sector < sectorCount)) {
+ m_pPGCI = (ifo_hdr_t*)(m_pBuffer + sector * DVD_VIDEO_LB_LEN);
+ } else {
+ TRACE(_T("IFO: Missing or invalid VTSM_PGCI_UT sector"));
+ }
+ sector = OFF_VTS_PGCIT(m_pBuffer);
+ if (sector && (sector < sectorCount)) {
+ m_pPGCIT = (ifo_hdr_t*)(m_pBuffer + sector * DVD_VIDEO_LB_LEN);
+ } else {
+ TRACE(_T("IFO: Missing or invalid VTS_PGCI sector"));
+ }
+ } else if (IsVMG()) {
+ sector = OFF_VMGM_PGCI_UT(m_pBuffer);
+ if (sector && (sector < sectorCount)) {
+ m_pPGCI = (ifo_hdr_t*)(m_pBuffer + sector * DVD_VIDEO_LB_LEN);
+ } else {
+ TRACE(_T("IFO: Missing or invalid VTSM_PGCI_UT sector"));
+ }
+ }
+ bRet = (m_pPGCI != nullptr);
+ }
}
-
- bRet = (m_pPGCI != nullptr);
+ CloseHandle(hFile);
+ } else {
+ ASSERT(FALSE);
}
return bRet;