int main() { LDAPMessage_t *req_bind, *req_search, *req_unbind; LDAPMessage_t *rsp_bind, *rsp_search1, *rsp_search2, *rsp_search_done; int sock = accept_single_connection(3389); fprintf(stderr, "Receiving LDAP message...\n"); req_bind = receive_ldap_message(sock); assert(req_bind); assert(req_bind->protocolOp.present == LDAPMessage__protocolOp_PR_bindRequest); assert(req_bind->protocolOp.choice.bindRequest.version == 3); fprintf(stderr, "Received BindRequest...\n"); asn_fprint(stderr, &asn_DEF_LDAPMessage, req_bind); fprintf(stderr, "Sending BindReply...\n"); rsp_bind = bind_response_ok(req_bind->messageID, &req_bind->protocolOp.choice.bindRequest.name); asn_fprint(stderr, &asn_DEF_LDAPMessage, rsp_bind); send_ldap_message(sock, rsp_bind); req_search = receive_ldap_message(sock); assert(req_search->protocolOp.present == LDAPMessage__protocolOp_PR_searchRequest); fprintf(stderr, "Received SearchRequest...\n"); xer_fprint(stderr, &asn_DEF_LDAPMessage, req_search); rsp_search1 = search_result_entry(req_search->messageID, "Lev Walkin", "*****@*****.**", "avatar.jpg"); asn_fprint(stderr, &asn_DEF_LDAPMessage, rsp_search1); send_ldap_message(sock, rsp_search1); rsp_search2 = search_result_entry(req_search->messageID, "Olga Bobrova", "*****@*****.**", NULL); asn_fprint(stderr, &asn_DEF_LDAPMessage, rsp_search2); send_ldap_message(sock, rsp_search2); rsp_search_done = search_result_done(req_search->messageID, &req_search->protocolOp.choice.searchRequest.baseObject); asn_fprint(stderr, &asn_DEF_LDAPMessage, rsp_search_done); send_ldap_message(sock, rsp_search_done); req_unbind = receive_ldap_message(sock); assert(req_unbind->protocolOp.present == LDAPMessage__protocolOp_PR_unbindRequest); xer_fprint(stderr, &asn_DEF_LDAPMessage, req_unbind); ASN_STRUCT_FREE(asn_DEF_LDAPMessage, req_bind); ASN_STRUCT_FREE(asn_DEF_LDAPMessage, req_search); ASN_STRUCT_FREE(asn_DEF_LDAPMessage, req_unbind); ASN_STRUCT_FREE(asn_DEF_LDAPMessage, rsp_bind); ASN_STRUCT_FREE(asn_DEF_LDAPMessage, rsp_search1); ASN_STRUCT_FREE(asn_DEF_LDAPMessage, rsp_search2); ASN_STRUCT_FREE(asn_DEF_LDAPMessage, rsp_search_done); return 0; }
static int save_object(void *bs, asn_TYPE_descriptor_t *td) { asn_enc_rval_t rval; /* Return value */ int i; rval = der_encode(td, bs, _buf_writer, 0); if (rval.encoded == -1) { fprintf(stderr, "Cannot encode %s: %s\n", rval.failed_type->name, strerror(errno)); assert(rval.encoded != -1); return -1; /* JIC */ } buf[buf_offset++] = 123; /* Finalize with garbage */ asn_fprint(stderr, td, bs); xer_fprint(stderr, td, bs); printf("OUT: ["); for(i = 0; i < buf_offset; i++) printf(" %02x", buf[i]); printf("]\n"); return 0; }
static void ent_debug(const char *str, LDAPMessage_t *msg) { if (!config.debug) { return; } fprintf(stdout, "%s\n", str); asn_fprint(stdout, &asn_DEF_LDAPMessage, msg); fprintf(stdout, "\n"); }
static int load_object(void *bs, asn_TYPE_descriptor_t *td) { asn_dec_rval_t rval; fprintf(stderr, "\nLOADING OBJECT OF SIZE %d\n", buf_offset); rval = ber_decode(0, td, (void **)&bs, buf, buf_offset); assert(rval.code == RC_OK); asn_fprint(stderr, td, bs); return (rval.code == RC_OK)?0:-1; }
int main(int ac, char **av) { T_t t; (void)ac; /* Unused argument */ (void)av; /* Unused argument */ /* Check exact buf1 */ check(&t, buf1, sizeof(buf1), sizeof(buf1)); compare(&t, buf1_reconstr, sizeof(buf1_reconstr)); asn_fprint(stderr, &asn_DEF_T, &t); asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); /* Check slightly more than buf1 */ check(&t, buf1, sizeof(buf1) + 10, sizeof(buf1)); compare(&t, buf1_reconstr, sizeof(buf1_reconstr)); asn_fprint(stderr, &asn_DEF_T, &t); asn_DEF_T.free_struct(&asn_DEF_T, &t, 1); /* Split the buffer in parts and check decoder restartability */ partial_read(buf1, sizeof(buf1)); return 0; }
static void check(LogLine_t *tp, uint8_t *ptr, int size, size_t consumed) { asn_dec_rval_t rval; tp = memset(tp, 0, sizeof(*tp)); fprintf(stderr, "Buf %p (%d)\n", ptr, size); rval = ber_decode(0, &asn_DEF_LogLine, (void **)&tp, ptr, size); fprintf(stderr, "Returned code %d, consumed %d\n", (int)rval.code, (int)rval.consumed); assert(rval.code == RC_OK); assert(rval.consumed == consumed); asn_fprint(stderr, &asn_DEF_LogLine, tp); asn_DEF_LogLine.free_struct(&asn_DEF_LogLine, tp, 1); }
static void check_serialize() { LogLine_t ll; VariablePartSet_t vps; VariablePart_t vp; VisibleString_t vpart; asn_enc_rval_t erval; int i; memset(&ll, 0, sizeof(ll)); memset(&vps, 0, sizeof(vps)); memset(&vp, 0, sizeof(vp)); memset(&vpart, 0, sizeof(vpart)); vpart.buf = "123"; vpart.size = 3; vp.present = VariablePart_PR_vset; ASN_SET_ADD(&vp.choice.vset, &vpart); vps.resolution.accept_as = accept_as_unknown; ASN_SEQUENCE_ADD(&vps.vparts, &vp); ASN_SEQUENCE_ADD(&ll.varsets, &vps); ll.line_digest.buf = "zzz\007"; ll.line_digest.size = 4; asn_fprint(stderr, &asn_DEF_LogLine, &ll); buf_size = 128; buf = alloca(buf_size); erval = der_encode(&asn_DEF_LogLine, &ll, buf_fill, 0); assert(erval.encoded > 1); fprintf(stderr, "Encoded in %d bytes\n", erval.encoded); fprintf(stderr, "\n"); for(i = 0; i < buf_pos; i++) { fprintf(stderr, "%d ", buf[i]); } fprintf(stderr, "\n\n"); assert(erval.encoded == sizeof(buf0)); assert(memcmp(buf0, buf, sizeof(buf0)) == 0); }
void test_AddRequest() { /// Building a AddRequest /// DNDSMessage_t *msg; // a DNDS Message DNDSObject_t *objClient; // a DS Object DNDSMessage_new(&msg); // DNDSMessage_set_version(msg, 1); DNDSMessage_set_channel(msg, 0); DNDSMessage_set_pdu(msg, pdu_PR_dsm); // Directory Service Message DSMessage_set_seqNumber(msg, 1); DSMessage_set_ackNumber(msg, 1); // seq XOR ack DSMessage_set_operation(msg, dsop_PR_addRequest); // DSMessage_set_action(msg, action_addClient); AddRequest_set_objectType(msg, DNDSObject_PR_client, &objClient); // Client_set_id(objClient, 987); Client_set_email(objClient, "test@test", 9); Client_set_password(objClient, "test", 4); // Client_set_status(objClient, 0); /// Encoding part asn_enc_rval_t ec; // Encoder return value FILE *fp = fopen("dnds.ber", "wb"); // BER output ec = der_encode(&asn_DEF_DNDSMessage, msg, write_out, fp); fclose(fp); xer_fprint(stdout, &asn_DEF_DNDSMessage, msg); asn_fprint(stdout, &asn_DEF_DNDSMessage, msg); DNDSMessage_del(msg); }
static void check_serialize() { LogLine_t ll; VariablePartSet_t *vps; VariablePart_t *vp; VisibleString_t *vpart; asn_enc_rval_t erval; int i; memset(&ll, 0, sizeof(ll)); vps = calloc(1, sizeof(*vps)); vp = calloc(1, sizeof(*vp)); vpart = OCTET_STRING_new_fromBuf(&asn_DEF_VisibleString, "123", 3); vp->present = VariablePart_PR_vset; ASN_SET_ADD(&vp->choice.vset, vpart); vps->resolution.accept_as = accept_as_unknown; ASN_SEQUENCE_ADD(&vps->vparts, vp); ASN_SEQUENCE_ADD(&ll.varsets, vps); OCTET_STRING_fromBuf(&ll.line_digest, "zzz\007", 4); asn_fprint(stderr, &asn_DEF_LogLine, &ll); buf_size = 128; uint8_t scratch[buf_size]; buf = scratch; erval = der_encode(&asn_DEF_LogLine, &ll, buf_fill, 0); assert(erval.encoded > 1); fprintf(stderr, "Encoded in %zd bytes\n", erval.encoded); fprintf(stderr, "\n"); for(i = 0; i < buf_pos; i++) { fprintf(stderr, "%d ", buf[i]); } fprintf(stderr, "\n\n"); assert(erval.encoded == sizeof(buf0)); assert(memcmp(buf0, buf, sizeof(buf0)) == 0); ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_LogLine, &ll); return; }
int main(int ac, char *av[]) { static asn_TYPE_descriptor_t *pduType = &PDU_Type; ssize_t suggested_bufsize = 8192; /* close or equal to stdio buffer */ int number_of_iterations = 1; int num; int ch; pduInit(); /* Figure out if Unaligned PER needs to be default */ if(pduType->uper_decoder) iform = INP_PER; /* * Pocess the command-line argments. */ while((ch = getopt(ac, av, "i:o:1b:cdn:p:hs:" JUNKOPT)) != -1) switch(ch) { case 'i': if(optarg[0] == 'b') { iform = INP_BER; break; } if(optarg[0] == 'x') { iform = INP_XER; break; } if(pduType->uper_decoder && optarg[0] == 'p') { iform = INP_PER; break; } fprintf(stderr, "-i<format>: '%s': improper format selector\n", optarg); exit(EX_UNAVAILABLE); case 'o': if(optarg[0] == 'd') { oform = OUT_DER; break; } if(pduType->uper_encoder && optarg[0] == 'p') { oform = OUT_PER; break; } if(optarg[0] == 'x') { oform = OUT_XER; break; } if(optarg[0] == 't') { oform = OUT_TEXT; break; } if(optarg[0] == 'n') { oform = OUT_NULL; break; } fprintf(stderr, "-o<format>: '%s': improper format selector\n", optarg); exit(EX_UNAVAILABLE); case '1': opt_onepdu = 1; break; case 'b': suggested_bufsize = atoi(optarg); if(suggested_bufsize < 1 || suggested_bufsize > 16 * 1024 * 1024) { fprintf(stderr, "-b %s: Improper buffer size (1..16M)\n", optarg); exit(EX_UNAVAILABLE); } break; case 'c': opt_check = 1; break; case 'd': opt_debug++; /* Double -dd means ASN.1 debug */ break; case 'n': number_of_iterations = atoi(optarg); if(number_of_iterations < 1) { fprintf(stderr, "-n %s: Improper iterations count\n", optarg); exit(EX_UNAVAILABLE); } break; case 'p': if(strcmp(optarg, "er-nopad") == 0) { opt_nopad = 1; break; } #ifdef ASN_PDU_COLLECTION if(strcmp(optarg, "list") == 0) { asn_TYPE_descriptor_t **pdu = asn_pdu_collection; fprintf(stderr, "Available PDU types:\n"); for(; *pdu; pdu++) printf("%s\n", (*pdu)->name); exit(0); } else if(optarg[0] >= 'A' && optarg[0] <= 'Z') { asn_TYPE_descriptor_t **pdu = asn_pdu_collection; while(*pdu && strcmp((*pdu)->name, optarg)) pdu++; if(*pdu) { pduType = *pdu; break; } fprintf(stderr, "-p %s: Unrecognized PDU\n", optarg); } #endif /* ASN_PDU_COLLECTION */ fprintf(stderr, "-p %s: Unrecognized option\n", optarg); exit(EX_UNAVAILABLE); case 's': opt_stack = atoi(optarg); if(opt_stack < 0) { fprintf(stderr, "-s %s: Non-negative value expected\n", optarg); exit(EX_UNAVAILABLE); } break; #ifdef JUNKTEST case 'J': opt_jprob = strtod(optarg, 0); if(opt_jprob <= 0.0 || opt_jprob > 1.0) { fprintf(stderr, "-J %s: Probability range 0..1 expected \n", optarg); exit(EX_UNAVAILABLE); } break; #endif /* JUNKTEST */ case 'h': default: #ifdef ASN_CONVERTER_TITLE #define _AXS(x) #x #define _ASX(x) _AXS(x) fprintf(stderr, "%s\n", _ASX(ASN_CONVERTER_TITLE)); #endif fprintf(stderr, "Usage: %s [options] <data.ber> ...\n", av[0]); fprintf(stderr, "Where options are:\n"); if(pduType->uper_decoder) fprintf(stderr, " -iper Input is in Unaligned PER (Packed Encoding Rules) (DEFAULT)\n"); fprintf(stderr, " -iber Input is in BER (Basic Encoding Rules)%s\n", iform == INP_PER ? "" : " (DEFAULT)"); fprintf(stderr, " -ixer Input is in XER (XML Encoding Rules)\n"); if(pduType->uper_encoder) fprintf(stderr, " -oper Output in Unaligned PER (Packed Encoding Rules)\n"); fprintf(stderr, " -oder Output in DER (Distinguished Encoding Rules)\n" " -oxer Output in XER (XML Encoding Rules) (DEFAULT)\n" " -otext Output in plain semi-structured text (dump)\n" " -onull Verify (decode) input, but do not output\n"); if(pduType->uper_decoder) fprintf(stderr, " -per-nopad Assume PER PDUs are not padded (-iper)\n"); #ifdef ASN_PDU_COLLECTION fprintf(stderr, " -p <PDU> Specify PDU type to decode\n" " -p list List available PDUs\n"); #endif /* ASN_PDU_COLLECTION */ fprintf(stderr, " -1 Decode only the first PDU in file\n" " -b <size> Set the i/o buffer size (default is %ld)\n" " -c Check ASN.1 constraints after decoding\n" " -d Enable debugging (-dd is even better)\n" " -n <num> Process files <num> times\n" " -s <size> Set the stack usage limit (default is %d)\n" #ifdef JUNKTEST " -J <prob> Set random junk test bit garbaging probability\n" #endif , (long)suggested_bufsize, _ASN_DEFAULT_STACK_MAX); exit(EX_USAGE); } ac -= optind; av += optind; if(ac < 1) { fprintf(stderr, "%s: No input files specified. " "Try '-h' for more information\n", av[-optind]); exit(EX_USAGE); } setvbuf(stdout, 0, _IOLBF, 0); for(num = 0; num < number_of_iterations; num++) { int ac_i; /* * Process all files in turn. */ for(ac_i = 0; ac_i < ac; ac_i++) { asn_enc_rval_t erv; void *structure; /* Decoded structure */ FILE *file = argument_to_file(av, ac_i); char *name = argument_to_name(av, ac_i); int first_pdu; for(first_pdu = 1; first_pdu || !opt_onepdu; first_pdu = 0) { /* * Decode the encoded structure from file. */ structure = data_decode_from_file(pduType, file, name, suggested_bufsize, first_pdu); if(!structure) { if(errno) { /* Error message is already printed */ exit(EX_DATAERR); } else { /* EOF */ break; } } /* Check ASN.1 constraints */ if(opt_check) { char errbuf[128]; size_t errlen = sizeof(errbuf); if(asn_check_constraints(pduType, structure, errbuf, &errlen)) { fprintf(stderr, "%s: ASN.1 constraint " "check failed: %s\n", name, errbuf); exit(EX_DATAERR); } } switch(oform) { case OUT_NULL: #ifdef JUNKTEST if(opt_jprob == 0.0) #endif fprintf(stderr, "%s: decoded successfully\n", name); break; case OUT_TEXT: /* -otext */ asn_fprint(stdout, pduType, structure); break; case OUT_XER: /* -oxer */ if(xer_fprint(stdout, pduType, structure)) { fprintf(stderr, "%s: Cannot convert %s into XML\n", name, pduType->name); exit(EX_UNAVAILABLE); } break; case OUT_DER: erv = der_encode(pduType, structure, write_out, stdout); if(erv.encoded < 0) { fprintf(stderr, "%s: Cannot convert %s into DER\n", name, pduType->name); exit(EX_UNAVAILABLE); } DEBUG("Encoded in %ld bytes of DER", (long)erv.encoded); break; case OUT_PER: erv = uper_encode(pduType, structure, write_out, stdout); if(erv.encoded < 0) { fprintf(stderr, "%s: Cannot convert %s into Unaligned PER\n", name, pduType->name); exit(EX_UNAVAILABLE); } DEBUG("Encoded in %ld bits of UPER", (long)erv.encoded); break; } ASN_STRUCT_FREE(*pduType, structure); structure = NULL; } if(file && file != stdin) fclose(file); } } #ifdef JUNKTEST if(opt_jprob > 0.0) { fprintf(stderr, "Junked %f OK (%d/%d)\n", opt_jprob, junk_failures, number_of_iterations); } #endif /* JUNKTEST */ return 0; }
static PDU_t * load_object_from(enum expectation expectation, char *fbuf, int size, enum der_or_xer how) { asn_dec_rval_t rval; asn_dec_rval_t (*zer_decode)(struct asn_codec_ctx_s *, asn_TYPE_descriptor_t *, void **, const void *, size_t); PDU_t *st = 0; int csize = 1; if(how == AS_DER) zer_decode = ber_decode; else zer_decode = xer_decode; if(getenv("INITIAL_CHUNK_SIZE")) csize = atoi(getenv("INITIAL_CHUNK_SIZE")); /* Perform multiple iterations with multiple chunks sizes */ for(; csize < 20; csize += 1) { int fbuf_offset = 0; int fbuf_left = size; int fbuf_chunk = csize; fprintf(stderr, "LOADING OBJECT OF SIZE %d, chunks %d\n", size, csize); if(st) asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); st = 0; do { fprintf(stderr, "Decoding bytes %d..%d (left %d)\n", fbuf_offset, fbuf_chunk < fbuf_left ? fbuf_chunk : fbuf_left, fbuf_left); if(st) { fprintf(stderr, "=== currently ===\n"); asn_fprint(stderr, &asn_DEF_PDU, st); fprintf(stderr, "=== end ===\n"); } rval = zer_decode(0, &asn_DEF_PDU, (void **)&st, fbuf + fbuf_offset, fbuf_chunk < fbuf_left ? fbuf_chunk : fbuf_left); fbuf_offset += rval.consumed; fbuf_left -= rval.consumed; if(rval.code == RC_WMORE) fbuf_chunk += 1; /* Give little more */ else fbuf_chunk = csize; /* Back off */ } while(fbuf_left && rval.code == RC_WMORE); if(expectation != EXP_BROKEN) { assert(rval.code == RC_OK); if(how == AS_DER) { assert(fbuf_offset == size); } else { assert(fbuf_offset - size < 2 || (fbuf_offset + 1 /* "\n" */ == size && fbuf[size - 1] == '\n') || (fbuf_offset + 2 /* "\r\n" */ == size && fbuf[size - 2] == '\r' && fbuf[size - 1] == '\n') ); } } else { assert(rval.code != RC_OK); fprintf(stderr, "Failed, but this was expected\n"); asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); st = 0; /* ignore leak for now */ } } if(st) asn_fprint(stderr, &asn_DEF_PDU, st); return st; }
static void check(int is_ok, uint8_t *buf, size_t size, size_t consumed) { T1_t t, *tp; void *tpp = &tp; asn_dec_rval_t rval; asn_enc_rval_t erval; int ret; int i; tp = memset(&t, 0, sizeof(t)); fprintf(stderr, "Buf %p\n", buf); rval = ber_decode(0, &asn_DEF_T1, (void **)tpp, buf, size); fprintf(stderr, "Returned code %d, consumed %d\n", (int)rval.code, (int)rval.consumed); if(is_ok) { assert(rval.code == RC_OK); assert(rval.consumed == (size_t)consumed); assert(t.a.size == 2); assert(t.b.present == b_PR_n); assert(t.b.choice.n.size == 1); assert(t.b.choice.n.buf[0] == 'i'); assert(t.c.size == 1); assert(t.c.buf[0] == 'x'); } else { if(rval.code == RC_OK) { assert(t.a.size != 2 || t.b.present != b_PR_n || t.b.choice.n.size != 1 || t.c.size != 1 ); } assert(rval.consumed <= (size_t)consumed); ASN_STRUCT_RESET(asn_DEF_T1, tp); return; } fprintf(stderr, "=> Re-creating using DER encoder <=\n"); /* * Try to re-create using DER encoding. */ buf2_pos = 0; erval = der_encode(&asn_DEF_T1, tp, buf2_fill, 0); assert(erval.encoded != -1); if(erval.encoded != sizeof(buf1)) { printf("%d != %d\n", (int)erval.encoded, (int)sizeof(buf1)); } assert(erval.encoded == (ssize_t)sizeof(buf1)); for(i = 0; i < (ssize_t)sizeof(buf1); i++) { if(buf1[i] != buf2[i]) { fprintf(stderr, "Recreated buffer content mismatch:\n"); fprintf(stderr, "Byte %d, %x != %x (%d != %d)\n", i, buf1[i], buf2[i], buf1[i], buf2[i] ); } assert(buf1[i] == buf2[i]); } fprintf(stderr, "=== asn_fprint() ===\n"); ret = asn_fprint(stderr, &asn_DEF_T1, tp); assert(ret == 0); fprintf(stderr, "=== xer_fprint() ===\n"); ret = xer_fprint(stderr, &asn_DEF_T1, tp); assert(ret == 0); fprintf(stderr, "=== EOF ===\n"); ASN_STRUCT_RESET(asn_DEF_T1, tp); }
static PDU_t * load_object_from(const char *fname, char *fbuf, int size, enum enctype how, int mustfail) { asn_dec_rval_t rval; PDU_t *st = 0; int csize = 1; if(getenv("INITIAL_CHUNK_SIZE")) csize = atoi(getenv("INITIAL_CHUNK_SIZE")); /* Perform multiple iterations with multiple chunks sizes */ for(; csize < 20; csize += 1) { int fbuf_offset = 0; int fbuf_left = size; int fbuf_chunk = csize; fprintf(stderr, "LOADING OBJECT OF SIZE %d FROM [%s] as %s," " chunks %d\n", size, fname, how==AS_PER?"PER":"XER", csize); if(st) asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); st = 0; do { fprintf(stderr, "\nDecoding bytes %d..%d (left %d) [%s]\n", fbuf_offset, fbuf_chunk < fbuf_left ? fbuf_chunk : fbuf_left, fbuf_left, fname); if(st) { fprintf(stderr, "=== currently ===\n"); asn_fprint(stderr, &asn_DEF_PDU, st); fprintf(stderr, "=== end ===\n"); } switch(how) { case AS_XER: rval = xer_decode(0, &asn_DEF_PDU, (void **)&st, fbuf + fbuf_offset, fbuf_chunk < fbuf_left ? fbuf_chunk : fbuf_left); break; case AS_DER: assert(0); break; case AS_PER: rval = uper_decode(0, &asn_DEF_PDU, (void **)&st, fbuf + fbuf_offset, fbuf_chunk < fbuf_left ? fbuf_chunk : fbuf_left, 0, 0); if(rval.code == RC_WMORE) { if(fbuf_chunk == fbuf_left) { fprintf(stderr, "-> PER decode error (%d bits of %d bytes (c=%d,l=%d)) \n", rval.consumed, size, fbuf_chunk, fbuf_left); rval.code = RC_FAIL; rval.consumed += 7; rval.consumed /= 8; if(mustfail) { fprintf(stderr, "-> (this was expected failure)\n"); return 0; } } else { rval.consumed = 0; /* Not restartable */ ASN_STRUCT_FREE(asn_DEF_PDU, st); st = 0; fprintf(stderr, "-> PER wants more\n"); } } else { fprintf(stderr, "-> PER ret %d/%d mf=%d\n", rval.code, rval.consumed, mustfail); /* uper_decode() returns _bits_ */ rval.consumed += 7; rval.consumed /= 8; if((mustfail?1:0) == (rval.code == RC_FAIL)) { if(mustfail) { fprintf(stderr, "-> (this was expected failure)\n"); return 0; } } else { fprintf(stderr, "-> (unexpected %s)\n", mustfail ? "success" : "failure"); rval.code = RC_FAIL; } } break; } fbuf_offset += rval.consumed; fbuf_left -= rval.consumed; if(rval.code == RC_WMORE) fbuf_chunk += 1; /* Give little more */ else fbuf_chunk = csize; /* Back off */ } while(fbuf_left && rval.code == RC_WMORE); assert(rval.code == RC_OK); if(how == AS_PER) { fprintf(stderr, "[left %d, off %d, size %d]\n", fbuf_left, fbuf_offset, size); assert(fbuf_offset == size); } else { assert(fbuf_offset - size < 2 || (fbuf_offset + 1 /* "\n" */ == size && fbuf[size - 1] == '\n') || (fbuf_offset + 2 /* "\r\n" */ == size && fbuf[size - 2] == '\r' && fbuf[size - 1] == '\n') ); } } if(st) asn_fprint(stderr, &asn_DEF_PDU, st); return st; }
static PDU_t * load_object_from(const char *fname, enum expectation expectation, char *fbuf, size_t size, enum enctype how) { asn_dec_rval_t rval; PDU_t *st = 0; size_t csize = 1; if(getenv("INITIAL_CHUNK_SIZE")) csize = atoi(getenv("INITIAL_CHUNK_SIZE")); /* Perform multiple iterations with multiple chunks sizes */ for(; csize < 20; csize += 1) { int fbuf_offset = 0; int fbuf_left = size; int fbuf_chunk = csize; fprintf(stderr, "LOADING OBJECT OF SIZE %zd FROM [%s] as %s," " chunks %zd\n", size, fname, how==AS_PER?"PER":"XER", csize); if(st) asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); st = 0; do { fprintf(stderr, "Decoding bytes %d..%d (left %d)\n", fbuf_offset, fbuf_chunk < fbuf_left ? fbuf_chunk : fbuf_left, fbuf_left); if(st) { fprintf(stderr, "=== currently ===\n"); asn_fprint(stderr, &asn_DEF_PDU, st); fprintf(stderr, "=== end ===\n"); } switch(how) { case AS_XER: rval = xer_decode(0, &asn_DEF_PDU, (void **)&st, fbuf + fbuf_offset, fbuf_chunk < fbuf_left ? fbuf_chunk : fbuf_left); break; case AS_PER: rval = uper_decode(0, &asn_DEF_PDU, (void **)&st, fbuf + fbuf_offset, fbuf_chunk < fbuf_left ? fbuf_chunk : fbuf_left, 0, 0); if(rval.code == RC_WMORE) { rval.consumed = 0; /* Not restartable */ ASN_STRUCT_FREE(asn_DEF_PDU, st); st = 0; fprintf(stderr, "-> PER wants more\n"); } else { fprintf(stderr, "-> PER ret %d/%ld\n", rval.code, rval.consumed); /* uper_decode() returns _bits_ */ rval.consumed += 7; rval.consumed /= 8; } break; } fbuf_offset += rval.consumed; fbuf_left -= rval.consumed; if(rval.code == RC_WMORE) fbuf_chunk += 1; /* Give little more */ else fbuf_chunk = csize; /* Back off */ } while(fbuf_left && rval.code == RC_WMORE); if(expectation != EXP_BROKEN) { assert(rval.code == RC_OK); if(how == AS_PER) { fprintf(stderr, "[left %d, off %d, size %zd]\n", fbuf_left, fbuf_offset, size); assert(fbuf_offset == size); } else { assert(fbuf_offset - size < 2 || (fbuf_offset + 1 /* "\n" */ == size && fbuf[size - 1] == '\n') || (fbuf_offset + 2 /* "\r\n" */ == size && fbuf[size - 2] == '\r' && fbuf[size - 1] == '\n') ); } } else { assert(rval.code != RC_OK); fprintf(stderr, "Failed, but this was expected\n"); asn_DEF_PDU.free_struct(&asn_DEF_PDU, st, 0); st = 0; /* ignore leak for now */ } } if(st) asn_fprint(stderr, &asn_DEF_PDU, st); return st; }