MCPcopy Create free account
hub / github.com/BYVoid/OpenCC / NewFromFile

Method NewFromFile

src/DartsDict.cpp:216–324  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

214}
215
216DartsDictPtr DartsDict::NewFromFile(FILE* fp) {
217 DartsDictPtr dict(new DartsDict());
218 auto internal = dict->internal;
219
220 size_t headerLen = strlen(OCDHEADER);
221 std::vector<char> headerBuffer(headerLen);
222 size_t bytesRead = fread(headerBuffer.data(), sizeof(char), headerLen, fp);
223 if (bytesRead != headerLen || memcmp(headerBuffer.data(), OCDHEADER, headerLen) != 0) {
224 throw InvalidFormat("Invalid OpenCC dictionary header");
225 }
226
227 // Measure remaining bytes for bounds checking
228 long currentOffset = ftell(fp);
229 fseek(fp, 0L, SEEK_END);
230 long fileEnd = ftell(fp);
231 fseek(fp, currentOffset, SEEK_SET);
232 size_t remainingSize =
233 (fileEnd > currentOffset)
234 ? static_cast<size_t>(fileEnd - currentOffset)
235 : 0;
236
237 // Detect 32-bit vs 64-bit unit size by reading 8 bytes and checking
238 // whether bytes [4..7] are all zero.
239 // - Old 64-bit build: dartsSize field is uint64_t (8 bytes); high 32 bits
240 // are zero for any realistic file size → bytes [4..7] == 0.
241 // - 32-bit build (new or old): dartsSize field is uint32_t (4 bytes);
242 // bytes [4..7] are the first 4 bytes of the darts array (non-zero for
243 // any valid array whose root unit has a non-zero offset).
244 uint8_t probe[8];
245 if (fread(probe, 1, 8, fp) != 8) {
246 throw InvalidFormat("Invalid OpenCC dictionary header (dartsSize)");
247 }
248 bool is64bit =
249 (probe[4] == 0 && probe[5] == 0 && probe[6] == 0 && probe[7] == 0);
250
251 if (is64bit) {
252 uint64_t dartsSize64;
253 memcpy(&dartsSize64, probe, 8);
254 size_t dartsSize = static_cast<size_t>(dartsSize64);
255 if (dartsSize > remainingSize) {
256 throw InvalidFormat(
257 "Invalid OpenCC dictionary (dartsSize exceeds file size)");
258 }
259 if (dartsSize % sizeof(LegacyUnit64) != 0) {
260 throw InvalidFormat("Invalid legacy OCD dictionary unit alignment");
261 }
262 std::unique_ptr<void, decltype(&free)> buffer(malloc(dartsSize), free);
263 if (!buffer) {
264 throw std::bad_alloc();
265 }
266 bytesRead = fread(buffer.get(), 1, dartsSize, fp);
267 if (bytesRead != dartsSize) {
268 throw InvalidFormat("Invalid legacy OCD dictionary size mismatch");
269 }
270
271 BinaryDictPtr binary = BinaryDict::NewFromFile(fp);
272
273 internal->buffer = buffer.release();

Callers

nothing calls this directly

Calls 13

freadFunction · 0.85
NewFromFileFunction · 0.85
moveFunction · 0.85
ValidateLegacy64Function · 0.85
releaseMethod · 0.80
unit_sizeMethod · 0.80
set_arrayMethod · 0.80
validateMethod · 0.80
dataMethod · 0.45
getMethod · 0.45
GetLexiconMethod · 0.45
KeyMaxLengthMethod · 0.45

Tested by

no test coverage detected