[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b

Török Edvin edwin at clamav.net
Sun Apr 4 00:59:47 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit 6922903ad9edcb743d87f828e6e94fe7358933c1
Author: Török Edvin <edwin at clamav.net>
Date:   Thu Jul 23 17:33:11 2009 +0300

    bytecode: fully switch to a stack based allocation, and operands with various bitwidths.

diff --git a/clambc/bcrun.c b/clambc/bcrun.c
index e472f70..45f0af3 100644
--- a/clambc/bcrun.c
+++ b/clambc/bcrun.c
@@ -90,6 +90,12 @@ int main(int argc, char *argv[])
 	exit(4);
     }
 
+    rc = cli_bytecode_prepare(bc);
+    if (rc != CL_SUCCESS) {
+	fprintf(stderr,"Unable to prepare bytecode: %s\n", cl_strerror(rc));
+	optfree(opts);
+	exit(4);
+    }
     fclose(f);
 
     printf("Bytecode loaded\n");
diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c
index 88c684e..4252baf 100644
--- a/libclamav/bytecode.c
+++ b/libclamav/bytecode.c
@@ -38,6 +38,7 @@ struct cli_bc_ctx *cli_bytecode_context_alloc(void)
     ctx->func = NULL;
     ctx->values = NULL;
     ctx->operands = NULL;
+    ctx->opsizes = NULL;
     return ctx;
 }
 
@@ -49,15 +50,37 @@ void cli_bytecode_context_destroy(struct cli_bc_ctx *ctx)
 
 int cli_bytecode_context_clear(struct cli_bc_ctx *ctx)
 {
+    free(ctx->opsizes);
     free(ctx->values);
     free(ctx->operands);
     memset(ctx, 0, sizeof(ctx));
     return CL_SUCCESS;
 }
 
+static unsigned typesize(const struct cli_bc *bc, uint16_t type)
+{
+    if (!type)
+	return 0;
+    if (type <= 8)
+	return 1;
+    if (type <= 16)
+	return 2;
+    if (type <= 32)
+	return 4;
+    if (type <= 64)
+	return 8;
+    return 0;
+}
+
+static unsigned typealign(const struct cli_bc *bc, uint16_t type)
+{
+    unsigned size = typesize(bc, type);
+    return size ? size : 1;
+}
+
 int cli_bytecode_context_setfuncid(struct cli_bc_ctx *ctx, const struct cli_bc *bc, unsigned funcid)
 {
-    unsigned i;
+    unsigned i, s=0;
     const struct cli_bc_func *func;
     if (funcid >= bc->num_func) {
 	cli_errmsg("bytecode: function ID doesn't exist: %u\n", funcid);
@@ -67,21 +90,26 @@ int cli_bytecode_context_setfuncid(struct cli_bc_ctx *ctx, const struct cli_bc *
     ctx->bc = bc;
     ctx->numParams = func->numArgs;
     ctx->funcid = funcid;
-    ctx->values = cli_malloc(sizeof(*ctx->values)*(func->numArgs+1));
-    if (!ctx->values) {
-	cli_errmsg("bytecode: error allocating memory for parameters\n");
-	return CL_EMEM;
-    }
     if (func->numArgs) {
 	ctx->operands = cli_malloc(sizeof(*ctx->operands)*func->numArgs);
 	if (!ctx->operands) {
 	    cli_errmsg("bytecode: error allocating memory for parameters\n");
 	    return CL_EMEM;
 	}
+	ctx->opsizes = cli_malloc(sizeof(*ctx->opsizes)*func->numArgs);
+	for (i=0;i<func->numArgs;i++) {
+	    unsigned al = typealign(bc, func->types[i]);
+	    s = (s+al-1)&~(al-1);
+	    ctx->operands[i] = s;
+	    s += ctx->opsizes[i] = typesize(bc, func->types[i]);
+	}
     }
-    for (i=0;i<func->numArgs;i++) {
-	ctx->values[i].ref = MAX_OP;
-	ctx->operands[i] = i;
+    s += 8;/* return value */
+    ctx->bytes = s;
+    ctx->values = cli_malloc(s);
+    if (!ctx->values) {
+	cli_errmsg("bytecode: error allocating memory for parameters\n");
+	return CL_EMEM;
     }
     return CL_SUCCESS;
 }
@@ -93,6 +121,7 @@ static inline int type_isint(uint16_t type)
 
 int cli_bytecode_context_setparam_int(struct cli_bc_ctx *ctx, unsigned i, uint64_t c)
 {
+    unsigned j, s=0;
     if (i >= ctx->numParams) {
 	cli_errmsg("bytecode: param index out of bounds: %u\n", i);
 	return CL_EARG;
@@ -101,8 +130,20 @@ int cli_bytecode_context_setparam_int(struct cli_bc_ctx *ctx, unsigned i, uint64
 	cli_errmsg("bytecode: parameter type mismatch\n");
 	return CL_EARG;
     }
-    ctx->values[i].v = c;
-    ctx->values[i].ref = CONSTANT_OP;
+    switch (ctx->opsizes[i]) {
+	case 1:
+	    ctx->values[ctx->operands[i]] = c;
+	    break;
+	case 2:
+	    *(uint16_t*)&ctx->values[ctx->operands[i]] = c;
+	    break;
+	case 4:
+	    *(uint32_t*)&ctx->values[ctx->operands[i]] = c;
+	    break;
+	case 8:
+	    *(uint64_t*)&ctx->values[ctx->operands[i]] = c;
+	    break;
+    }
     return CL_SUCCESS;
 }
 
@@ -175,8 +216,8 @@ static inline operand_t readOperand(struct cli_bc_func *func, unsigned char *p,
 	    *ok = 0;
 	    return MAX_OP;
 	}
-	func->constants[func->numConstants].v = readNumber(p, off, len, ok);
-	func->constants[func->numConstants].ref = CONSTANT_OP;
+	v = readNumber(p, off, len, ok);
+	func->constants[func->numConstants] = v;
 	return func->numValues + func->numConstants++;
     }
     v = readNumber(p, off, len, ok);
@@ -299,6 +340,7 @@ static int parseHeader(struct cli_bc *bc, unsigned char *buffer)
     bc->metadata.maxTime = readNumber(buffer, &offset, len, &ok);
     bc->metadata.targetExclude = readString(buffer, &offset, len, &ok);
     bc->num_func = readNumber(buffer, &offset, len, &ok);
+    bc->state = bc_loaded;
     if (!ok) {
 	cli_errmsg("Invalid bytecode header at %u\n", offset);
 	return CL_EMALFDB;
@@ -410,10 +452,18 @@ static bbid_t readBBID(struct cli_bc_func *func, const unsigned char *buffer, un
     return id;
 }
 
+
+static uint16_t get_type(struct cli_bc_func *func, operand_t op)
+{
+    if (op >= func->numValues)
+	return 64;
+    return func->types[op];
+}
+
 static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char *buffer)
 {
     char ok=1;
-    unsigned offset, len, last = 0;
+    unsigned offset, len, i, last = 0;
     struct cli_bc_bb *BB;
     struct cli_bc_func *bcfunc = &bc->funcs[func];
     struct cli_bc_inst inst;
@@ -457,6 +507,10 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
 	    case OP_JMP:
 		inst.u.jump = readBBID(bcfunc, buffer, &offset, len, &ok);
 		break;
+	    case OP_RET:
+		inst.u.unaryop = readOperand(bcfunc, buffer, &offset, len, &ok);
+		inst.type = readNumber(buffer, &offset, len, &ok);
+		break;
 	    case OP_BRANCH:
 		inst.u.branch.condition = readOperand(bcfunc, buffer, &offset, len, &ok);
 		inst.u.branch.br_true = readBBID(bcfunc, buffer, &offset, len, &ok);
@@ -466,6 +520,7 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
 		numOp = readFixedNumber(buffer, &offset, len, &ok, 1);
 		if (ok) {
 		    inst.u.ops.numOps = numOp;
+		    inst.u.ops.opsizes=NULL;
 		    inst.u.ops.ops = cli_calloc(numOp, sizeof(*inst.u.ops.ops));
 		    if (!inst.u.ops.ops) {
 			cli_errmsg("Out of memory allocating operands\n");
@@ -524,7 +579,8 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
 	    return CL_EMALFDB;
 	}
 	if (bcfunc->insn_idx + BB->numInsts >= bcfunc->numInsts) {
-	    cli_errmsg("More instructions than declared in total!\n");
+	    cli_errmsg("More instructions than declared in total: %u > %u!\n",
+		       bcfunc->insn_idx+BB->numInsts, bcfunc->numInsts);
 	    return CL_EMALFDB;
 	}
 	switch (inst.opcode) {
@@ -540,7 +596,7 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
 	    case OP_ICMP_SGE:
 	    case OP_ICMP_SLE:
 	    case OP_ICMP_SLT:
-		inst.type = bcfunc->types[inst.u.binop[0]];
+		inst.type = get_type(bcfunc, inst.u.binop[0]);
 		break;
 	}
 	inst.interp_op = inst.opcode*5;
@@ -566,6 +622,7 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
 		   len-offset);
 	return CL_EMALFDB;
     }
+    bcfunc->numBytes = 0;
     bcfunc->insn_idx += BB->numInsts;
     return CL_SUCCESS;
 }
@@ -586,7 +643,6 @@ int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio)
 	cli_errmsg("Unable to load bytecode (null file)\n");
 	return CL_ENULLARG;
     }
-
     while (cli_dbgets(buffer, FILEBUFF, f, dbio)) {
 	int rc;
 	cli_chomp(buffer);
@@ -618,6 +674,11 @@ int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio)
 		    return rc;
 		}
 		if (bb >= bc->funcs[current_func].numBB) {
+		    if (bc->funcs[current_func].insn_idx != bc->funcs[current_func].numInsts) {
+			cli_errmsg("Parsed different number of instructions than declared: %u != %u\n",
+				   bc->funcs[current_func].insn_idx, bc->funcs[current_func].numInsts);
+			return CL_EMALFDB;
+		    }
 		    cli_dbgmsg("Parsed %u BBs, %u instructions\n",
 			       bb, bc->funcs[current_func].numInsts);
 		    state = PARSE_FUNC_HEADER;
@@ -644,29 +705,31 @@ int cli_bytecode_run(const struct cli_bc *bc, struct cli_bc_ctx *ctx)
 	return CL_ENULLARG;
     if (ctx->numParams && (!ctx->values || !ctx->operands))
 	return CL_ENULLARG;
-    for (i=0;i<ctx->numParams;i++) {
-	if (ctx->values[i].ref == MAX_OP) {
-	    cli_errmsg("bytecode: parameter %u is uninitialized!\n", i);
-	    return CL_EARG;
-	}
+    if (bc->state == bc_loaded) {
+	cli_errmsg("bytecode has to be prepared either for interpreter or JIT!\n");
+	return CL_EARG;
     }
     memset(&func, 0, sizeof(func));
     func.numInsts = 1;
     func.numValues = 1;
+    func.numBytes = ctx->bytes;
+    memset(ctx->values+ctx->bytes-8, 0, 8);
 
     inst.opcode = OP_CALL_DIRECT;
     inst.interp_op = OP_CALL_DIRECT*5;
     inst.dest = func.numArgs;
-    inst.type = 0;/* TODO: support toplevel functions with return values */
+    inst.type = 0;
     inst.u.ops.numOps = ctx->numParams;
     inst.u.ops.funcid = ctx->funcid;
     inst.u.ops.ops = ctx->operands;
+    inst.u.ops.opsizes = ctx->opsizes;
     return cli_vm_execute(ctx->bc, ctx, &func, &inst);
 }
 
 uint64_t cli_bytecode_context_getresult_int(struct cli_bc_ctx *ctx)
 {
-    return ctx->values[ctx->numParams].v;
+    return *(uint64_t*)ctx->values;/*XXX*/
+//    return ctx->values[ctx->numParams];
 }
 
 void cli_bytecode_destroy(struct cli_bc *bc)
@@ -683,8 +746,10 @@ void cli_bytecode_destroy(struct cli_bc *bc)
 	    struct cli_bc_bb *BB = &f->BB[j];
 	    for(k=0;k<BB->numInsts;k++) {
 		struct cli_bc_inst *ii = &BB->insts[k];
-		if (operand_counts[ii->opcode] > 3 || ii->opcode == OP_CALL_DIRECT)
+		if (operand_counts[ii->opcode] > 3 || ii->opcode == OP_CALL_DIRECT) {
 		    free(ii->u.ops.ops);
+		    free(ii->u.ops.opsizes);
+		}
 	    }
 	}
 	free(f->BB);
@@ -694,3 +759,136 @@ void cli_bytecode_destroy(struct cli_bc *bc)
     free(bc->funcs);
 }
 
+#define MAP(val) do { operand_t o = val; \
+    if (o > totValues) {\
+	cli_errmsg("bytecode: operand out of range: %u > %u, for instruction %u in function %u\n", o, totValues, j, i);\
+	return CL_EBYTECODE;\
+    }\
+    val = map[o]; } while (0)
+
+static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
+{
+    unsigned i, j, k;
+    for (i=0;i<bc->num_func;i++) {
+	struct cli_bc_func *bcfunc = &bc->funcs[i];
+	unsigned totValues = bcfunc->numValues + bcfunc->numConstants;
+	unsigned *map = cli_malloc(sizeof(*map)*totValues);
+	for (j=0;j<bcfunc->numValues;j++) {
+	    uint16_t ty = bcfunc->types[j];
+	    unsigned align;
+	    if (ty > 64) {
+		cli_errmsg("Bytecode: non-integer types not yet implemented\n");
+		return CL_EMALFDB;
+	    }
+	    align = typealign(bc, ty);
+	    bcfunc->numBytes  = (bcfunc->numBytes + align-1)&(~(align-1));
+	    map[j] = bcfunc->numBytes;
+	    bcfunc->numBytes += typesize(bc, ty);
+	}
+	bcfunc->numBytes = (bcfunc->numBytes + 7)&~7;
+	for (j=0;j<bcfunc->numConstants;j++) {
+	    map[bcfunc->numValues+j] = bcfunc->numBytes;
+	    bcfunc->numBytes += 8;
+	}
+	for (j=0;j<bcfunc->numInsts;j++) {
+	    struct cli_bc_inst *inst = &bcfunc->allinsts[j];
+	    inst->dest = map[inst->dest];
+	    switch (inst->opcode) {
+		case OP_ADD:
+		case OP_SUB:
+		case OP_MUL:
+		case OP_UDIV:
+		case OP_SDIV:
+		case OP_UREM:
+		case OP_SREM:
+		case OP_SHL:
+		case OP_LSHR:
+		case OP_ASHR:
+		case OP_AND:
+		case OP_OR:
+		case OP_XOR:
+		case OP_ICMP_EQ:
+		case OP_ICMP_NE:
+		case OP_ICMP_UGT:
+		case OP_ICMP_UGE:
+		case OP_ICMP_ULT:
+		case OP_ICMP_ULE:
+		case OP_ICMP_SGT:
+		case OP_ICMP_SGE:
+		case OP_ICMP_SLT:
+		case OP_ICMP_SLE:
+		case OP_COPY:
+		    MAP(inst->u.binop[0]);
+		    MAP(inst->u.binop[1]);
+		    break;
+		case OP_SEXT:
+		case OP_ZEXT:
+		case OP_TRUNC:
+		    MAP(inst->u.cast.source);
+		    break;
+		case OP_BRANCH:
+		    MAP(inst->u.branch.condition);
+		    break;
+		case OP_JMP:
+		    break;
+		case OP_RET:
+		    MAP(inst->u.unaryop);
+		    break;
+		case OP_SELECT:
+		    MAP(inst->u.three[0]);
+		    MAP(inst->u.three[1]);
+		    MAP(inst->u.three[2]);
+		    break;
+		case OP_CALL_DIRECT:
+		{
+		    struct cli_bc_func *target = &bc->funcs[inst->u.ops.funcid];
+		    if (inst->u.ops.funcid > bc->num_func) {
+			cli_errmsg("bytecode: called function out of range: %u > %u\n", inst->u.ops.funcid, bc->num_func);
+			return CL_EBYTECODE;
+		    }
+		    if (inst->u.ops.numOps != target->numArgs) {
+			cli_errmsg("bytecode: call operands don't match function prototype\n");
+			return CL_EBYTECODE;
+		    }
+		    if (inst->u.ops.numOps) {
+			inst->u.ops.opsizes = cli_malloc(sizeof(*inst->u.ops.opsizes)*inst->u.ops.numOps);
+			if (!inst->u.ops.opsizes) {
+			    cli_errmsg("Out of memory when allocating operand sizes\n");
+			    return CL_EMEM;
+			}
+		    }
+		    for (k=0;k<inst->u.ops.numOps;k++) {
+			MAP(inst->u.ops.ops[k]);
+			inst->u.ops.opsizes[k] = typesize(bc, target->types[k]);
+		    }
+		    break;
+		}
+		default:
+		    cli_dbgmsg("Unhandled opcode: %d\n", inst->opcode);
+		    return CL_EBYTECODE;
+	    }
+	}
+	free(map);
+    }
+    bc->state = bc_interp;
+    return CL_SUCCESS;
+}
+
+static int cli_bytecode_prepare_jit(struct cli_bc *bc)
+{
+    if (bc->state != bc_loaded) {
+	cli_warnmsg("Cannot prepare for JIT, because it has already been converted to interpreter");
+	return CL_EBYTECODE;
+    }
+    cli_warnmsg("JIT not yet implemented\n");
+    return CL_EBYTECODE;
+}
+
+int cli_bytecode_prepare(struct cli_bc *bc)
+{
+    if (bc->state == bc_interp || bc->state == bc_jit)
+	return CL_SUCCESS;
+    if (cli_bytecode_prepare_jit(bc) == CL_SUCCESS)
+	return CL_SUCCESS;
+    return cli_bytecode_prepare_interpreter(bc);
+}
diff --git a/libclamav/bytecode.h b/libclamav/bytecode.h
index da6606b..39dab43 100644
--- a/libclamav/bytecode.h
+++ b/libclamav/bytecode.h
@@ -30,6 +30,12 @@ struct cli_bc_func;
 struct cli_bc_value;
 struct cli_bc_inst;
 
+enum bc_state {
+    bc_loaded,
+    bc_jit,
+    bc_interp
+};
+
 struct cli_bc {
   unsigned verifier;
   char *sigmaker;
@@ -37,6 +43,7 @@ struct cli_bc {
   struct bytecode_metadata metadata;
   unsigned num_func;
   struct cli_bc_func *funcs;
+  enum bc_state state;
 };
 
 struct cli_bc_ctx *cli_bytecode_context_alloc(void);
@@ -48,6 +55,7 @@ uint64_t cli_bytecode_context_getresult_int(struct cli_bc_ctx *ctx);
 void cli_bytecode_context_destroy(struct cli_bc_ctx *ctx);
 
 int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio);
+int cli_bytecode_prepare(struct cli_bc *bc);
 int cli_bytecode_run(const struct cli_bc *bc, struct cli_bc_ctx *ctx);
 void cli_bytecode_destroy(struct cli_bc *bc);
 
diff --git a/libclamav/bytecode_priv.h b/libclamav/bytecode_priv.h
index 4e0655a..cde7d16 100644
--- a/libclamav/bytecode_priv.h
+++ b/libclamav/bytecode_priv.h
@@ -28,6 +28,7 @@ typedef uint16_t funcid_t;
 
 struct cli_bc_callop {
     operand_t* ops;
+    uint16_t* opsizes;
     uint8_t numOps;
     funcid_t funcid;
 };
@@ -38,14 +39,6 @@ struct branch {
     bbid_t br_false;
 };
 
-#define MAX_OP (operand_t)(~0u)
-#define CONSTANT_OP (MAX_OP-1)
-#define ARG_OP (MAX_OP-1)
-struct cli_bc_value {
-    uint64_t v;
-    operand_t ref;/* this has CONSTANT_OP value for constants, and ARG_op for arguments */
-};
-
 struct cli_bc_cast {
     uint64_t mask;
     operand_t source;
@@ -78,21 +71,24 @@ struct cli_bc_func {
     uint8_t numArgs;
     uint16_t numLocals;
     uint32_t numInsts;
-    uint32_t numValues;//without constants
+    uint32_t numValues;/* without constants */
     uint32_t numConstants;
+    uint32_t numBytes;/* stack size */
     uint16_t numBB;
     uint16_t *types;
     uint32_t insn_idx;
     struct cli_bc_bb *BB;
     struct cli_bc_inst *allinsts;
-    struct cli_bc_value *constants;
+    uint64_t *constants;
 };
-
+#define MAX_OP ~0u
 struct cli_bc_ctx {
     /* id and params of toplevel function called */
     const struct cli_bc *bc;
     const struct cli_bc_func *func;
-    struct cli_bc_value *values;
+    unsigned bytes;
+    uint16_t *opsizes;
+    char *values;
     operand_t *operands;
     uint16_t funcid;
     unsigned numParams;
diff --git a/libclamav/bytecode_vm.c b/libclamav/bytecode_vm.c
index ea5ade5..e7ba741 100644
--- a/libclamav/bytecode_vm.c
+++ b/libclamav/bytecode_vm.c
@@ -55,6 +55,11 @@ static int bcfail(const char *msg, long a, long b,
 
 #define SIGNEXT(a, from) CLI_SRS(((int64_t)(a)) << (64-(from)), (64-(from)))
 
+#ifdef CL_DEBUG
+#undef always_inline
+#define always_inline
+#endif
+
 static always_inline int jump(const struct cli_bc_func *func, uint16_t bbid, struct cli_bc_bb **bb, const struct cli_bc_inst **inst,
 		unsigned *bb_inst)
 {
@@ -164,24 +169,24 @@ static void cli_stack_destroy(struct stack *stack)
 struct stack_entry {
     struct stack_entry *prev;
     const struct cli_bc_func *func;
-    struct cli_bc_value *ret;
+    operand_t ret;
     struct cli_bc_bb *bb;
     unsigned bb_inst;
-    struct cli_bc_value *values;
+    char *values;
 };
 
 static always_inline struct stack_entry *allocate_stack(struct stack *stack,
 							struct stack_entry *prev,
 							const struct cli_bc_func *func,
 							const struct cli_bc_func *func_old,
-							struct cli_bc_value *ret,
+							operand_t ret,
 							struct cli_bc_bb *bb,
 							unsigned bb_inst)
 {
     unsigned i;
-    struct cli_bc_value *values;
+    char *values;
     const unsigned numValues = func->numValues + func->numConstants;
-    struct stack_entry *entry = cli_stack_alloc(stack, sizeof(*entry) + sizeof(*values)*numValues);
+    struct stack_entry *entry = cli_stack_alloc(stack, sizeof(*entry) + sizeof(*values)*func->numBytes);
     if (!entry)
 	return NULL;
     entry->prev = prev;
@@ -190,18 +195,17 @@ static always_inline struct stack_entry *allocate_stack(struct stack *stack,
     entry->bb = bb;
     entry->bb_inst = bb_inst;
     /* we allocated room for values right after stack_entry! */
-    entry->values = values = (struct cli_bc_value*)&entry[1];
+    entry->values = values = (char*)&entry[1];
 
-    memcpy(&values[func->numValues], func->constants,
-	   sizeof(*values)*func->numConstants);
-    memset(values, 0, sizeof(*values)*func->numValues);//XXX
+    memcpy(&values[func->numBytes - func->numConstants*8], func->constants,
+	   sizeof(*values)*func->numConstants*8);
     return entry;
 }
 
 static always_inline struct stack_entry *pop_stack(struct stack *stack,
 						   struct stack_entry *stack_entry,
 						   const struct cli_bc_func **func,
-						   struct cli_bc_value **ret,
+						   operand_t *ret,
 						   struct cli_bc_bb **bb,
 						   unsigned *bb_inst)
 {
@@ -224,26 +228,43 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack,
     CHECK_EQ((p)&3, 0); 
     CHECK_EQ((p)&7, 0); 
 */
-#define WRITE8(p, x) CHECK_GT(func->numValues+func->numConstants, p);\
-    *(uint8_t*)&values[p].v = x
-#define WRITE16(p, x) CHECK_GT(func->numValues+func->numConstants, p);\
-    *(uint16_t*)&values[p].v = x
-#define WRITE32(p, x) CHECK_GT(func->numValues+func->numConstants, p);\
-    *(uint32_t*)&values[p].v = x
-#define WRITE64(p, x) CHECK_GT(func->numValues+func->numConstants, p);\
-    *(uint32_t*)&values[p].v = x
-
-#define READ1(x, p) CHECK_GT(func->numValues+func->numConstants, p);\
-    x = (*(uint8_t*)&values[p].v)&1
-#define READ8(x, p) CHECK_GT(func->numValues+func->numConstants, p);\
-    x = *(uint8_t*)&values[p].v
-#define READ16(x, p) CHECK_GT(func->numValues+func->numConstants, p);\
-    x = *(uint16_t*)&values[p].v
-#define READ32(x, p) CHECK_GT(func->numValues+func->numConstants, p);\
-    x = *(uint32_t*)&values[p].v
-#define READ64(x, p) CHECK_GT(func->numValues+func->numConstants, p);\
-    x = *(uint64_t*)&values[p].v
-
+#define WRITE8(p, x) CHECK_GT(func->numBytes, p);\
+    *(uint8_t*)&values[p] = x
+#define WRITE16(p, x) CHECK_GT(func->numBytes, p+1);\
+    CHECK_EQ((p)&1, 0);\
+    *(uint16_t*)&values[p] = x
+#define WRITE32(p, x) CHECK_GT(func->numBytes, p+3);\
+    CHECK_EQ((p)&3, 0);\
+    *(uint32_t*)&values[p] = x
+#define WRITE64(p, x) CHECK_GT(func->numBytes, p+7);\
+    CHECK_EQ((p)&7, 0);\
+    *(uint32_t*)&values[p] = x
+
+#define READ1(x, p) CHECK_GT(func->numBytes, p);\
+    x = (*(uint8_t*)&values[p])&1
+#define READ8(x, p) CHECK_GT(func->numBytes, p);\
+    x = *(uint8_t*)&values[p]
+#define READ16(x, p) CHECK_GT(func->numBytes, p+1);\
+    CHECK_EQ((p)&1, 0);\
+    x = *(uint16_t*)&values[p]
+#define READ32(x, p) CHECK_GT(func->numBytes, p+3);\
+    CHECK_EQ((p)&3, 0);\
+    x = *(uint32_t*)&values[p]
+#define READ64(x, p) CHECK_GT(func->numBytes, p+7);\
+    CHECK_EQ((p)&7, 0);\
+    x = *(uint64_t*)&values[p]
+
+#define READOLD8(x, p) CHECK_GT(func->numBytes, p);\
+    x = *(uint8_t*)&old_values[p]
+#define READOLD16(x, p) CHECK_GT(func->numBytes, p+1);\
+    CHECK_EQ((p)&1, 0);\
+    x = *(uint16_t*)&old_values[p]
+#define READOLD32(x, p) CHECK_GT(func->numBytes, p+3);\
+    CHECK_EQ((p)&3, 0);\
+    x = *(uint32_t*)&old_values[p]
+#define READOLD64(x, p) CHECK_GT(func->numBytes, p+7);\
+    CHECK_EQ((p)&7, 0);\
+    x = *(uint64_t*)&old_values[p]
 
 #define BINOP(i) inst->u.binop[i]
 
@@ -297,7 +318,7 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack,
 		    OP;\
 		    W4(inst->dest, res);\
 		    break;\
-		}\
+		}
 
 #define DEFINE_BINOP(opc, OP) DEFINE_BINOP_HELPER(opc, OP, WRITE8, WRITE8, WRITE16, WRITE32, WRITE64)
 #define DEFINE_ICMPOP(opc, OP) DEFINE_BINOP_HELPER(opc, OP, WRITE8, WRITE8, WRITE8, WRITE8, WRITE8)
@@ -339,7 +360,7 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack,
 		    OP;\
 		    WRITE64(inst->dest, res);\
 		    break;\
-		}\
+		}
 
 #define DEFINE_OP(opc) \
     case opc*5: /* fall-through */\
@@ -358,6 +379,25 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack,
 	default: CHECK_UNREACHABLE;\
     }
 
+#define DEFINE_OP_RET_N(OP, T, R0, W0) \
+    case OP: {\
+		T tmp;\
+		R0(tmp, inst->u.unaryop);\
+		CHECK_GT(stack_depth, 0);\
+		stack_depth--;\
+		stack_entry = pop_stack(&stack, stack_entry, &func, &i, &bb,\
+					&bb_inst);\
+		values = stack_entry ? stack_entry->values : ctx->values;\
+		CHECK_GT(func->numBytes, i);\
+		W0(i, tmp);\
+		if (!bb) {\
+		    stop = CL_BREAK;\
+		    continue;\
+		}\
+		inst = &bb->insts[bb_inst];\
+		break;\
+	    }
+
 static always_inline int check_sdivops(int64_t op0, int64_t op1)
 {
     return op1 == 0 || (op0 == -1 && op1 ==  (-9223372036854775807LL-1LL));
@@ -366,18 +406,16 @@ static always_inline int check_sdivops(int64_t op0, int64_t op1)
 int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct cli_bc_func *func, const struct cli_bc_inst *inst)
 {
     uint64_t tmp;
-    unsigned i, stack_depth=0, bb_inst=0, stop=0 ;
+    unsigned i, j, stack_depth=0, bb_inst=0, stop=0 ;
     struct cli_bc_func *func2;
     struct stack stack;
     struct stack_entry *stack_entry = NULL;
     struct cli_bc_bb *bb = NULL;
-    struct cli_bc_value *values = ctx->values;
-    struct cli_bc_value *value, *old_values;
+    char *values = ctx->values;
+    char *old_values;
 
     memset(&stack, 0, sizeof(stack));
     do {
-	value = &values[inst->dest];
-	CHECK_GT(func->numValues+func->numConstants, value - values);
 	switch (inst->interp_op) {
 	    DEFINE_BINOP(OP_ADD, res = op0 + op1);
 	    DEFINE_BINOP(OP_SUB, res = op0 - op1);
@@ -423,7 +461,7 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 				 READ64(res, inst->u.cast.source)));
 
 	    DEFINE_OP(OP_BRANCH)
-		stop = jump(func, (values[inst->u.branch.condition].v&1) ?
+		stop = jump(func, (values[inst->u.branch.condition]&1) ?
 			  inst->u.branch.br_true : inst->u.branch.br_false,
 			  &bb, &inst, &bb_inst);
 		continue;
@@ -432,21 +470,11 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 		stop = jump(func, inst->u.jump, &bb, &inst, &bb_inst);
 		continue;
 
-	    DEFINE_OP(OP_RET)
-		CHECK_GT(stack_depth, 0);
-		tmp = values[inst->u.unaryop].v;
-		stack_entry = pop_stack(&stack, stack_entry, &func, &value, &bb,
-					&bb_inst);
-		values = stack_entry ? stack_entry->values : ctx->values;
-		CHECK_GT(func->numValues+func->numConstants, value-values);
-		CHECK_GT(value-values, -1);
-		value->v = tmp;
-		if (!bb) {
-		    stop = CL_BREAK;
-		    continue;
-		}
-		inst = &bb->insts[bb_inst];
-		break;
+	    DEFINE_OP_RET_N(OP_RET*5, uint8_t, READ1, WRITE8);
+	    DEFINE_OP_RET_N(OP_RET*5+1, uint8_t, READ8, WRITE8);
+	    DEFINE_OP_RET_N(OP_RET*5+2, uint16_t, READ16, WRITE16);
+	    DEFINE_OP_RET_N(OP_RET*5+3, uint32_t, READ32, WRITE32);
+	    DEFINE_OP_RET_N(OP_RET*5+4, uint64_t, READ64, WRITE64);
 
 	    DEFINE_ICMPOP(OP_ICMP_EQ, res = (op0 == op1));
 	    DEFINE_ICMPOP(OP_ICMP_NE, res = (op0 != op1));
@@ -513,12 +541,55 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 		func2 = &bc->funcs[inst->u.ops.funcid];
 		CHECK_EQ(func2->numArgs, inst->u.ops.numOps);
 		old_values = values;
-		stack_entry = allocate_stack(&stack, stack_entry, func2, func, value,
+		stack_entry = allocate_stack(&stack, stack_entry, func2, func, inst->dest,
 					     bb, bb_inst);
 		values = stack_entry->values;
-		cli_dbgmsg("Executing %d\n", inst->u.ops.funcid);
-		for (i=0;i<func2->numArgs;i++)
-		    values[i] = old_values[inst->u.ops.ops[i]];
+//		cli_dbgmsg("Executing %d, -> %u (%u); %u\n", inst->u.ops.funcid,
+//			   inst->dest, inst->type, stack_depth);
+		if (stack_depth > 10000) {
+		    cli_errmsg("bytecode: stack depth exceeded\n");
+		    stop = CL_EBYTECODE;
+		    break;
+		}
+		j = 0;
+		for (i=0;i<func2->numArgs;i++) {
+		    switch (inst->u.ops.opsizes[i]) {
+			case 1: {
+			    uint8_t v;
+			    READOLD8(v, inst->u.ops.ops[i]);
+			    CHECK_GT(func2->numBytes, j);
+			    values[j++] = v;
+			    break;
+			}
+			case 2: {
+			    uint16_t v;
+			    READOLD16(v, inst->u.ops.ops[i]);
+			    j = (j+1)&~1;
+			    CHECK_GT(func2->numBytes, j);
+			    *(uint16_t*)&values[j] = v;
+			    j += 2;
+			    break;
+			}
+			case 4: {
+			    uint32_t v;
+			    READOLD32(v, inst->u.ops.ops[i]);
+			    j = (j+3)&~3;
+			    CHECK_GT(func2->numBytes, j);
+			    *(uint32_t*)&values[j] = v;
+			    j += 4;
+			    break;
+			}
+			case 8: {
+			    uint64_t v;
+			    READOLD64(v, inst->u.ops.ops[i]);
+			    j = (j+7)&~7;
+			    CHECK_GT(func2->numBytes, j);
+			    *(uint64_t*)&values[j] = v;
+			    j += 8;
+			    break;
+			}
+		    }
+		}
 		func = func2;
 		CHECK_GT(func->numBB, 0);
 		stop = jump(func, 0, &bb, &inst, &bb_inst);
diff --git a/libclamav/libclamav.map b/libclamav/libclamav.map
index ea2d7be..870c19e 100644
--- a/libclamav/libclamav.map
+++ b/libclamav/libclamav.map
@@ -145,6 +145,7 @@ CLAMAV_PRIVATE {
     base64Flush;
     have_rar;
     cli_bytecode_load;
+    cli_bytecode_prepare;
     cli_bytecode_run;
     cli_bytecode_destroy;
     cli_bytecode_context_alloc;
diff --git a/unit_tests/check_bytecode.c b/unit_tests/check_bytecode.c
index 0ea2af9..c80165a 100644
--- a/unit_tests/check_bytecode.c
+++ b/unit_tests/check_bytecode.c
@@ -53,6 +53,9 @@ static void runtest(const char *file, uint64_t expected)
     fail_unless(rc == CL_SUCCESS, "cli_bytecode_load failed");
     fclose(f);
 
+    rc = cli_bytecode_prepare(&bc);
+    fail_unless(rc == CL_SUCCESS, "cli_bytecode_prepare failed");
+
     ctx = cli_bytecode_context_alloc();
     fail_unless(!!ctx, "cli_bytecode_context_alloc failed");
 
diff --git a/unit_tests/input/arith.cbc b/unit_tests/input/arith.cbc
index 7b00a62..ba74bc8 100644
--- a/unit_tests/input/arith.cbc
+++ b/unit_tests/input/arith.cbc
@@ -1,351 +1,351 @@
 ClamBCaa`|`````|`bbep`clamcoincidencejb
 A`Lbabb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bb`bFbbbaa
-Bb`b`oa`abb`baaoa`acb`baboa`adb`bacoa`aeb`badoa`afb`baeoa`agb`bafoa`ahb`bagoa`aib`bahoa`ajb`baioa`akb`bajoa`alb`bakoa`amb`baloa`anb`bamoa`aob`banoa`b`ab`baooa`baab`bb`aoa`bbab`bbaaa`aa`b`bbbaa`baaabb`bbcaa`bbaacb`bbdaa`bcaadb`bbeaa`bdaaeb`bbfaa`beaafb`bbgaa`bfaagb`bbhaa`bgaahb`bbiaa`bhaaib`bbjaa`biaajb`bbkaa`bjaakb`bblaa`bkaalb`bbmaa`blaamb`bbnaa`bmaanb`bboaa`bnaaob`bb`ba`boab`aTcab`bE
+Bb`b`oa`abb`baaoa`acb`baboa`adb`bacoa`aeb`badoa`afb`baeoa`agb`bafoa`ahb`bagoa`aib`bahoa`ajb`baioa`akb`bajoa`alb`bakoa`amb`baloa`anb`bamoa`aob`banoa`b`ab`baooa`baab`bb`aoa`bbab`bbaaa`aa`b`bbbaa`baaabb`bbcaa`bbaacb`bbdaa`bcaadb`bbeaa`bdaaeb`bbfaa`beaafb`bbgaa`bfaagb`bbhaa`bgaahb`bbiaa`bhaaib`bbjaa`biaajb`bbkaa`bjaakb`bblaa`bkaalb`bbmaa`blaamb`bbnaa`bmaanb`bboaa`bnaaob`bb`ba`boab`aTcab`bb`bE
 A`Lb`cahaab`bahaab`bahaab`bahaab`bb`aaab`bb`aaab`bb`aaab`bb`aaab`bb`baab`bb`baab`bb`baab`bb`baab`bb`daab`bb`daab`bb`daab`bb`daab`bFbaebab
 Bah`oabbcaAaAaaaaada`AbTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 BahacoabbcaAaBooaaaddaac at Taaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 BahafoabbcaBooBooaaagdaafBnoTaaagafae
-Bb`bahoaabga at Tcaah
+Bb`bahoaabga at Tcaahb`b
 BahaioabbcaBooAaaaajdaai at Taaajahag
-Bb`bakoaabga at Tcaak
+Bb`bakoaabga at Tcaakb`b
 Bb`aaloabbdaAaAaaaamdaalAbTaaamajai
-Bb`banoaabga at Tcaan
+Bb`banoaabga at Tcaanb`b
 Bb`aaooabbdaAaDooooaab`adaao at Taab`aalak
-Bb`bbaaoaabga at Tcabaa
+Bb`bbaaoaabga at Tcabaab`b
 Bb`abbaoabbdaDooooDooooaabcadabbaDnoooTaabcaanam
-Bb`bbdaoaabga at Tcabda
+Bb`bbdaoaabga at Tcabdab`b
 Bb`abeaoabbdaDooooAaaabfadabea at Taabfab`aao
-Bb`bbgaoaabga at Tcabga
+Bb`bbgaoaabga at Tcabgab`b
 Bb`bbhaoabbeaAaAaaabiadabhaAbTaabiabbabaa
-Bb`bbjaoaabga at Tcabja
+Bb`bbjaoaabga at Tcabjab`b
 Bb`bbkaoabbeaAaHooooooooaabladabka at Taablabdabca
-Bb`bbmaoaabga at Tcabma
+Bb`bbmaoaabga at Tcabmab`b
 Bb`bbnaoabbeaHooooooooHooooooooaaboadabnaHnoooooooTaaboabfabea
-Bb`bb`boaabga at Tcab`b
+Bb`bb`boaabga at Tcab`bb`b
 Bb`bbaboabbeaHooooooooAaaabbbdabab at Taabbbbhabga
-Bb`bbcboaabga at Tcabcb
+Bb`bbcboaabga at Tcabcbb`b
 Bb`dbdboabbfaAaAaaabebdabdbAbTaabebbjabia
-Bb`bbfboaabga at Tcabfb
+Bb`bbfboaabga at Tcabfbb`b
 Bb`dbgboabbfaAaPooooooooooooooooaabhbdabgb at Taabhbblabka
-Bb`bbiboaabga at Tcabib
+Bb`bbiboaabga at Tcabibb`b
 Bb`dbjboabbfaPooooooooooooooooPooooooooooooooooaabkbdabjbPnoooooooooooooooTaabkbbnabma
-Bb`bblboaabga at Tcablb
+Bb`bblboaabga at Tcablbb`b
 Bb`dbmboabbfaPooooooooooooooooAaaabnbdabmb at Taabnbb`bboa
-Bb`bboboaabga at Tcabob
-BTcaAaE
+Bb`bboboaabga at Tcabobb`b
+BTcaAab`bE
 A`Lbdbahaab`bahaab`bahaab`bb`aaab`bb`aaab`bb`aaab`bb`baab`bb`baab`bb`baab`bb`daab`bb`daab`bb`daab`bFbmcbia
 Bah`oabbhaBooAaaaaada`BnoTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 BahacoabbhaAaBooaaaddaacAbTaaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 BahafoabbhaAaAaaaagdaaf at Taaagafae
-Bb`bahoaabga at Tcaah
+Bb`bahoaabga at Tcaahb`b
 Bb`aaioabbiaDooooAaaaajdaaiDnoooTaaajahag
-Bb`bakoaabga at Tcaak
+Bb`bakoaabga at Tcaakb`b
 Bb`aaloabbiaAaDooooaaamdaalAbTaaamajai
-Bb`banoaabga at Tcaan
+Bb`banoaabga at Tcaanb`b
 Bb`aaooabbiaAaAaaab`adaao at Taab`aalak
-Bb`bbaaoaabga at Tcabaa
+Bb`bbaaoaabga at Tcabaab`b
 Bb`bbbaoabbjaHooooooooAaaabcadabbaHnoooooooTaabcaanam
-Bb`bbdaoaabga at Tcabda
+Bb`bbdaoaabga at Tcabdab`b
 Bb`bbeaoabbjaAaHooooooooaabfadabeaAbTaabfab`aao
-Bb`bbgaoaabga at Tcabga
+Bb`bbgaoaabga at Tcabgab`b
 Bb`bbhaoabbjaAaAaaabiadabha at Taabiabbabaa
-Bb`bbjaoaabga at Tcabja
+Bb`bbjaoaabga at Tcabjab`b
 Bb`dbkaoabbkaPooooooooooooooooAaaabladabkaPnoooooooooooooooTaablabdabca
-Bb`bbmaoaabga at Tcabma
+Bb`bbmaoaabga at Tcabmab`b
 Bb`dbnaoabbkaAaPooooooooooooooooaaboadabnaAbTaaboabfabea
-Bb`bb`boaabga at Tcab`b
+Bb`bb`boaabga at Tcab`bb`b
 Bb`dbaboabbkaAaAaaabbbdabab at Taabbbbhabga
-Bb`bbcboaabga at Tcabcb
-BTcaAdE
+Bb`bbcboaabga at Tcabcbb`b
+BTcaAdb`bE
 A`Lb`cahaab`bahaab`bahaab`bahaab`bb`aaab`bb`aaab`bb`aaab`bb`aaab`bb`baab`bb`baab`bb`baab`bb`baab`bb`daab`bb`daab`bb`daab`bb`daab`bFbaebab
 Bah`oabblaBooAaaaaada`BooTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 BahacoabblaBooBooaaaddaacAaTaaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 BahafoabblaAaAaaaagdaafAaTaaagafae
-Bb`bahoaabga at Tcaah
+Bb`bahoaabga at Tcaahb`b
 BahaioabblaBaaBcbaaajdaaiBceTaaajahag
-Bb`bakoaabga at Tcaak
+Bb`bakoaabga at Tcaakb`b
 Bb`aaloabbmaDooooAaaaamdaalDooooTaaamajai
-Bb`banoaabga at Tcaan
+Bb`banoaabga at Tcaanb`b
 Bb`aaooabbmaDooooDooooaab`adaaoAaTaab`aalak
-Bb`bbaaoaabga at Tcabaa
+Bb`bbaaoaabga at Tcabaab`b
 Bb`abbaoabbmaAaAaaabcadabbaAaTaabcaanam
-Bb`bbdaoaabga at Tcabda
+Bb`bbdaoaabga at Tcabdab`b
 Bb`abeaoabbmaBckCgfcaabfadabeaDe`afTaabfab`aao
-Bb`bbgaoaabga at Tcabga
+Bb`bbgaoaabga at Tcabgab`b
 Bb`bbhaoabbnaHooooooooAaaabiadabhaHooooooooTaabiabbabaa
-Bb`bbjaoaabga at Tcabja
+Bb`bbjaoaabga at Tcabjab`b
 Bb`bbkaoabbnaHooooooooHooooooooaabladabkaAaTaablabdabca
-Bb`bbmaoaabga at Tcabma
+Bb`bbmaoaabga at Tcabmab`b
 Bb`bbnaoabbnaAaAaaaboadabnaAaTaaboabfabea
-Bb`bb`boaabga at Tcab`b
+Bb`bb`boaabga at Tcab`bb`b
 Bb`bbaboabbnaE`emkbEhnmdmaabbbdababH`h`jlgbgTaabbbbhabga
-Bb`bbcboaabga at Tcabcb
+Bb`bbcboaabga at Tcabcbb`b
 Bb`dbdboabboaPooooooooooooooooAaaabebdabdbPooooooooooooooooTaabebbjabia
-Bb`bbfboaabga at Tcabfb
+Bb`bbfboaabga at Tcabfbb`b
 Bb`dbgboabboaPooooooooooooooooPooooooooooooooooaabhbdabgbAaTaabhbblabka
-Bb`bbiboaabga at Tcabib
+Bb`bbiboaabga at Tcabibb`b
 Bb`dbjboabboaAaAaaabkbdabjbAaTaabkbbnabma
-Bb`bblboaabga at Tcablb
+Bb`bblboaabga at Tcablbb`b
 Bb`dbmboabboaImaghnanbdIogjdckg`baabnbdabmbPcfifjghokjjemflgTaabnbb`bboa
-Bb`bboboaabga at Tcabob
-BTcaB`aE
+Bb`bboboaabga at Tcabobb`b
+BTcaB`ab`bE
 A`Lacb`aaab`bFafac
 Bb`a`oabbabDjnmoAgaaaada`DfddbTaaaaabaa
-Bb`baboaabga at Tcaab
-BTcaB`dE
+Bb`baboaabga at Tcaabb`b
+BTcaB`db`bE
 A`Lbfaahaab`bahaab`bahaab`bahaab`bahahaab`bahaab`bb`aaab`bFbebao
 Bah`oabbdbAaBooaaaada`BooTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 BahacoabbdbBooAaaaaddaacBooTaaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 BahafoabbdbBooBooaaagdaafAaTaaagafae
-Bb`bahoaabga at Tcaah
+Bb`bahoaabga at Tcaahb`b
 BahaioabbdbAaAaaaajdaaiAaTaaajahag
-Bb`bakoaabga at Tcaak
+Bb`bakoaabga at Tcaakb`b
 BahaloabbcaBnoAeahamoabbdbAfalaaandaamAbTaaanajai
-Bb`baooaabga at Tcaao
+Bb`baooaabga at Tcaaob`b
 Bahb`aoabbdbalAbaabaadab`aAaTaabaaalak
-Bb`bbbaoaabga at Tcabba
+Bb`bbbaoaabga at Tcabbab`b
 Bb`abcaoabbebDjnmoAgaabdadabcaDdkooTaabdaanam
-Bb`bbeaoaabga at Tcabea
-BTcaC``aE
+Bb`bbeaoaabga at Tcabeab`b
+BTcaC``ab`bE
 A`Laoahaab`bahaab`bahaab`bb`aaab`bb`aaab`bFbjaak
 Bah`oabblbBooAaaaaada`@Taaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 BahacoabbhbBooAaaaaddaac at Taaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 BahafoabblbAaBooaaagdaaf at Taaagafae
-Bb`bahoaabga at Tcaah
+Bb`bahoaabga at Tcaahb`b
 Bb`aaioabbmbDinmoAgaaajdaaiDmoooTaaajahag
-Bb`bakoaabga at Tcaak
+Bb`bakoaabga at Tcaakb`b
 Bb`aaloabbibDinmoAgaaamdaalAfTaaamajai
-Bb`banoaabga at Tcaan
-BTcaC``dE
+Bb`banoaabga at Tcaanb`b
+BTcaC``db`bE
 A`Lalahaab`bahaab`bahaab`bb`aaab`bFbeaai
 Bah`oabb`cAaAaaaaada`AbTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 Bahacoabb`cAa at aaaddaacAaTaaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 Bahafoabb`cBnoAbaaagdaafBhoTaaagafae
-Bb`bahoaabga at Tcaah
+Bb`bahoaabga at Tcaahb`b
 Bb`aaioabbacDnojoAbaaajdaaiDhoknTaaajahag
-Bb`bakoaabga at Tcaak
-BTcaD```aE
+Bb`bakoaabga at Tcaakb`b
+BTcaD```ab`bE
 A`Lagahaab`bahahaab`bFalae
 Bah`oabbdcBnoAaaaaada`BogTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 BahacoabbcaBnoAeahadoabbdcacAaaaaedaadAaTaaaeadac
-Bb`bafoaabga at Tcaaf
-BTcaD```dE
+Bb`bafoaabga at Tcaafb`b
+BTcaD```db`bE
 A`Lafahaab`bahaab`bFakae
 Bah`oabbhcBnoAaaaaada`BooTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 BahacoabbhcBngAaaaaddaacBocTaaadadac
-Bb`baeoaabga at Tcaae
-BTcaE````aE
+Bb`baeoaabga at Tcaaeb`b
+BTcaE````ab`bE
 A`Lalahaab`bb`aaab`bb`baab`bb`daab`bFbeaai
 Bah`oabblcBjeAoaaaada`AjTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 Bb`aacoabbmcDlkjeD```oaaaddaacD```eTaaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 Bb`bafoabbncHdcbalkjeG``````oaaagdaafG``````jTaaagafae
-Bb`bahoaabga at Tcaah
+Bb`bahoaabga at Tcaahb`b
 Bb`daioabbocPdcbahgfedcbalkjeG``````oaaajdaaiG``````fTaaajahag
-Bb`bakoaabga at Tcaak
-BTcaE````dE
+Bb`bakoaabga at Tcaakb`b
+BTcaE````db`bE
 A`Lalahaab`bb`aaab`bb`baab`bb`daab`bFbeaai
 Bah`oabb`dBjeAoaaaada`BoeTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 Bb`aacoabbadDlkjeD```oaaaddaacDlkjoTaaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 Bb`bafoabbbdHdcbalkjeG``````oaaagdaafHdcbalkoeTaaagafae
-Bb`bahoaabga at Tcaah
+Bb`bahoaabga at Tcaahb`b
 Bb`daioabbcdPdcbahgfedcbalkjeG``````oaaajdaaiPdcbahgoedcbalkjeTaaajahag
-Bb`bakoaabga at Tcaak
-BTcaF`````aE
+Bb`bakoaabga at Tcaakb`b
+BTcaF`````ab`bE
 A`Lalahaab`bb`aaab`bb`baab`bb`daab`bFbeaai
 Bah`oabbddBjeB`oaaaada`BjjTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 Bb`aacoabbedDjejeD``ooaaaddaacDjeejTaaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 Bb`bafoabbfdHjejejejeH``ooooooaaagdaafHjeejejejTaaagafae
-Bb`bahoaabga at Tcaah
+Bb`bahoaabga at Tcaahb`b
 Bb`daioabbgdPjejejejejejejejeP``ooooooooooooooaaajdaaiPjeejejejejejejejTaaajahag
-Bb`bakoaabga at Tcaak
-BTcaF`````dE
+Bb`bakoaabga at Tcaakb`b
+BTcaF`````db`bE
 A`Laib`aaab`bb`baab`bb`daab`bFb`aag
 Bb`a`oaabhdBloaaaada`DloooTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 Bb`bacoaabidDjoooaaaddaacHjoooooooTaaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 Bb`dafoaabjdHjoooooooaaagdaafPjoooooooooooooooTaaagafae
-Bb`bahoaabga at Tcaah
-BTcaG``````aE
+Bb`bahoaabga at Tcaahb`b
+BTcaG``````ab`bE
 A`Laib`aaab`bb`baab`bb`daab`bFb`aag
 Bb`a`oaabkdBloaaaada`BloTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 Bb`bacoaabldDloooaaaddaacDloooTaaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 Bb`dafoaabmdHloooooooaaagdaafHloooooooTaaagafae
-Bb`bahoaabga at Tcaah
-BTcaG``````dE
+Bb`bahoaabga at Tcaahb`b
+BTcaG``````db`bE
 A`Laiahaab`bb`aaab`bb`baab`bFb`aag
 Bah`oaabndDmnnoaaaada`BmnTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 Bb`aacoaabodHmnnomjnmaaaddaacDmnnoTaaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 Bb`bafoaab`ePonnkmnnomjnmonnkaaagdaafHonnkmnnoTaaagafae
-Bb`bahoaabga at Tcaah
-BTcaH```````aE
+Bb`bahoaabga at Tcaahb`b
+BTcaH```````ab`bE
 A`Laob`baab`bb`baab`bb`baab`bb`baab`bb`baab`bFbjaak
 Bb`b`oadbaeHooooooooAb at Adaaaada`CijbTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 Bb`bacoadbaeHooooooooHooooooooAaHooooooooaaaddaacCbbcTaaadadac
-Bb`baeoaabga at Tcaae
+Bb`baeoaabga at Tcaaeb`b
 Bb`bafoadbaeHoooooooo at AcHnoooooooaaagdaafCcjbTaaagafae
-Bb`bahoaabga at Tcaah
+Bb`bahoaabga at Tcaahb`b
 Bb`baioadbaeHoooooooo at Ac@aaajdaaiCcnbTaaajahag
-Bb`bakoaabga at Tcaak
+Bb`bakoaabga at Tcaakb`b
 Bb`baloadbaeHoooooooo@@HooooooooaaamdaalBkbTaaamajai
-Bb`banoaabga at Tcaan
-BTcaH```````dE
+Bb`banoaabga at Tcaanb`b
+BTcaH```````db`bE
 A`Lafb`baab`bb`baab`bFakae
 Bb`b`oacbbeAdAeAfaaaada`AeTaaaaabaa
-Bb`baboaabga at Tcaab
+Bb`baboaabga at Tcaabb`b
 Bb`bacoacbbe at AeAfaaaddaacAfTaaadadac
-Bb`baeoaabga at Tcaae
-BTcaH```````hE
+Bb`baeoaabga at Tcaaeb`b
+BTcaH```````hb`bE
 AbLaaahahahFabaa
-Bahaba`aa`TcaabE
+Bahaba`aa`TcaabahE
 AbLaab`ab`ab`aFabaa
-Bb`aaba`aa`TcaabE
+Bb`aaba`aa`Tcaabb`aE
 AbLaab`bb`bb`bFabaa
-Bb`baba`aa`TcaabE
+Bb`baba`aa`Tcaabb`bE
 AbLaab`db`db`dFabaa
-Bb`daba`aa`TcaabE
+Bb`daba`aa`Tcaabb`dE
 AaLaab`bb`bFabaa
-Bb`baae`Aa`TcaaaE
+Bb`baae`Aa`Tcaaab`bE
 AbLaaahahahFabaa
-Bahabb``aaTcaabE
+Bahabb``aaTcaabahE
 AbLaab`ab`ab`aFabaa
-Bb`aabb``aaTcaabE
+Bb`aabb``aaTcaabb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babb``aaTcaabE
+Bb`babb``aaTcaabb`bE
 AbLaab`db`db`dFabaa
-Bb`dabb``aaTcaabE
+Bb`dabb``aaTcaabb`dE
 AbLaaahahahFabaa
-Bahabc`aa`TcaabE
+Bahabc`aa`TcaabahE
 AbLaab`ab`ab`aFabaa
-Bb`aabc`aa`TcaabE
+Bb`aabc`aa`Tcaabb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babc`aa`TcaabE
+Bb`babc`aa`Tcaabb`bE
 AbLaab`db`db`dFabaa
-Bb`dabc`aa`TcaabE
-AbLadahahb`bb`bb`bahFaeaa
-Bb`bab`a`b`bac`aaab`badd`abacahaen`adTcaaeE
-AbLadb`ab`ab`bb`bb`bb`aFaeaa
-Bb`bab`a`b`bac`aaab`badd`abacb`aaen`adTcaaeE
+Bb`dabc`aa`Tcaabb`dE
+AbLaaahahahFabaa
+Bahabd``aaTcaabahE
+AbLaab`ab`ab`aFabaa
+Bb`aabd``aaTcaabb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babd``aaTcaabE
+Bb`babd``aaTcaabb`bE
 AbLaab`db`db`dFabaa
-Bb`dabd``aaTcaabE
+Bb`dabd``aaTcaabb`dE
 AbLadahahb`bb`bb`bahFaeaa
-Bb`babo``b`baco`aab`bade`abacahaen`adTcaaeE
+Bb`babo``b`baco`aab`bade`abacahaen`adTcaaeahE
 AbLadb`ab`ab`bb`bb`bb`aFaeaa
-Bb`babo``b`baco`aab`bade`abacb`aaen`adTcaaeE
+Bb`babo``b`baco`aab`bade`abacb`aaen`adTcaaeb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babe``aaTcaabE
+Bb`babe``aaTcaabb`bE
 AbLaab`db`db`dFabaa
-Bb`dabe``aaTcaabE
-AbLadahahb`bb`bb`bahFaeaa
-Bb`bab`a`b`bac`aaab`badf`abacahaen`adTcaaeE
-AbLadb`ab`ab`bb`bb`bb`aFaeaa
-Bb`bab`a`b`bac`aaab`badf`abacb`aaen`adTcaaeE
+Bb`dabe``aaTcaabb`dE
+AbLaaahahahFabaa
+Bahabf``aaTcaabahE
+AbLaab`ab`ab`aFabaa
+Bb`aabf``aaTcaabb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babf``aaTcaabE
+Bb`babf``aaTcaabb`bE
 AbLaab`db`db`dFabaa
-Bb`dabf``aaTcaabE
+Bb`dabf``aaTcaabb`dE
 AbLadahahb`bb`bb`bahFaeaa
-Bb`babo``b`baco`aab`badg`abacahaen`adTcaaeE
+Bb`babo``b`baco`aab`badg`abacahaen`adTcaaeahE
 AbLadb`ab`ab`bb`bb`bb`aFaeaa
-Bb`babo``b`baco`aab`badg`abacb`aaen`adTcaaeE
+Bb`babo``b`baco`aab`badg`abacb`aaen`adTcaaeb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babg``aaTcaabE
+Bb`babg``aaTcaabb`bE
 AbLaab`db`db`dFabaa
-Bb`dabg``aaTcaabE
+Bb`dabg``aaTcaabb`dE
 AbLacahb`bb`bb`bahFadaa
-Bb`babo``b`bach`abaaahadn`acTcaadE
+Bb`babo``b`bach`abaaahadn`acTcaadahE
 AbLacb`ab`bb`bb`bb`aFadaa
-Bb`babo``b`bach`abaab`aadn`acTcaadE
+Bb`babo``b`bach`abaab`aadn`acTcaadb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babh``aaTcaabE
+Bb`babh``aaTcaabb`bE
 AbLabb`db`bb`db`dFacaa
-Bb`dab`aaab`dach``abTcaacE
+Bb`dab`aaab`dach``abTcaacb`dE
 AbLacahb`bb`bb`bahFadaa
-Bb`bab`a`b`baci`abaaahadn`acTcaadE
+Bb`bab`a`b`baci`abaaahadn`acTcaadahE
 AbLacb`ab`bb`bb`bb`aFadaa
-Bb`bab`a`b`baci`abaab`aadn`acTcaadE
+Bb`bab`a`b`baci`abaab`aadn`acTcaadb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babi``aaTcaabE
+Bb`babi``aaTcaabb`bE
 AbLabb`db`bb`db`dFacaa
-Bb`dab`aaab`daci``abTcaacE
+Bb`dab`aaab`daci``abTcaacb`dE
 AbLadahahb`bb`bb`bahFaeaa
-Bb`babo``b`baco`aab`badj`abacahaen`adTcaaeE
+Bb`babo``b`baco`aab`badj`abacahaen`adTcaaeahE
 AbLadb`ab`ab`bb`bb`bb`aFaeaa
-Bb`babo``b`baco`aab`badj`abacb`aaen`adTcaaeE
+Bb`babo``b`baco`aab`badj`abacb`aaen`adTcaaeb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babj``aaTcaabE
+Bb`babj``aaTcaabb`bE
 AbLaab`db`db`dFabaa
-Bb`dabj``aaTcaabE
+Bb`dabj``aaTcaabb`dE
 AbLaaahahahFabaa
-Bahabk`aa`TcaabE
+Bahabk`aa`TcaabahE
 AbLaab`ab`ab`aFabaa
-Bb`aabk`aa`TcaabE
+Bb`aabk`aa`Tcaabb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babk`aa`TcaabE
+Bb`babk`aa`Tcaabb`bE
 AbLaab`db`db`dFabaa
-Bb`dabk`aa`TcaabE
+Bb`dabk`aa`Tcaabb`dE
 AbLaaahahahFabaa
-Bahabl`aa`TcaabE
+Bahabl`aa`TcaabahE
 AbLaab`ab`ab`aFabaa
-Bb`aabl`aa`TcaabE
+Bb`aabl`aa`Tcaabb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babl`aa`TcaabE
+Bb`babl`aa`Tcaabb`bE
 AbLaab`db`db`dFabaa
-Bb`dabl`aa`TcaabE
+Bb`dabl`aa`Tcaabb`dE
 AbLaaahahahFabaa
-Bahabm`aa`TcaabE
+Bahabm`aa`TcaabahE
 AbLaab`ab`ab`aFabaa
-Bb`aabm`aa`TcaabE
+Bb`aabm`aa`Tcaabb`aE
 AbLaab`bb`bb`bFabaa
-Bb`babm`aa`TcaabE
+Bb`babm`aa`Tcaabb`bE
 AbLaab`db`db`dFabaa
-Bb`dabm`aa`TcaabE
+Bb`dabm`aa`Tcaabb`dE
 AaLaaahb`aFabaa
-Bb`aaao``TcaaaE
+Bb`aaao``Tcaaab`aE
 AaLaab`ab`bFabaa
-Bb`baao``TcaaaE
+Bb`baao``Tcaaab`bE
 AaLaab`bb`dFabaa
-Bb`daao``TcaaaE
+Bb`daao``Tcaaab`dE
 AaLaaahb`aFabaa
-Bb`aaa`a`TcaaaE
+Bb`aaa`a`Tcaaab`aE
 AaLaab`ab`bFabaa
-Bb`baa`a`TcaaaE
+Bb`baa`a`Tcaaab`bE
 AaLaab`bb`dFabaa
-Bb`daa`a`TcaaaE
+Bb`daa`a`Tcaaab`dE
 AaLaab`aahFabaa
-Bahaan``TcaaaE
+Bahaan``TcaaaahE
 AaLaab`bb`aFabaa
-Bb`aaan``TcaaaE
+Bb`aaan``Tcaaab`aE
 AaLaab`db`bFabaa
-Bb`baan``TcaaaE
+Bb`baan``Tcaaab`bE
 AdLbmab`bb`bb`bb`baab`baab`bb`baab`bb`baab`bb`baab`bb`baab`bb`baab`bb`baab`bb`baab`bb`baab`bb`bFbnaaa
-Baaadma`aab`bae`aadaaafjaaaabb`bagl`aeAbb`bahnaafaeagaaaija`aab`bajl`ahAdb`baknaaiajahaaalmaaaabb`baml`akAhb`bannaalakamaaaoha`acb`bb`al`anB`ab`bbaanaaob`aanaabbafaaaacb`bbcal`baaB`bb`bbdanabbabaabcaaabeahaabacb`bbfal`bdaB`db`bbganabeabdabfaaabhafa`acb`bbial`bgaB`hb`bbjanabhabiabgaaabkada`aab`bblal`bjaC``ab`bbmanabkablabjaaabnadaaaabb`bboal`bmaC``bb`bb`bnabnabmaboaTcab`bE
+Baaadma`aab`bae`aadaaafjaaaabb`bagl`aeAbb`bahnaafaeagaaaija`aab`bajl`ahAdb`baknaaiajahaaalmaaaabb`baml`akAhb`bannaalakamaaaoha`acb`bb`al`anB`ab`bbaanaaob`aanaabbafaaaacb`bbcal`baaB`bb`bbdanabbabaabcaaabeahaabacb`bbfal`bdaB`db`bbganabeabdabfaaabhafa`acb`bbial`bgaB`hb`bbjanabhabiabgaaabkada`aab`bblal`bjaC``ab`bbmanabkablabjaaabnadaaaabb`bboal`bmaC``bb`bb`bnabnabmaboaTcab`bb`bE
 AcLabb`bb`bb`baab`bFacaa
-Baaacea`@b`badnaacaaabTcaadE
+Baaacea`@b`badnaacaaabTcaadb`bE
diff --git a/unit_tests/input/retmagic.cbc b/unit_tests/input/retmagic.cbc
index 59b1346..87d0044 100644
--- a/unit_tests/input/retmagic.cbc
+++ b/unit_tests/input/retmagic.cbc
@@ -1,3 +1,3 @@
 ClamBCaa`|`````|`aap`clamcoincidencejb
 A`L`Faaaa
-BTcaHm``odcbaE
+BTcaHm``odcbab`bE

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list