Ejemplo n.º 1
0
/*
 - allocset - allocate a set of characters for []
 */
static cset *
allocset(struct parse *p)
{
	int no = p->g->ncsets++;
	size_t nc;
	size_t nbytes;
	cset *cs;
	size_t css = (size_t)p->g->csetsize;
	int i;

	if (no >= p->ncsalloc) {	/* need another column of space */
		void *ptr;

		p->ncsalloc += CHAR_BIT;
		nc = p->ncsalloc;
		assert(nc % CHAR_BIT == 0);
		nbytes = nc / CHAR_BIT * css;

		ptr = (cset *)cli_realloc((char *)p->g->sets, nc * sizeof(cset));
		if (ptr == NULL)
			goto nomem;
		p->g->sets = ptr;

		ptr = (uch *)cli_realloc((char *)p->g->setbits, nbytes);
		if (ptr == NULL)
			goto nomem;
		p->g->setbits = ptr;

		for (i = 0; i < no; i++)
			p->g->sets[i].ptr = p->g->setbits + css*(i/CHAR_BIT);

		(void) memset((char *)p->g->setbits + (nbytes - css), 0, css);
	}
	/* XXX should not happen */
	if (p->g->sets == NULL || p->g->setbits == NULL)
		goto nomem;

	cs = &p->g->sets[no];
	cs->ptr = p->g->setbits + css*((no)/CHAR_BIT);
	cs->mask = 1 << ((no) % CHAR_BIT);
	cs->hash = 0;
	cs->smultis = 0;
	cs->multis = NULL;

	return(cs);
nomem:
	free(p->g->sets);
	p->g->sets = NULL;
	free(p->g->setbits);
	p->g->setbits = NULL;

	SETERROR(REG_ESPACE);
	/* caller's responsibility not to do set ops */
	return(NULL);
}
Ejemplo n.º 2
0
static void init_testfiles(void)
{
    struct dirent *dirent;
    unsigned i = 0;
    int expect = expected_testfiles;

    DIR *d = opendir(OBJDIR"/../test");
    fail_unless(!!d, "opendir");
    if (!d)
	return;
    testfiles = NULL;
    testfiles_n = 0;
    while ((dirent = readdir(d))) {
	if (strncmp(dirent->d_name, "clam", 4))
	    continue;
        i++;
	testfiles = cli_realloc(testfiles, i*sizeof(*testfiles));
	fail_unless(!!testfiles, "cli_realloc");
	testfiles[i-1] = strdup(dirent->d_name);
    }
    testfiles_n = i;
    if (get_fpu_endian() == FPU_ENDIAN_UNKNOWN)
        expect--;
    expect -= skip_files();
    fail_unless_fmt(testfiles_n == expect, "testfiles: %d != %d", testfiles_n, expect);

    closedir(d);
}
Ejemplo n.º 3
0
/*
 * Return clamav return code
 */
int
blobGrow(blob *b, size_t len)
{
    assert(b != NULL);
    assert(b->magic == BLOBCLASS);

    if(len == 0)
        return CL_SUCCESS;

    if(b->isClosed) {
        /*
         * Should be cli_dbgmsg, but I want to see them for now,
         * and cli_dbgmsg doesn't support debug levels
         */
        cli_warnmsg("Growing closed blob\n");
        b->isClosed = 0;
    }
    if(b->data == NULL) {
        assert(b->len == 0);
        assert(b->size == 0);

        b->data = cli_malloc(len);
        if(b->data)
            b->size = (off_t)len;
    } else {
        unsigned char *ptr = cli_realloc(b->data, b->size + len);

        if(ptr) {
            b->size += (off_t)len;
            b->data = ptr;
        }
    }

    return (b->data) ? CL_SUCCESS : CL_EMEM;
}
Ejemplo n.º 4
0
static void textbuf_clean(struct text_buffer *buf)
{
	if(buf->capacity > BUF_KEEP_SIZE) {
		buf->data = cli_realloc(buf->data, BUF_KEEP_SIZE);
		buf->capacity = BUF_KEEP_SIZE;
	}
	buf->pos = 0;
}
Ejemplo n.º 5
0
/*
 - stripsnug - compact the strip
 */
static void
stripsnug(struct parse *p, struct re_guts *g)
{
	g->nstates = p->slen;
	g->strip = (sop *)cli_realloc((char *)p->strip, p->slen * sizeof(sop));
	if (g->strip == NULL) {
		SETERROR(REG_ESPACE);
		g->strip = p->strip;
	}
}
Ejemplo n.º 6
0
static inline char *textbuffer_done(yyscan_t scanner)
{
       char *str = cli_realloc(scanner->buf.data, scanner->buf.pos);
       if(!str) {
               str = scanner->buf.data;
       }
       scanner->yytext = str;
       scanner->yylen = scanner->buf.pos - 1;
       memset(&scanner->buf, 0, sizeof(scanner->buf));
       return str;
}
Ejemplo n.º 7
0
static int tokens_ensure_capacity(struct tokens *tokens, size_t cap)
{
	if(tokens->capacity < cap) {
		cap += 1024;
		tokens->data = cli_realloc(tokens->data, cap * sizeof(*tokens->data));
		if(!tokens->data)
			return CL_EMEM;
		tokens->capacity = cap;
	}
	return CL_SUCCESS;
}
Ejemplo n.º 8
0
static char *
get_unicode_name(const char *name, int size, int big_endian)
{
	int i, increment;
	char *newname, *ret;

	if((name == NULL) || (*name == '\0') || (size <= 0))
		return NULL;

	newname = (char *)cli_malloc(size * 7 + 1);
	if(newname == NULL) {
        cli_errmsg("get_unicode_name: Unable to allocate memory for newname\n");
		return NULL;
    }

	if((!big_endian) && (size & 0x1)) {
		cli_dbgmsg("get_unicode_name: odd number of bytes %d\n", size);
		--size;
	}

	increment = (big_endian) ? 1 : 2;
	ret = newname;

	for(i = 0; i < size; i += increment) {
		if((!(name[i]&0x80)) && isprint(name[i])) {
		        *ret++ = tolower(name[i]);
		} else {
			if((name[i] < 10) && (name[i] >= 0)) {
				*ret++ = '_';
				*ret++ = (char)(name[i] + '0');
			} else {
				uint16_t x;
				if ((i + 1) >= size)
					break;
				x = (uint16_t)((name[i] << 8) | name[i + 1]);

				*ret++ = '_';
				*ret++ = (char)('a'+((x&0xF)));
				*ret++ = (char)('a'+((x>>4)&0xF));
				*ret++ = (char)('a'+((x>>8)&0xF));
				*ret++ = 'a';
				*ret++ = 'a';
			}
			*ret++ = '_';
		}
	}

	*ret = '\0';

	/* Saves a lot of memory */
	ret = cli_realloc(newname, (ret - newname) + 1);
	return ret ? ret : newname;
}
Ejemplo n.º 9
0
static int tokens_ensure_capacity(struct tokens *tokens, size_t cap)
{
	if(tokens->capacity < cap) {
	        yystype *data;
		cap += 1024;
		/* Keep old data if OOM */
		data = cli_realloc(tokens->data, cap * sizeof(*tokens->data));
		if(!data)
			return CL_EMEM;
		tokens->data = data;
		tokens->capacity = cap;
	}
	return CL_SUCCESS;
}
Ejemplo n.º 10
0
static inline void ev_chain(cli_events_t *ctx, struct cli_event *ev, union ev_val *val)
{
    union ev_val *chain;
    uint32_t siz = sizeof(*chain) * (ev->count + 1);

    chain = cli_realloc(ev->u.v_chain, siz);
    if (!chain) {
	cli_event_error_oom(ctx, siz);
	return;
    }
    ev->u.v_chain = chain;
    ev->u.v_chain[ev->count] = *val;
    ev->count++;
}
Ejemplo n.º 11
0
int32_t cli_bcapi_hashset_new(struct cli_bc_ctx *ctx )
{
    unsigned  n = ctx->nhashsets+1;
    struct cli_hashset *s = cli_realloc(ctx->hashsets, sizeof(*ctx->hashsets)*n);
    if (!s) {
	cli_event_error_oom(EV, 0);
	return -1;
    }
    ctx->hashsets = s;
    ctx->nhashsets = n;
    s = &s[n-1];
    cli_hashset_init(s, 16, 80);
    return n-1;
}
Ejemplo n.º 12
0
/*
 - enlarge - enlarge the strip
 */
static void
enlarge(struct parse *p, sopno size)
{
	sop *sp;

	if (p->ssize >= size)
		return;

	sp = (sop *)cli_realloc(p->strip, size*sizeof(sop));
	if (sp == NULL) {
		SETERROR(REG_ESPACE);
		return;
	}
	p->strip = sp;
	p->ssize = size;
}
Ejemplo n.º 13
0
static int onas_ddd_grow_wdlt() {

	char **ptr = NULL;

	ptr = (char **) cli_realloc(wdlt, wdlt_len << 1);
	if (ptr) {
		wdlt = ptr;
		memset(&ptr[wdlt_len], 0, sizeof(char *) * (wdlt_len - 1));
	} else {
		return CL_EMEM;
	}

	wdlt_len <<= 1;

	return CL_SUCCESS;
}
Ejemplo n.º 14
0
int32_t cli_bcapi_inflate_init(struct cli_bc_ctx *ctx, int32_t from, int32_t to, int32_t windowBits)
{
    int ret;
    z_stream stream;
    struct bc_inflate *b;
    unsigned n = ctx->ninflates + 1;
    if (!get_buffer(ctx, from) || !get_buffer(ctx, to)) {
	cli_dbgmsg("bytecode api: inflate_init: invalid buffers!\n");
	return -1;
    }
    memset(&stream, 0, sizeof(stream));
    ret = inflateInit2(&stream, windowBits);
    switch (ret) {
	case Z_MEM_ERROR:
	    cli_dbgmsg("bytecode api: inflateInit2: out of memory!\n");
	    return -1;
	case Z_VERSION_ERROR:
	    cli_dbgmsg("bytecode api: inflateinit2: zlib version error!\n");
	    return -1;
	case Z_STREAM_ERROR:
	    cli_dbgmsg("bytecode api: inflateinit2: zlib stream error!\n");
	    return -1;
	case Z_OK:
	    break;
	default:
	    cli_dbgmsg("bytecode api: inflateInit2: unknown error %d\n", ret);
	    return -1;
    }

    b = cli_realloc(ctx->inflates, sizeof(*ctx->inflates)*n);
    if (!b) {
	inflateEnd(&stream);
	return -1;
    }
    ctx->inflates = b;
    ctx->ninflates = n;
    b = &b[n-1];

    b->from = from;
    b->to = to;
    b->needSync = 0;
    memcpy(&b->stream, &stream, sizeof(stream));
    return n-1;
}
Ejemplo n.º 15
0
/*
 - mcadd - add a collating element to a cset
 */
static void
mcadd( struct parse *p, cset *cs, const char *cp)
{
	size_t oldend = cs->smultis;
	void *np;

	cs->smultis += strlen(cp) + 1;
	np = cli_realloc(cs->multis, cs->smultis);
	if (np == NULL) {
		if (cs->multis)
			free(cs->multis);
		cs->multis = NULL;
		SETERROR(REG_ESPACE);
		return;
	}
	cs->multis = np;

	cli_strlcpy(cs->multis + oldend - 1, cp, cs->smultis - oldend + 1);
}
Ejemplo n.º 16
0
int32_t cli_bcapi_hashset_done(struct cli_bc_ctx *ctx , int32_t id)
{
    struct cli_hashset *s = get_hashset(ctx, id);
    if (!s)
	return -1;
    cli_hashset_destroy(s);
    if (id == ctx->nhashsets-1) {
	ctx->nhashsets--;
	if (!ctx->nhashsets) {
	    free(ctx->hashsets);
	    ctx->hashsets = NULL;
	} else {
	    s = cli_realloc(ctx->hashsets, ctx->nhashsets*sizeof(*s));
	    if (s)
		ctx->hashsets = s;
	}
    }
    return 0;
}
Ejemplo n.º 17
0
int32_t cli_bcapi_buffer_pipe_new(struct cli_bc_ctx *ctx, uint32_t size)
{
    unsigned char *data;
    struct bc_buffer *b;
    unsigned n = ctx->nbuffers + 1;

    data = cli_calloc(1, size);
    if (!data)
	return -1;
    b = cli_realloc(ctx->buffers, sizeof(*ctx->buffers)*n);
    if (!b) {
	free(data);
	return -1;
    }
    ctx->buffers = b;
    ctx->nbuffers = n;
    b = &b[n-1];

    b->data = data;
    b->size = size;
    b->write_cursor = b->read_cursor = 0;
    return n-1;
}
Ejemplo n.º 18
0
int32_t cli_bcapi_buffer_pipe_new_fromfile(struct cli_bc_ctx *ctx , uint32_t at)
{
    struct bc_buffer *b;
    unsigned n = ctx->nbuffers + 1;

    if (at >= ctx->file_size)
	return -1;

    b = cli_realloc(ctx->buffers, sizeof(*ctx->buffers)*n);
    if (!b) {
	return -1;
    }
    ctx->buffers = b;
    ctx->nbuffers = n;
    b = &b[n-1];

    /* NULL data means read from file at pos read_cursor */
    b->data = NULL;
    b->size = 0;
    b->read_cursor = at;
    b->write_cursor = 0;
    return n-1;
}
Ejemplo n.º 19
0
void
blobClose(blob *b)
{
    assert(b != NULL);
    assert(b->magic == BLOBCLASS);

    if(b->isClosed) {
        cli_warnmsg("Attempt to close a previously closed blob\n");
        return;
    }

    /*
     * Nothing more is going to be added to this blob. If it'll save more
     * than a trivial amount (say 64 bytes) of memory, shrink the allocation
     */
    if((b->size - b->len) >= 64) {
        if(b->len == 0) {	/* Not likely */
            free(b->data);
            b->data = NULL;
            cli_dbgmsg("blobClose: recovered all %lu bytes\n",
                       (unsigned long)b->size);
            b->size = 0;
        } else {
            unsigned char *ptr = cli_realloc(b->data, b->len);

            if(ptr == NULL)
                return;

            cli_dbgmsg("blobClose: recovered %lu bytes from %lu\n",
                       (unsigned long)(b->size - b->len),
                       (unsigned long)b->size);
            b->size = b->len;
            b->data = ptr;
        }
    }
    b->isClosed = 1;
}
Ejemplo n.º 20
0
/* buffer is html-normlike "chunk", if original file is bigger than buffer,
 * we rewind to a space, so we'll know that tokens won't be broken in half at
 * the end of a buffer. All tokens except string-literals of course.
 * So we can assume that after the buffer there is either a space, EOF, or a
 * chunk of text not containing whitespace at all (for which we care only if its
 * a stringliteral)*/
void cli_js_process_buffer(struct parser_state *state, const char *buf, size_t n)
{
	struct scope* current = state->current;
	YYSTYPE val;
	int yv;
	YY_BUFFER_STATE yyb;

	if(!state->global) {
		/* this state has either not been initialized,
		 * or cli_js_parse_done() was already called on it */
		cli_warnmsg(MODULE "invalid state\n");
		return;
	}
	yyb = yy_scan_bytes(buf, n, state->scanner);
	memset(&val, 0, sizeof(val));
	val.vtype = vtype_undefined;
	/* on EOF yylex will return 0 */
	while( (yv=yylex(&val, state->scanner)) != 0)
	{
		const char *text;
		size_t leng;

		val.type = yv;
		switch(yv) {
			case TOK_VAR:
				current->fsm_state = InsideVar;
				break;
			case TOK_IDENTIFIER_NAME:
				text = yyget_text(state->scanner);
				leng = yyget_leng(state->scanner);
				if(current->last_token == TOK_DOT) {
					/* this is a member name, don't normalize
					*/
					TOKEN_SET(&val, string, cli_strdup(text));
					val.type = TOK_UNNORM_IDENTIFIER;
				} else {
					switch(current->fsm_state) {
						case WaitParameterList:
							state->syntax_errors++;
							/* fall through */
						case Base:
						case InsideInitializer:
							TOKEN_SET(&val, cstring, scope_use(current, text, leng));
							break;
						case InsideVar:
						case InsideFunctionDecl:
							TOKEN_SET(&val, cstring, scope_declare(current, text, leng, state));
							current->fsm_state = InsideInitializer;
							current->brackets = 0;
							break;
						case WaitFunctionName:
							TOKEN_SET(&val, cstring, scope_declare(current, text, leng, state));
							current->fsm_state = WaitParameterList;
							break;
					}
				}
				break;
			case TOK_PAR_OPEN:
				switch(current->fsm_state) {
					case WaitFunctionName:
						/* fallthrough */
					case WaitParameterList:
						current->fsm_state = InsideFunctionDecl;
						break;
					default:
						/* noop */
						break;
				}
				break;
			case TOK_PAR_CLOSE:
				switch(current->fsm_state) {
					case WaitFunctionName:
						state->syntax_errors++;
						break;
					case WaitParameterList:
						current->fsm_state = Base;
						break;
					default:
						/* noop */
						break;
				}
				break;
			case TOK_CURLY_BRACE_OPEN:
				switch(current->fsm_state) {
					case WaitFunctionName:
						/* fallthrough */
					case WaitParameterList:
					case InsideFunctionDecl:
						/* in a syntactically correct
						 * file, we would already be in
						 * the Base state when we see a {
						 */
						current->fsm_state = Base;
						/* fall-through */
					case InsideVar:
					case InsideInitializer:
						state->syntax_errors++;
						/* fall-through */
					case Base:
					default:
						current->blocks++;
						break;
				}
				break;
					case TOK_CURLY_BRACE_CLOSE:
				if(current->blocks > 0)
					current->blocks--;
				else
					state->syntax_errors++;
				if(!current->blocks) {
					if(current->parent) {
						/* add dummy FUNCTION token to
						 * mark function end */
						TOKEN_SET(&val, cstring, "}");
						add_token(state, &val);
						TOKEN_SET(&val, scope, NULL);
						val.type = TOK_FUNCTION;

						state->current = current = current->parent;
					} else{
						/* extra } */
						state->syntax_errors++;
				}
				}
				break;
			case TOK_BRACKET_OPEN:
				current->brackets++;
				break;
			case TOK_BRACKET_CLOSE:
				if(current->brackets > 0)
					current->brackets--;
				else
					state->syntax_errors++;
				break;
			case TOK_COMMA:
				if (current->fsm_state == InsideInitializer && current->brackets == 0 && current->blocks == 0) {
					/* initializer ended only if we
					 * encountered a comma, and [] are
					 * balanced.
					 * This avoids switching state on:
					 * var x = [4,y,u];*/
					current->fsm_state = InsideVar;
				}
				break;
			case TOK_SEMICOLON:
				if (current->brackets == 0 && current->blocks == 0) {
					/* avoid switching state on unbalanced []:
					 * var x = [test;testi]; */
					current->fsm_state = Base;
				}
				break;
			case TOK_FUNCTION:
				current = scope_new(state);
				current->fsm_state = WaitFunctionName;
				TOKEN_SET(&val, scope, state->current);
				break;
			case TOK_StringLiteral:
				if(state->tokens.cnt > 1 && state->tokens.data[state->tokens.cnt-1].type == TOK_PLUS) {
					/* see if can fold */
					yystype *prev_string = &state->tokens.data[state->tokens.cnt-2];
					if(prev_string->type == TOK_StringLiteral) {
						char *str = TOKEN_GET(prev_string, string);
						size_t str_len = strlen(str);

						text = yyget_text(state->scanner);
						leng = yyget_leng(state->scanner);


						/* delete TOK_PLUS */
						free_token(&state->tokens.data[--state->tokens.cnt]);

						str = cli_realloc(str, str_len + leng + 1);
						if (!str)
						    break;
						strncpy(str+str_len, text, leng);
						str[str_len + leng] = '\0';
						TOKEN_SET(prev_string, string, str);
						free(val.val.string);
						memset(&val, 0, sizeof(val));
						val.vtype = vtype_undefined;
						continue;
					}
				}
				break;
		}
		if(val.vtype == vtype_undefined) {
			text = yyget_text(state->scanner);
			TOKEN_SET(&val, string, cli_strdup(text));
			abort();
		}
		add_token(state, &val);
		current->last_token = yv;
		memset(&val, 0, sizeof(val));
		val.vtype = vtype_undefined;
	}
}
Ejemplo n.º 21
0
vba_project_t *
cli_vba_readdir(const char *dir, struct uniq *U, uint32_t which)
{
	unsigned char *buf;
	const unsigned char vba56_signature[] = { 0xcc, 0x61 };
	uint16_t record_count, buflen, ffff, byte_count;
	uint32_t offset;
	int i, j, fd, big_endian = FALSE;
	vba_project_t *vba_project;
	struct vba56_header v56h;
	off_t seekback;
	char fullname[1024], *hash;

	cli_dbgmsg("in cli_vba_readdir()\n");

	if(dir == NULL)
		return NULL;

	/*
	 * _VBA_PROJECT files are embedded within office documents (OLE2)
	 */
	
	if (!uniq_get(U, "_vba_project", 12, &hash))
		return NULL;
	snprintf(fullname, sizeof(fullname), "%s"PATHSEP"%s_%u", dir, hash, which);
	fullname[sizeof(fullname)-1] = '\0';
	fd = open(fullname, O_RDONLY|O_BINARY);

	if(fd == -1)
		return NULL;

	if(cli_readn(fd, &v56h, sizeof(struct vba56_header)) != sizeof(struct vba56_header)) {
		close(fd);
		return NULL;
	}
	if (memcmp(v56h.magic, vba56_signature, sizeof(v56h.magic)) != 0) {
		close(fd);
		return NULL;
	}

	i = vba_read_project_strings(fd, TRUE);
	if ((seekback = lseek(fd, 0, SEEK_CUR)) == -1) {
		cli_dbgmsg("vba_readdir: lseek() failed. Unable to guess VBA type\n");
		close(fd);
		return NULL;
	}
	if (lseek(fd, sizeof(struct vba56_header), SEEK_SET) == -1) {
		cli_dbgmsg("vba_readdir: lseek() failed. Unable to guess VBA type\n");
		close(fd);
		return NULL;
	}
	j = vba_read_project_strings(fd, FALSE);
	if(!i && !j) {
		close(fd);
		cli_dbgmsg("vba_readdir: Unable to guess VBA type\n");
		return NULL;
	}
	if (i > j) {
		big_endian = TRUE;
		if (lseek(fd, seekback, SEEK_SET) == -1) {
			cli_dbgmsg("vba_readdir: call to lseek() while guessing big-endian has failed\n");
			close(fd);
			return NULL;
		}
		cli_dbgmsg("vba_readdir: Guessing big-endian\n");
	} else {
		cli_dbgmsg("vba_readdir: Guessing little-endian\n");
	}

	/* junk some more stuff */
	do
		if (cli_readn(fd, &ffff, 2) != 2) {
			close(fd);
			return NULL;
		}
	while(ffff != 0xFFFF);

	/* check for alignment error */
	if(!seekandread(fd, -3, SEEK_CUR, &ffff, sizeof(uint16_t))) {
		close(fd);
		return NULL;
	}
	if (ffff != 0xFFFF) {
		if (lseek(fd, 1, SEEK_CUR) == -1) {
            cli_dbgmsg("call to lseek() while checking alignment error has failed\n");
            close(fd);
            return NULL;
        }
    }

	if(!read_uint16(fd, &ffff, big_endian)) {
		close(fd);
		return NULL;
	}

	if(ffff != 0xFFFF) {
		if (lseek(fd, ffff, SEEK_CUR) == -1) {
            cli_dbgmsg("call to lseek() while checking alignment error has failed\n");
            close(fd);
            return NULL;
        }
    }

	if(!read_uint16(fd, &ffff, big_endian)) {
		close(fd);
		return NULL;
	}

	if(ffff == 0xFFFF)
		ffff = 0;

	if (lseek(fd, ffff + 100, SEEK_CUR) == -1) {
        cli_dbgmsg("call to lseek() failed\n");
        close(fd);
        return NULL;
    }

	if(!read_uint16(fd, &record_count, big_endian)) {
		close(fd);
		return NULL;
	}
	cli_dbgmsg("vba_readdir: VBA Record count %d\n", record_count);
	if (record_count == 0) {
		/* No macros, assume clean */
		close(fd);
		return NULL;
	}
	if (record_count > MAX_VBA_COUNT) {
		/* Almost certainly an error */
		cli_dbgmsg("vba_readdir: VBA Record count too big\n");
		close(fd);
		return NULL;
	}

	vba_project = create_vba_project(record_count, dir, U);
	if(vba_project == NULL) {
		close(fd);
		return NULL;
	}
	buf = NULL;
	buflen = 0;
	for(i = 0; i < record_count; i++) {
		uint16_t length;
		char *ptr;

		vba_project->colls[i] = 0;
		if(!read_uint16(fd, &length, big_endian))
			break;

		if (length == 0) {
			cli_dbgmsg("vba_readdir: zero name length\n");
			break;
		}
		if(length > buflen) {
			unsigned char *newbuf = (unsigned char *)cli_realloc(buf, length);
			if(newbuf == NULL)
				break;
			buflen = length;
			buf = newbuf;
		}
		if (cli_readn(fd, buf, length) != length) {
			cli_dbgmsg("vba_readdir: read name failed\n");
			break;
		}
		ptr = get_unicode_name((const char *)buf, length, big_endian);
		if(ptr == NULL) break;
		if (!(vba_project->colls[i]=uniq_get(U, ptr, strlen(ptr), &hash))) {
			cli_dbgmsg("vba_readdir: cannot find project %s (%s)\n", ptr, hash);
			free(ptr);
			break;
		}
		cli_dbgmsg("vba_readdir: project name: %s (%s)\n", ptr, hash);
		free(ptr);
		vba_project->name[i] = hash;
		if(!read_uint16(fd, &length, big_endian))
			break;
		lseek(fd, length, SEEK_CUR);

		if(!read_uint16(fd, &ffff, big_endian))
			break;
		if (ffff == 0xFFFF) {
			lseek(fd, 2, SEEK_CUR);
			if(!read_uint16(fd, &ffff, big_endian))
				break;
			lseek(fd, ffff + 8, SEEK_CUR);
		} else
			lseek(fd, ffff + 10, SEEK_CUR);

		if(!read_uint16(fd, &byte_count, big_endian))
			break;
		lseek(fd, (8 * byte_count) + 5, SEEK_CUR);
		if(!read_uint32(fd, &offset, big_endian))
			break;
		cli_dbgmsg("vba_readdir: offset: %u\n", (unsigned int)offset);
		vba_project->offset[i] = offset;
		lseek(fd, 2, SEEK_CUR);
	}

	if(buf)
		free(buf);

	close(fd);

	if(i < record_count) {
		free(vba_project->name);
		free(vba_project->colls);
		free(vba_project->dir);
		free(vba_project->offset);
		free(vba_project);
		return NULL;
	}

	return vba_project;
}
Ejemplo n.º 22
0
/* return count of valid strings found, 0 on error */
static int
vba_read_project_strings(int fd, int big_endian)
{
    unsigned char *buf = NULL;
    uint16_t buflen = 0;
    uint16_t length = 0;
    int ret = 0, getnewlength = 1;

    for(;;) {
        off_t offset;
        char *name;

        /* if no initial name length, exit */
        if(getnewlength && !read_uint16(fd, &length, big_endian)) {
            ret = 0;
            break;
        }
        getnewlength = 0;

        /* if too short, break */
        if (length < 6) {
            if (lseek(fd, -2, SEEK_CUR) == -1) {
                cli_dbgmsg("vba_read_project_strings: call to lseek() has failed\n");
                ret = 0;
            }
            break;
        }
        /* ensure buffer is large enough */
        if(length > buflen) {
            unsigned char *newbuf = (unsigned char *)cli_realloc(buf, length);
            if(newbuf == NULL) {
                ret = 0;
                break;
            }
            buflen = length;
            buf = newbuf;
        }

        /* save current offset */
        offset = lseek(fd, 0, SEEK_CUR);
        if (offset == -1) {
            cli_dbgmsg("vba_read_project_strings: call to lseek() has failed\n");
            ret = 0;
            break;
        }

        /* if read name failed, break */
        if(cli_readn(fd, buf, length) != (int)length) {
            cli_dbgmsg("read name failed - rewinding\n");
            if (lseek(fd, offset, SEEK_SET) == -1) {
                cli_dbgmsg("call to lseek() in read name failed\n");
                ret = 0;
            }
            break;
        }
        name = get_unicode_name((const char *)buf, length, big_endian);
        cli_dbgmsg("length: %d, name: %s\n", length, (name) ? name : "[null]");

        /* if invalid name, break */
        if((name == NULL) || (memcmp("*\\", name, 2) != 0) ||
           (strchr("ghcd", name[2]) == NULL)) {
            /* Not a valid string, rewind */
            if (lseek(fd, -(length+2), SEEK_CUR) == -1) {
                cli_dbgmsg("call to lseek() after get_unicode_name has failed\n");
                ret = 0;
            }
            free(name);
            break;
        }
        free(name);

        /* can't get length, break */
        if(!read_uint16(fd, &length, big_endian)) {
            break;
        }

        ret++;

        /* continue on reasonable length value */
        if ((length != 0) && (length != 65535)) {
            continue;
        }

        /* determine offset and run middle test */
        offset = lseek(fd, 10, SEEK_CUR);
        if (offset == -1) {
            cli_dbgmsg("call to lseek() has failed\n");
            ret = 0;
            break;
        }
        cli_dbgmsg("offset: %lu\n", (unsigned long)offset);
        vba56_test_middle(fd);
        getnewlength = 1;
    }

    free(buf);
    return ret;
}
Ejemplo n.º 23
0
static int
vba_read_project_strings(int fd, int big_endian)
{
	unsigned char *buf = NULL;
	uint16_t buflen = 0;
	int ret = 0;

	for(;;) {
		off_t offset;
		uint16_t length;
		char *name;

		if(!read_uint16(fd, &length, big_endian))
			break;

		if (length < 6) {
			lseek(fd, -2, SEEK_CUR);
			break;
		}
		if(length > buflen) {
			unsigned char *newbuf = (unsigned char *)cli_realloc(buf, length);
			if(newbuf == NULL) {
				if(buf)
					free(buf);
				return 0;
			}
			buflen = length;
			buf = newbuf;
		}

		offset = lseek(fd, 0, SEEK_CUR);

		if(cli_readn(fd, buf, length) != (int)length) {
			cli_dbgmsg("read name failed - rewinding\n");
			lseek(fd, offset, SEEK_SET);
			break;
		}
		name = get_unicode_name((const char *)buf, length, big_endian);
		cli_dbgmsg("length: %d, name: %s\n", length, (name) ? name : "[null]");

		if((name == NULL) || (memcmp("*\\", name, 2) != 0) ||
		   (strchr("ghcd", name[2]) == NULL)) {
			/* Not a string */
			lseek(fd, -(length+2), SEEK_CUR);
			if(name)
				free(name);
			break;
		}
		free(name);

		if(!read_uint16(fd, &length, big_endian)) {
			if(buf)
				free(buf);
			break;
		}

		ret++;

		if ((length != 0) && (length != 65535)) {
			lseek(fd, -2, SEEK_CUR);
			continue;
		}
		offset = lseek(fd, 10, SEEK_CUR);
		cli_dbgmsg("offset: %lu\n", (unsigned long)offset);
		vba56_test_middle(fd);
	}
	if(buf)
		free(buf);
	return ret;
}
Ejemplo n.º 24
0
int
cli_binhex(const char *dir, int desc)
{
#ifndef HAVE_MMAP
	cli_warnmsg("File not decoded - binhex decoding needs mmap() (for now)\n");
	return CL_CLEAN;
#else
	struct stat statb;
	char *buf, *start, *line;
	size_t size;
	long bytesleft;
	message *m;
	fileblob *fb;

	if(fstat(desc, &statb) < 0)
		return CL_EOPEN;

	size = (size_t)statb.st_size;

	if(size == 0)
		return CL_CLEAN;

	m = messageCreate();
	if(m == NULL)
		return CL_EMEM;

	start = buf = mmap(NULL, size, PROT_READ, MAP_PRIVATE, desc, 0);
	if(buf == MAP_FAILED) {
		messageDestroy(m);
		return CL_EMEM;
	}

	cli_dbgmsg("mmap'ed binhex file\n");

	bytesleft = (long)size;
	line = NULL;

	while(bytesleft > 0) {
		int length = 0;
		char *ptr, *newline;

		/*printf("%d: ", bytesleft);*/

		for(ptr = buf; bytesleft && (*ptr != '\n') && (*ptr != '\r'); ptr++) {
			length++;
			--bytesleft;
		}

		/*printf("%d: ", length);*/

		newline = cli_realloc(line, (size_t)(length + 1));
		if(newline == NULL)
			break;

		line = newline;

		memcpy(line, buf, length);
		line[length] = '\0';

		/*puts(line);*/

		if(messageAddStr(m, line) < 0)
			break;

		if((bytesleft > 0) && (*ptr == '\r')) {
			ptr++;
			bytesleft--;
		}
		buf = ++ptr;
		bytesleft--;
	}
	munmap(start, size);

	if(line)
		free(line);

	if(binhexBegin(m) == NULL) {
		messageDestroy(m);
		cli_errmsg("No binhex line found\n");
		return CL_EFORMAT;
	}

	/* similar to binhexMessage */
	messageSetEncoding(m, "x-binhex");

	fb = messageToFileblob(m, dir, 1);
	if(fb) {
		cli_dbgmsg("Binhex file decoded to %s\n", fileblobGetFilename(fb));
		fileblobDestroy(fb);
	} else
		cli_errmsg("Couldn't decode binhex file to %s\n", dir);
	messageDestroy(m);

	if(fb)
		return CL_CLEAN;	/* a lie - but it gets things going */
	return CL_EIO;	/* probably CL_EMEM, but we can't tell at this layer */
#endif
}
Ejemplo n.º 25
0
/*
 * Returns <0 for failure
 */
int
blobAddData(blob *b, const unsigned char *data, size_t len)
{
#if	HAVE_CLI_GETPAGESIZE
    static int pagesize;
    int growth;
#endif

    assert(b != NULL);
    assert(b->magic == BLOBCLASS);
    assert(data != NULL);

    if(len == 0)
        return 0;

    if(b->isClosed) {
        /*
         * Should be cli_dbgmsg, but I want to see them for now,
         * and cli_dbgmsg doesn't support debug levels
         */
        cli_warnmsg("Reopening closed blob\n");
        b->isClosed = 0;
    }
    /*
     * The payoff here is between reducing the number of calls to
     * malloc/realloc and not overallocating memory. A lot of machines
     * are more tight with memory than one may imagine which is why
     * we don't just allocate a *huge* amount and be done with it. Closing
     * the blob helps because that reclaims memory. If you know the maximum
     * size of a blob before you start adding data, use blobGrow() that's
     * the most optimum
     */
#if	HAVE_CLI_GETPAGESIZE
    if(pagesize == 0) {
        pagesize = cli_getpagesize();
        if(pagesize == 0)
            pagesize = 4096;
    }
    growth = pagesize;
    if(len >= (size_t)pagesize)
        growth = ((len / pagesize) + 1) * pagesize;

    /*cli_dbgmsg("blobGrow: b->size %lu, b->len %lu, len %lu, growth = %u\n",
    	b->size, b->len, len, growth);*/

    if(b->data == NULL) {
        assert(b->len == 0);
        assert(b->size == 0);

        b->size = growth;
        b->data = cli_malloc(growth);
    } else if(b->size < b->len + (off_t)len) {
        unsigned char *p = cli_realloc(b->data, b->size + growth);

        if(p == NULL)
            return -1;

        b->size += growth;
        b->data = p;
    }
#else
    if(b->data == NULL) {
        assert(b->len == 0);
        assert(b->size == 0);

        b->size = (off_t)len * 4;
        b->data = cli_malloc(b->size);
    } else if(b->size < b->len + (off_t)len) {
        unsigned char *p = cli_realloc(b->data, b->size + (len * 4));

        if(p == NULL)
            return -1;

        b->size += (off_t)len * 4;
        b->data = p;
    }
#endif

    if(b->data) {
        memcpy(&b->data[b->len], data, len);
        b->len += (off_t)len;
    }
    return 0;
}