| 104 | } |
| 105 | |
| 106 | int MPPC_Decompress(u_char **src, u_char **dst, u_long *srcCnt, u_long *dstCnt, char *history, int flags) |
| 107 | { |
| 108 | struct MPPC_decomp_state *state = (struct MPPC_decomp_state*)history; |
| 109 | uint32_t olen, off, len, bits, val, sig, i, l; |
| 110 | uint8_t *hist, *s; |
| 111 | u_char *isrc = *src; |
| 112 | int rtn = MPPC_OK; |
| 113 | |
| 114 | if ((flags & MPPC_RESTART_HISTORY) != 0) { |
| 115 | memcpy(state->hist, state->hist + MPPE_HIST_LEN, MPPE_HIST_LEN); |
| 116 | state->histptr = MPPE_HIST_LEN; |
| 117 | } |
| 118 | |
| 119 | hist = state->hist + state->histptr; |
| 120 | olen = len = i = 0; |
| 121 | l = 8; |
| 122 | bits = *srcCnt * 8; |
| 123 | while (bits >= 8) { |
| 124 | val = getbyte(isrc, i++, l); |
| 125 | if (val < 0x80) { /* literal byte < 0x80 */ |
| 126 | if (state->histptr < 2*MPPE_HIST_LEN) { |
| 127 | /* Copy uncompressed byte to the history. */ |
| 128 | (state->hist)[(state->histptr)++] = (uint8_t) val; |
| 129 | } else { |
| 130 | /* Buffer overflow; drop packet. */ |
| 131 | rtn &= ~MPPC_OK; |
| 132 | return rtn; |
| 133 | } |
| 134 | olen++; |
| 135 | bits -= 8; |
| 136 | continue; |
| 137 | } |
| 138 | |
| 139 | sig = val & 0xc0; |
| 140 | if (sig == 0x80) { /* literal byte >= 0x80 */ |
| 141 | if (state->histptr < 2*MPPE_HIST_LEN) { |
| 142 | /* Copy uncompressed byte to the history. */ |
| 143 | (state->hist)[(state->histptr)++] = |
| 144 | (uint8_t) (0x80|((val&0x3f)<<1)|getbits(isrc, 1 , &i ,&l)); |
| 145 | } else { |
| 146 | /* buffer overflow; drop packet */ |
| 147 | rtn &= ~MPPC_OK; |
| 148 | return (rtn); |
| 149 | } |
| 150 | olen++; |
| 151 | bits -= 9; |
| 152 | continue; |
| 153 | } |
| 154 | |
| 155 | /* Not a literal byte so it must be an (offset,length) pair */ |
| 156 | /* decode offset */ |
| 157 | sig = val & 0xf0; |
| 158 | if (sig == 0xf0) { /* 10-bit offset; 0 <= offset < 64 */ |
| 159 | off = (((val&0x0f)<<2)|getbits(isrc, 2 , &i ,&l)); |
| 160 | bits -= 10; |
| 161 | } else { |
| 162 | if (sig == 0xe0) { /* 12-bit offset; 64 <= offset < 320 */ |
| 163 | off = ((((val&0x0f)<<4)|getbits(isrc, 4 , &i ,&l))+64); |
no test coverage detected