| 108 | } __packed; |
| 109 | |
| 110 | size_t ulz4fn(const void *src, size_t srcn, void *dst, size_t dstn) |
| 111 | { |
| 112 | const void *in = src; |
| 113 | void *out = dst; |
| 114 | size_t out_size = 0; |
| 115 | int has_block_checksum; |
| 116 | |
| 117 | { /* With in-place decompression the header may become invalid later. */ |
| 118 | const struct lz4_frame_header *h = in; |
| 119 | |
| 120 | if (srcn < sizeof(*h) + sizeof(uint64_t) + sizeof(uint8_t)) |
| 121 | return 0; /* input overrun */ |
| 122 | |
| 123 | /* We assume there's always only a single, standard frame. */ |
| 124 | if (LZ4_readLE32(&h->magic) != LZ4F_MAGICNUMBER |
| 125 | || (h->flags & VERSION) != (1 << VERSION_SHIFT)) |
| 126 | return 0; /* unknown format */ |
| 127 | if ((h->flags & RESERVED0) || (h->block_descriptor & RESERVED1_2)) |
| 128 | return 0; /* reserved must be zero */ |
| 129 | if (!(h->flags & INDEPENDENT_BLOCKS)) |
| 130 | return 0; /* we don't support block dependency */ |
| 131 | has_block_checksum = h->flags & HAS_BLOCK_CHECKSUM; |
| 132 | |
| 133 | in += sizeof(*h); |
| 134 | if (h->flags & HAS_CONTENT_SIZE) |
| 135 | in += sizeof(uint64_t); |
| 136 | in += sizeof(uint8_t); |
| 137 | } |
| 138 | |
| 139 | while (1) { |
| 140 | if ((size_t)(in - src) + sizeof(struct lz4_block_header) > srcn) |
| 141 | break; /* input overrun */ |
| 142 | |
| 143 | struct lz4_block_header b = { |
| 144 | .raw = LZ4_readLE32((const uint32_t *)in) |
| 145 | }; |
| 146 | in += sizeof(struct lz4_block_header); |
| 147 | |
| 148 | if ((size_t)(in - src) + (b.raw & BH_SIZE) > srcn) |
| 149 | break; /* input overrun */ |
| 150 | |
| 151 | if (!(b.raw & BH_SIZE)) { |
| 152 | out_size = out - dst; |
| 153 | break; /* decompression successful */ |
| 154 | } |
| 155 | |
| 156 | if (b.raw & NOT_COMPRESSED) { |
| 157 | size_t size = MIN((uintptr_t)(b.raw & BH_SIZE), (uintptr_t)dst |
| 158 | + dstn - (uintptr_t)out); |
| 159 | memcpy(out, in, size); |
| 160 | if (size < (b.raw & BH_SIZE)) |
| 161 | break; /* output overrun */ |
| 162 | out += size; |
| 163 | } else { |
| 164 | /* constant folding essential, do not touch params! */ |
| 165 | int ret = LZ4_decompress_generic(in, out, (b.raw & BH_SIZE), |
| 166 | dst + dstn - out, endOnInputSize, |
| 167 | full, 0, noDict, out, NULL, 0); |
no test coverage detected