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

📄 native.c

📁 在x86平台上运行不可信任代码的sandbox。
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <unistd.h>#include <errno.h>#include <vxa/vxa.h>#include <vxa/codec.h>#include "zlib.h"#define BUFSIZE (64*1024)char vxacodec_name[] = "zlib";// Defined in dzlib-bin.c, generated from dzlib by bin2c.plextern const uint8_t vxa_dzlib_data[];extern const int vxa_dzlib_length;// Translate a zlib return code into a VXA return codestatic int xlrc(vxaio *io, z_stream *zs, int zrc){	switch (zrc) {	case Z_OK:		return VXA_RC_OK;	case Z_STREAM_END:		return vxa_error(io, VXA_RC_EOF, "end of file");	case Z_MEM_ERROR:		return vxa_error(io, VXA_RC_NO_MEMORY, "out of memory in zlib");	case Z_STREAM_ERROR:		return vxa_error(io, VXA_RC_INVALID_ARG,				"zlib detected invalid argument");	default:		if (zs->msg)			return vxa_error(io, VXA_RC_UNKNOWN,					"zlib error: %s", zs->msg);		else			return vxa_error(io, VXA_RC_UNKNOWN,					"unknown zlib error: %d", zrc);	}}int vxacodec_init(struct vxacodec *c, struct vxaio *io){	c->decoder = vxa_dzlib_data;	c->decodersize = vxa_dzlib_length;}int vxacodec_encode(vxacodec *c, vxaio *io){	io->method = VXA_M_DEFLATE;	z_stream zs;	memset(&zs, 0, sizeof(zs));	// Allocate input and output data buffers	char *iobuf = malloc(BUFSIZE*2);	if (iobuf == NULL) {		return vxa_error(io, VXA_RC_NO_MEMORY,			"No memory for zlib I/O buffers");	}	char *inbuf = iobuf;	char *outbuf = iobuf + BUFSIZE;	// Just encode input data into a raw deflate stream,	// leaving the client to do any wrapping (e.g., ZIP)	int zrc = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED,			-15, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);	if (zrc != Z_OK) {	    enderr:		free(iobuf);		return xlrc(io, &zs, zrc);	}	// Compress the input stream	ssize_t inlen;	while ((inlen = io->readf(io, inbuf, BUFSIZE)) > 0) {		// Compress this input block		zs.next_in = inbuf;		zs.avail_in = inlen;		do {			zs.next_out = outbuf;			zs.avail_out = BUFSIZE;			if ((zrc = deflate(&zs, 0)) != Z_OK) {				zerr:				deflateEnd(&zs);				free(iobuf);				return xlrc(io, &zs, zrc);			}			// Write any output the decompressor produced			ssize_t outlen = io->writef(io, outbuf,						BUFSIZE - zs.avail_out);			if (outlen < 0)				goto ioerr;			// Continue decompressing the input block until done		} while (zs.avail_in > 0);	}	if (inlen < 0) {		ioerr:		deflateEnd(&zs);		free(iobuf);		return io->errcode;	}	// Flush the output	zs.avail_in = 0;	int done = 0;	do {		zs.next_out = outbuf;		zs.avail_out = BUFSIZE;		zrc = deflate(&zs, Z_FINISH);		if (zrc == Z_STREAM_END)			done = 1;		else if (zrc != Z_OK)			goto zerr;		// Write compressor output		ssize_t outlen = io->writef(io, outbuf,					BUFSIZE - zs.avail_out);		if (outlen < 0)			goto ioerr;	} while (!done);	zrc = deflateEnd(&zs);	if (zrc != Z_OK)		goto enderr;	free(iobuf);	return 0;}int vxacodec_decode(vxacodec *c, vxaio *io){	// Decode gzip format or raw deflate stream as appropriate	int wbits;	switch (io->method) {	case VXA_M_GZIP:		wbits = 16+15;	// Decode GZIP format stream		break;	case VXA_M_DEFLATE:		wbits = -15;	// Decode raw deflate stream		break;	default:		return vxa_error(io, VXA_RC_WRONG_FORMAT,				"zlib: unsupported method code %08x",				io->method);	}	z_stream zs;	memset(&zs, 0, sizeof(zs));	// Allocate input and output data buffers	char *iobuf = malloc(BUFSIZE*2);	if (iobuf == NULL) {		return vxa_error(io, VXA_RC_NO_MEMORY,			"No memory for zlib I/O buffers");	}	char *inbuf = iobuf;	char *outbuf = iobuf + BUFSIZE;	// Initialize the decompressor in the appropriate mode.	int zrc = inflateInit2(&zs, wbits);	if (zrc != Z_OK) {		enderr:		free(iobuf);		return xlrc(io, &zs, zrc);	}	// Deompress the input stream	int done = 0;	do {		// Read a block of input data		ssize_t inlen = io->readf(io, inbuf, BUFSIZE);		if (inlen == 0)			vxa_error(io, VXA_RC_CORRUPT_DATA,				"compressed input data truncated");		if (inlen <= 0) {			ioerr:			inflateEnd(&zs);			free(iobuf);			return io->errcode;		}		// Decompress this input block		zs.next_in = inbuf;		zs.avail_in = inlen;		do {			zs.next_out = outbuf;			zs.avail_out = BUFSIZE;			zrc = inflate(&zs, 0);			if (zrc == Z_STREAM_END)				done = 1;			else if (zrc != Z_OK) {				zerr:				inflateEnd(&zs);				free(iobuf);				return xlrc(io, &zs, zrc);			}			// Write any output the decompressor produced			ssize_t outlen = io->writef(io, outbuf,						BUFSIZE - zs.avail_out);			if (outlen < 0)				goto ioerr;			// Continue decompressing until done		} while (zs.avail_in > 0 && !done);	} while (!done);	zrc = inflateEnd(&zs);	if (zrc != Z_OK)		goto enderr;	free(iobuf);	return VXA_RC_OK;}int vxacodec_recognize(vxacodec *c, vxaio *io, const void *header, size_t size){	const uint8_t *inp = header;	// See if the initial data provided looks like a GZIP file.	if (size >= 3 && inp[0] == 0x1f && inp[1] == 0x8b && inp[2] == 8) {		// Apparently a GZIP stream...		io->method = VXA_M_GZIP;	// "gzip"		return vxa_error(io, VXA_RC_COMPRESSED,				"input already compressed in gzip format");	}	// Format not recognized, but we could try compressing it anyway...	return VXA_RC_OK;}

⌨️ 快捷键说明

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