⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpzinflate.c

📁 著名的加密软件的应用于电子邮件中
💻 C
📖 第 1 页 / 共 4 页
字号:

getlitlength2:
		/* Method 2: We don't even have 20 bits available - do it bit-by-bit. */
		t = tl + ((unsigned)b & ml);
		/*
		* See if higher-order bits we're missing actually matter.
		* We don't have to try to fill the bit buffer, because we only get
		* here if s (number of following input bytes) is supposed to be zero.
		*/
		if (k < (unsigned)t->bits) {
		ctx->outptr = w;
		ctx->substate = 0;
		SAVEBITBUFEMPTY;
		return 1;
		}
		/* Actually, s is set (see GETBITSOR comment) to -1, so reset it */
		s = 0;
		if ((e = t->exop) < 0) {
		do {
		if (e == -128)
		return INFERR_BADINPUT;
		DUMPBITS(t->bits);
		e = -e;
		t = t->next;
		case 1:
		NEEDBITS2(e, t[(unsigned)b & mask[e]].bits,
		ctx->t=t; ctx->outptr=w; ctx->numbits=e; ctx->substate=1)
		t += (unsigned)b & mask[e];
		} while ((e = t->exop) < 0);
		}
		DUMPBITS(t->bits);
		if (e & 16) { /* then it's a literal */
		*w++ = (unsigned char)t->base;
		if (--r == 0) {
		/* We just filled the output buffer - return */
		SAVEBITBUF;
		ctx->outptr = w;
		ctx->substate = 0; /* Restart at top of loop */
		return 2; /* Output buffer full */
		}
		continue;
		}

		if (e & 32) /* EOB */
		break; /* Leave infinite loop */

		/*FALLTHROUGH*/
		case 2:
		NEEDBITS(e, ctx->t = t; ctx->outptr=w; ctx->numbits=e; ctx->substate=2)

gotlength:

/* All data is available - compute total length of block to copy */
n = t->base + ((unsigned)b & mask[e]);
DUMPBITS((unsigned)e);

	/*FALLTHROUGH*/
case 3:
/* Get distance code - 15 is maximum code size */
GETBITSOR(15, goto getdistance2)
t = td + ((unsigned)b & md);
/* Negative t->exop means there's a subtable of 2^-e entries */
		if ((e = t->exop) < 0) {
		do {
		if (e == -128)
		return INFERR_BADINPUT;	/* Invalid code (static table case) */
		DUMPBITS(t->bits);
		e = -e;
		t = t->next + ((unsigned)b & mask[e]);
		} while ((e = t->exop) < 0);
		}
		goto gotdistance;

getdistance2:
/* We don't even have 15 bits available - do it bit-by-bit. */
t = td + ((unsigned)b & md);
/*
* See if higher-order bits we're missing actually matter.
* We don't have to try to fill the bit buffer, because we only get
* here if s (number of following input bytes) is supposed to be zero.
	*/
if (k < (unsigned)t->bits) {
ctx->outptr = w;
ctx->copylen = n;
ctx->substate = 3;
SAVEBITBUFEMPTY;
return 1;
}
/* Actually (see GETBITSOR comment) s is set to -1, so reset it */
s = 0;
/* Negative t->exop means there's a subtable of 2^-e entries */
		if ((e = t->exop) < 0) {
		do {
		if (e == -128)
		return INFERR_BADINPUT;	/* Invalid code (static table case) */
		DUMPBITS(t->bits);
		e = -e;
		t = t->next;
	case 4:
NEEDBITS2(e, t[(unsigned)b & mask[e]].bits, ctx->t=t; ctx->outptr=w;
ctx->copylen = n; ctx->numbits=e; ctx->substate=4)
		t += (unsigned)b & mask[e];
		} while ((e = t->exop) < 0);
		}

gotdistance:
/* All data is available - compute the base distance */
DUMPBITS(t->bits);
d = t->base;
/*FALLTHROUGH*/
case 5:
/* e is number of bits extra following distance code (0..13) */
NEEDBITS(e, ctx->outptr=w; ctx->copylen=n; ctx->distbase=d;
	ctx->numbits=e; ctx->substate=5)
d += ((unsigned)b & mask[e]);
DUMPBITS((unsigned)e);

#if WSIZE < 32768
		if (d > ctx->slidelen)
		return INFERR_BADINPUT;
	#endif

		/* do the copy, with handling for wrapping around end of buffer */
		if ((unsigned)(w - ctx->slide) >= d && w + n < ctx->slideend - 2) {
		/* Simple case - neither source nor dest cross end of buffer */
		p = w - d;
		r -= n + 2;
		*w++ = *p++;
		*w++ = *p++;
		do {
		*w++ = *p++;
		} while (--n);
		} else {
		n += 2; /* # of bytes to copy */
		p = ctx->slide + ((w - ctx->slide - d) & ctx->slidemask); /* src */
		do {
		/* Set e to number of bytes we can copy at once */
		n -= (e = (unsigned)(e = ctx->slideend - (p>w?p:w)) > n ? n : e);
		r -= e;
		do {
		*w++ = *p++;
		} while (--e);
		if (r == 0) { /* Did we just write everything we could? */
		SAVEBITBUF;
		ctx->outptr = w;
		ctx->copylen = n;
		ctx->distbase = d; /* Save copy distance to recompute p */
		ctx->substate = 6;
		return 2; /* Need more output space */
case 6:
		p = ctx->slide + ((w - ctx->slide - d) & ctx->slidemask);
		}
		if (p == ctx->slideend)
		p = ctx->slide;
		} while (n);
	}
} /* for(;;) */
} /* switch(ctx->subcase) */

EOB:
/* End of Block */
ctx->outptr = w;
SAVEBITBUF;
ctx->state = STATE_START;
ctx->substate = 0;

if (tl && tl != fixed_tl)
huft_free(tl);
if (td && td != fixed_td)
huft_free(td);
ctx->tree1 = 0;
ctx->tree2 = 0;

return 0;
}


/*
* Start state - read 3 bits, which are last block flag (set to 1 on
* last block), and 2 bits of block type.
*/
static int
infStart(struct InflateContext *ctx)
	{
		ulg b;
		unsigned k;
		int s;
		unsigned char const *g;
		int retval = 0;

		if (ctx->lastblock) {
		 ctx->state = STATE_DONE;
		 return 0;
		}

		LOADBITBUF;
		NEEDBITS(3, (void)0);

		ctx->lastblock = (int)(b & 1);
		DUMPBITS(1);

		switch(b & 3) {
		case 0: /* Stored */
		 ctx->state = STATE_STOREDLEN;
		 break;
		case 1: /* Static - build fixed trees and start decoding */
			retval = infFixedTree();
			ctx->tree1 = fixed_tl;
			ctx->bits1 = fixed_bl;
			ctx->tree2 = fixed_td;
			ctx->bits2 = fixed_bd;
			ctx->state = STATE_INFLATE;
			break;
		case 2: /* Dynamic */
		 ctx->state = STATE_DYN_HDR;
		 break;
		case 3: /* Illegal */
		 retval = INFERR_BADINPUT;
		 break;
		}

		DUMPBITS(2);
		SAVEBITBUF;

 ctx->substate = 0;
 return retval;
}

/*
* Get a pointer to available data in the output buffer
*/
unsigned char const *
infGetBytes(struct InflateContext *ctx, unsigned *len)
	{
		*len = ctx->outptr - ctx->readptr;
		return *len ? ctx->readptr : 0;
	}

/*
* Mark data in the output buffer as already read. We don't start
* accepting new data until the entire output buffer has been read,
* at which point the outptr is set back to the beginning of the
* buffer.
*/
void
infSkipBytes(struct InflateContext *ctx, unsigned len)
	{
		pgpAssert(len <= (unsigned)(ctx->outptr - ctx->readptr));

	   ctx->readptr += len;

/* If at end of buffer, recirculate */
if (ctx->readptr == ctx->slideend) {
		pgpAssert(ctx->outptr == ctx->slideend);
		ctx->readptr = ctx->outptr = ctx->slide;
	}
}


/*
 * Returns number of bytes written.
 * *error < 0 on error, == 0 if no error (done with input or output full)
 */
size_t
infWrite(struct InflateContext *ctx, unsigned char const *buf, size_t len,
int *error)
{
int i;

if (ctx->outptr == ctx->slideend) {
 *error = (ctx->state == STATE_STOP) ? 0 : ctx->substate;
 return 0; /* Out of output space! */
}

		ctx->inptr = buf;
		/* Decompression code can't handle more than INT_MAX bytes at a time */
		ctx->inlen = len > INT_MAX ? INT_MAX : (int)len;

		do {
		 switch(ctx->state) {
		 case STATE_START:
				i = infStart(ctx);
				break;
				case STATE_STOREDLEN:
				i = infStoredLen(ctx);
				break;
				case STATE_STORED:
				i = infStored(ctx);
				break;
				case STATE_DYN_HDR:
				i = infDynHdr(ctx);
				break;
				case STATE_DYN_BITS:
				i = infDynBits(ctx);
				break;
				case STATE_DYN_TREE:
				i = infDynTree(ctx);
				break;
				case STATE_INFLATE:
				i = infInflate(ctx);
				break;
				case STATE_DONE:
				if (ctx->inlen || ctx->bufbits > 7)
				 i = INFERR_LONG;
#if STRICT
				else if (ctx->bitbuffer & mask[ctx->bufbits])
				i = INFERR_BADINPUT; /* Unused bits != 0 */
	#endif
				else
					i = 2; /* Read output, please */
				break;
				case STATE_STOP:
				i = ctx->substate;
				break;
				default:
				pgpAssert(i=0); /* To shut up compiler warnings */
			}
		} while (i == 0);

if (i < 0) {
ctx->state = STATE_STOP;
ctx->substate = i;
*error = i;
} else {
*error = 0;
}

pgpAssert((size_t)(ctx->inptr - buf) == len - ctx->inlen);
return (size_t)(ctx->inptr - buf); /* Bytes read */
}

/*
* Signal EOF, detecting truncated messages.
* If another error has been reported, this just repeats it.
*/
/* New version, hopefully useful. */
int
infEOF(struct InflateContext *ctx)
{
/* If processing is halted, just return the last error (if any) */
if (ctx->state == STATE_STOP)
 return ctx->substate;

/* If expecting still more input, we're short */
if (ctx->state != STATE_DONE)
 return INFERR_SHORT;

/* Otherwise, all is well. */
 return 0;
}

struct InflateContext *
infAlloc(void)
{
struct InflateContext *ctx;
unsigned char *slide;

slide = (unsigned char *)pgpMemAlloc(WSIZE);
if (!slide)
 return 0;
ctx = (struct InflateContext *)pgpMemAlloc(sizeof(*ctx));
if (!ctx) {
 pgpMemFree(slide);
 return 0;
}
ctx->slide = slide;
ctx->slideend = slide+WSIZE;
ctx->slidelen = WSIZE;
ctx->slidemask = WSIZE-1;

ctx->outptr = slide;
ctx->readptr = slide;

ctx->state = STATE_START;
ctx->substate = 0;
ctx->inlen = 0;
ctx->bitbuffer = 0;
ctx->bufbits = 0;
ctx->lastblock = 0;

ctx->tree1 = 0;
ctx->tree2 = 0;

return ctx;
}

void
infFree(struct InflateContext *ctx)
	{
		if (ctx->tree1 && ctx->tree1 != fixed_tl)
		 huft_free(ctx->tree1);
		if (ctx->tree2 && ctx->tree2 != fixed_td)
		 huft_free(ctx->tree2);

		if (ctx->slide) {
#if SECURE
		memset(ctx->slide, 0, ctx->slidelen);
#endif
  pgpMemFree(ctx->slide);
 }
#if SECURE
 memset(ctx, 0, sizeof(*ctx));
#endif
 pgpMemFree(ctx);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -