| 389 | } |
| 390 | |
| 391 | static unsigned int PKWAREAPI Expand(TDcmpStruct * pWork) |
| 392 | { |
| 393 | unsigned int next_literal; // Literal decoded from the compressed data |
| 394 | unsigned int result; // Value to be returned |
| 395 | unsigned int copyBytes; // Number of bytes to copy to the output buffer |
| 396 | |
| 397 | pWork->outputPos = 0x1000; // Initialize output buffer position |
| 398 | |
| 399 | // Decode the next literal from the input data. |
| 400 | // The returned literal can either be an uncompressed byte (next_literal < 0x100) |
| 401 | // or an encoded length of the repeating byte sequence that |
| 402 | // is to be copied to the current buffer position |
| 403 | while((result = next_literal = DecodeLit(pWork)) < 0x305) |
| 404 | { |
| 405 | // If the literal is greater than 0x100, it holds length |
| 406 | // of repeating byte sequence |
| 407 | // literal of 0x100 means repeating sequence of 0x2 bytes |
| 408 | // literal of 0x101 means repeating sequence of 0x3 bytes |
| 409 | // ... |
| 410 | // literal of 0x305 means repeating sequence of 0x207 bytes |
| 411 | if(next_literal >= 0x100) |
| 412 | { |
| 413 | unsigned char * source; |
| 414 | unsigned char * target; |
| 415 | unsigned int rep_length; // Length of the repetition, in bytes |
| 416 | unsigned int minus_dist; // Backward distance to the repetition, relative to the current buffer position |
| 417 | |
| 418 | // Get the length of the repeating sequence. |
| 419 | // Note that the repeating block may overlap the current output position, |
| 420 | // for example if there was a sequence of equal bytes |
| 421 | rep_length = next_literal - 0xFE; |
| 422 | |
| 423 | // Get backward distance to the repetition |
| 424 | if((minus_dist = DecodeDist(pWork, rep_length)) == 0) |
| 425 | { |
| 426 | result = 0x306; |
| 427 | break; |
| 428 | } |
| 429 | |
| 430 | // Target and source pointer |
| 431 | target = &pWork->out_buff[pWork->outputPos]; |
| 432 | source = target - minus_dist; |
| 433 | |
| 434 | // Update buffer output position |
| 435 | pWork->outputPos += rep_length; |
| 436 | |
| 437 | // Copy the repeating sequence |
| 438 | while(rep_length-- > 0) |
| 439 | *target++ = *source++; |
| 440 | } |
| 441 | else |
| 442 | { |
| 443 | pWork->out_buff[pWork->outputPos++] = (unsigned char)next_literal; |
| 444 | } |
| 445 | |
| 446 | // Flush the output buffer, if number of extracted bytes has reached the end |
| 447 | if(pWork->outputPos >= 0x2000) |
| 448 | { |
no test coverage detected