Bug Summary

File:Source/Core/DiscIO/Src/FileHandlerARC.cpp
Location:line 175, column 4
Description:Dereference of null pointer

Annotated Source Code

1// Copyright 2013 Dolphin Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5#include "Common.h"
6
7#include "FileHandlerARC.h"
8#include "StringUtil.h"
9#include "Blob.h"
10#include "FileUtil.h"
11
12#define ARC_ID0x55aa382d 0x55aa382d
13
14namespace DiscIO
15{
16CARCFile::CARCFile(const std::string& _rFilename)
17 : m_pBuffer(NULL__null)
18 , m_Initialized(false)
19{
20 DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rFilename.c_str());
21 if (pReader != NULL__null)
22 {
23 u64 FileSize = pReader->GetDataSize();
24 m_pBuffer = new u8[(u32)FileSize];
25 pReader->Read(0, FileSize, m_pBuffer);
26 delete pReader;
27
28 m_Initialized = ParseBuffer();
29 }
30}
31
32CARCFile::CARCFile(const std::string& _rFilename, u32 offset)
33 : m_pBuffer(NULL__null)
34 , m_Initialized(false)
35{
36 DiscIO::IBlobReader* pReader = DiscIO::CreateBlobReader(_rFilename.c_str());
37 if (pReader != NULL__null)
38 {
39 u64 FileSize = pReader->GetDataSize() - offset;
40 m_pBuffer = new u8[(u32)FileSize];
41 pReader->Read(offset, FileSize, m_pBuffer);
42 delete pReader;
43
44 m_Initialized = ParseBuffer();
45 }
46}
47
48CARCFile::CARCFile(const u8* _pBuffer, size_t _BufferSize)
49 : m_pBuffer(NULL__null)
50 , m_Initialized(false)
51{
52 m_pBuffer = new u8[_BufferSize];
53
54 if (m_pBuffer)
55 {
56 memcpy(m_pBuffer, _pBuffer, _BufferSize);
57 m_Initialized = ParseBuffer();
58 }
59}
60
61
62CARCFile::~CARCFile()
63{
64 delete [] m_pBuffer;
65}
66
67
68bool
69CARCFile::IsInitialized()
70{
71 return(m_Initialized);
72}
73
74
75size_t
76CARCFile::GetFileSize(const std::string& _rFullPath)
77{
78 if (!m_Initialized)
79 {
80 return(0);
81 }
82
83 const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
84
85 if (pFileInfo != NULL__null)
86 {
87 return((size_t) pFileInfo->m_FileSize);
88 }
89
90 return(0);
91}
92
93
94size_t
95CARCFile::ReadFile(const std::string& _rFullPath, u8* _pBuffer, size_t _MaxBufferSize)
96{
97 if (!m_Initialized)
98 {
99 return(0);
100 }
101
102 const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
103
104 if (pFileInfo == NULL__null)
105 {
106 return(0);
107 }
108
109 if (pFileInfo->m_FileSize > _MaxBufferSize)
110 {
111 return(0);
112 }
113
114 memcpy(_pBuffer, &m_pBuffer[pFileInfo->m_Offset], (size_t)pFileInfo->m_FileSize);
115 return((size_t) pFileInfo->m_FileSize);
116}
117
118
119bool
120CARCFile::ExportFile(const std::string& _rFullPath, const std::string& _rExportFilename)
121{
122 if (!m_Initialized)
123 {
124 return(false);
125 }
126
127 const SFileInfo* pFileInfo = FindFileInfo(_rFullPath);
128
129 if (pFileInfo == NULL__null)
130 {
131 return(false);
132 }
133
134 File::IOFile pFile(_rExportFilename, "wb");
135
136 return pFile.WriteBytes(&m_pBuffer[pFileInfo->m_Offset], (size_t) pFileInfo->m_FileSize);
137}
138
139
140bool
141CARCFile::ExportAllFiles(const std::string& _rFullPath)
142{
143 return(false);
144}
145
146
147bool
148CARCFile::ParseBuffer()
149{
150 // check ID
151 u32 ID = Common::swap32(*(u32*)(m_pBuffer));
152
153 if (ID != ARC_ID0x55aa382d)
1
Assuming 'ID' is equal to 1437218861
2
Taking false branch
154 return false;
155
156 // read header
157 u32 FSTOffset = Common::swap32(*(u32*)(m_pBuffer + 0x4));
158 //u32 FSTSize = Common::swap32(*(u32*)(m_pBuffer + 0x8));
159 //u32 FileOffset = Common::swap32(*(u32*)(m_pBuffer + 0xC));
160
161 // read all file infos
162 SFileInfo Root;
163 Root.m_NameOffset = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x0));
164 Root.m_Offset = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x4));
165 Root.m_FileSize = Common::swap32(*(u32*)(m_pBuffer + FSTOffset + 0x8));
166
167 if (Root.IsDirectory())
3
Taking true branch
168 {
169 m_FileInfoVector.resize((unsigned int)Root.m_FileSize);
170 const char* szNameTable = (char*)(m_pBuffer + FSTOffset);
171
172 for (size_t i = 0; i < m_FileInfoVector.size(); i++)
4
Loop condition is true. Entering loop body
173 {
174 u8* Offset = m_pBuffer + FSTOffset + (i * 0xC);
175 m_FileInfoVector[i].m_NameOffset = Common::swap32(*(u32*)(Offset + 0x0));
5
Dereference of null pointer
176 m_FileInfoVector[i].m_Offset = Common::swap32(*(u32*)(Offset + 0x4));
177 m_FileInfoVector[i].m_FileSize = Common::swap32(*(u32*)(Offset + 0x8));
178
179 szNameTable += 0xC;
180 }
181
182 BuildFilenames(1, m_FileInfoVector.size(), NULL__null, szNameTable);
183 }
184
185 return(true);
186}
187
188
189size_t
190CARCFile::BuildFilenames(const size_t _FirstIndex, const size_t _LastIndex, const char* _szDirectory, const char* _szNameTable)
191{
192 size_t CurrentIndex = _FirstIndex;
193
194 while (CurrentIndex < _LastIndex)
195 {
196 SFileInfo& rFileInfo = m_FileInfoVector[CurrentIndex];
197 int uOffset = rFileInfo.m_NameOffset & 0xFFFFFF;
198
199 // check next index
200 if (rFileInfo.IsDirectory())
201 {
202 // this is a directory, build up the new szDirectory
203 if (_szDirectory != NULL__null)
204 {
205 sprintf(rFileInfo.m_FullPath, "%s%s/", _szDirectory, &_szNameTable[uOffset]);
206 }
207 else
208 {
209 sprintf(rFileInfo.m_FullPath, "%s/", &_szNameTable[uOffset]);
210 }
211
212 CurrentIndex = BuildFilenames(CurrentIndex + 1, (size_t) rFileInfo.m_FileSize, rFileInfo.m_FullPath, _szNameTable);
213 }
214 else
215 {
216 // this is a filename
217 if (_szDirectory != NULL__null)
218 {
219 sprintf(rFileInfo.m_FullPath, "%s%s", _szDirectory, &_szNameTable[uOffset]);
220 }
221 else
222 {
223 sprintf(rFileInfo.m_FullPath, "%s", &_szNameTable[uOffset]);
224 }
225
226 CurrentIndex++;
227 }
228 }
229
230 return(CurrentIndex);
231}
232
233
234const SFileInfo*
235CARCFile::FindFileInfo(std::string _rFullPath) const
236{
237 for (size_t i = 0; i < m_FileInfoVector.size(); i++)
238 {
239 if (!strcasecmp(m_FileInfoVector[i].m_FullPath, _rFullPath.c_str()))
240 {
241 return(&m_FileInfoVector[i]);
242 }
243 }
244
245 return(NULL__null);
246}
247} // namespace