[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