| 460 | } |
| 461 | |
| 462 | UCHAR* Compressor::unpack(ULONG inLength, const UCHAR* input, |
| 463 | ULONG outLength, UCHAR* output) |
| 464 | { |
| 465 | /************************************** |
| 466 | * |
| 467 | * Decompress a compressed string into a buffer. |
| 468 | * Return the address where the output stopped. |
| 469 | * |
| 470 | **************************************/ |
| 471 | const auto end = input + inLength; |
| 472 | const auto output_end = output + outLength; |
| 473 | |
| 474 | while (input < end) |
| 475 | { |
| 476 | const int length = (signed char) *input++; |
| 477 | |
| 478 | if (length < 0) |
| 479 | { |
| 480 | auto zipLength = (unsigned) -length; |
| 481 | |
| 482 | if (length == -1) |
| 483 | { |
| 484 | zipLength = get_short(input); |
| 485 | input += sizeof(USHORT); |
| 486 | } |
| 487 | else if (length == -2) |
| 488 | { |
| 489 | zipLength = get_long(input); |
| 490 | input += sizeof(ULONG); |
| 491 | } |
| 492 | |
| 493 | if (input >= end || output + zipLength > output_end) |
| 494 | BUGCHECK(179); // msg 179 decompression overran buffer |
| 495 | |
| 496 | const auto c = *input++; |
| 497 | memset(output, c, zipLength); |
| 498 | output += zipLength; |
| 499 | } |
| 500 | else |
| 501 | { |
| 502 | if (input + length > end || output + length > output_end) |
| 503 | BUGCHECK(179); // msg 179 decompression overran buffer |
| 504 | |
| 505 | memcpy(output, input, length); |
| 506 | output += length; |
| 507 | input += length; |
| 508 | } |
| 509 | } |
| 510 | |
| 511 | if (output > output_end) |
| 512 | BUGCHECK(179); // msg 179 decompression overran buffer |
| 513 | |
| 514 | return output; |
| 515 | } |
| 516 | |
| 517 | ULONG Difference::apply(ULONG diffLength, ULONG outLength, UCHAR* const output) |
| 518 | { |