constr_SEQUENCE_oer.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /*
  2. * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
  3. * All rights reserved.
  4. * Redistribution and modifications are permitted subject to BSD license.
  5. */
  6. #ifndef ASN_DISABLE_OER_SUPPORT
  7. #include <asn_internal.h>
  8. #include <constr_SEQUENCE.h>
  9. #include <OPEN_TYPE.h>
  10. #include <errno.h>
  11. /*
  12. * This macro "eats" the part of the buffer which is definitely "consumed",
  13. * i.e. was correctly converted into local representation or rightfully skipped.
  14. */
  15. #undef ADVANCE
  16. #define ADVANCE(num_bytes) \
  17. do { \
  18. size_t num = num_bytes; \
  19. ptr = ((const char *)ptr) + num; \
  20. size -= num; \
  21. consumed_myself += num; \
  22. } while(0)
  23. /*
  24. * Switch to the next phase of parsing.
  25. */
  26. #undef NEXT_PHASE
  27. #undef PHASE_OUT
  28. #define NEXT_PHASE(ctx) \
  29. do { \
  30. ctx->phase++; \
  31. ctx->step = 0; \
  32. } while(0)
  33. /*
  34. * Check whether we are inside the extensions group.
  35. */
  36. #define IN_EXTENSION_GROUP(specs, memb_idx) \
  37. ((specs)->first_extension >= 0 \
  38. && (unsigned)(specs)->first_extension <= (memb_idx))
  39. #define IN_ROOT_GROUP_PRED(edx) \
  40. edx < (specs->first_extension < 0 ? td->elements_count \
  41. : (size_t)specs->first_extension)
  42. #define FOR_IN_ROOT_GROUP(edx) for(edx = 0; IN_ROOT_GROUP_PRED(edx); edx++)
  43. /*
  44. * Return a standardized complex structure.
  45. */
  46. #undef RETURN
  47. #define RETURN(_code) do { \
  48. rval.code = _code; \
  49. rval.consumed = consumed_myself;\
  50. return rval; \
  51. } while(0)
  52. /*
  53. * Return pointer to a member.
  54. */
  55. static void **
  56. element_ptrptr(void *struct_ptr, asn_TYPE_member_t *elm, void **tmp_save_ptr) {
  57. if(elm->flags & ATF_POINTER) {
  58. /* Member is a pointer to another structure */
  59. return (void **)((char *)struct_ptr + elm->memb_offset);
  60. } else {
  61. assert(tmp_save_ptr);
  62. *tmp_save_ptr = (void *)((char *)struct_ptr + elm->memb_offset);
  63. return tmp_save_ptr;
  64. }
  65. }
  66. static const void *
  67. element_ptr(const void *struct_ptr, const asn_TYPE_member_t *elm) {
  68. if(elm->flags & ATF_POINTER) {
  69. /* Member is a pointer to another structure */
  70. return *(const void *const *)((const char *)struct_ptr
  71. + elm->memb_offset);
  72. } else {
  73. return (const void *)((const char *)struct_ptr + elm->memb_offset);
  74. }
  75. }
  76. asn_dec_rval_t
  77. SEQUENCE_decode_oer(const asn_codec_ctx_t *opt_codec_ctx,
  78. const asn_TYPE_descriptor_t *td,
  79. const asn_oer_constraints_t *constraints, void **struct_ptr,
  80. const void *ptr, size_t size) {
  81. const asn_SEQUENCE_specifics_t *specs =
  82. (const asn_SEQUENCE_specifics_t *)td->specifics;
  83. asn_dec_rval_t rval = {RC_OK, 0};
  84. void *st = *struct_ptr; /* Target structure */
  85. asn_struct_ctx_t *ctx; /* Decoder context */
  86. size_t consumed_myself = 0; /* Consumed bytes from ptr. */
  87. (void)constraints;
  88. if(ASN__STACK_OVERFLOW_CHECK(opt_codec_ctx))
  89. ASN__DECODE_FAILED;
  90. /*
  91. * Create the target structure if it is not present already.
  92. */
  93. if(st == 0) {
  94. st = *struct_ptr = CALLOC(1, specs->struct_size);
  95. if(st == 0) {
  96. RETURN(RC_FAIL);
  97. }
  98. }
  99. /*
  100. * Restore parsing context.
  101. */
  102. ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
  103. /*
  104. * Start to parse where left previously.
  105. */
  106. switch(ctx->phase) {
  107. case 0: {
  108. /*
  109. * Fetch preamble.
  110. */
  111. asn_bit_data_t *preamble;
  112. int has_extensions_bit = (specs->first_extension >= 0);
  113. size_t preamble_bits = (has_extensions_bit + specs->roms_count);
  114. size_t preamble_bytes = ((7 + preamble_bits) >> 3);
  115. ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 0", td->name);
  116. ASN_DEBUG(
  117. "Expecting preamble bits %" ASN_PRI_SIZE " for %s (including %d extension bits)",
  118. preamble_bits, td->name, has_extensions_bit);
  119. if(preamble_bytes > size) {
  120. ASN__DECODE_STARVED;
  121. }
  122. preamble = asn_bit_data_new_contiguous(ptr, preamble_bits);
  123. if(!preamble) {
  124. RETURN(RC_FAIL);
  125. }
  126. preamble->nboff = has_extensions_bit;
  127. ctx->ptr = preamble;
  128. ADVANCE(preamble_bytes);
  129. }
  130. NEXT_PHASE(ctx);
  131. /* FALL THROUGH */
  132. case 1: {
  133. /* Decode components of the extension root */
  134. asn_bit_data_t *preamble = ctx->ptr;
  135. size_t edx;
  136. ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 1 (Root)", td->name);
  137. assert(preamble);
  138. for(edx = (ctx->step >> 1); IN_ROOT_GROUP_PRED(edx);
  139. edx++, ctx->step = (ctx->step & ~1) + 2) {
  140. asn_TYPE_member_t *elm = &td->elements[edx];
  141. ASN_DEBUG("Decoding %s->%s", td->name, elm->name);
  142. assert(!IN_EXTENSION_GROUP(specs, edx));
  143. if(ctx->step & 1) {
  144. goto microphase2_decode_continues;
  145. }
  146. if(elm->optional) {
  147. int32_t present = asn_get_few_bits(preamble, 1);
  148. if(present < 0) {
  149. ASN_DEBUG("Presence map ended prematurely: %d", present);
  150. RETURN(RC_FAIL);
  151. } else if(present == 0) {
  152. if(elm->default_value_set) {
  153. /* Fill-in DEFAULT */
  154. void *tmp;
  155. if(elm->default_value_set(
  156. element_ptrptr(st, elm, &tmp))) {
  157. RETURN(RC_FAIL);
  158. }
  159. }
  160. /* The member is not present. */
  161. continue;
  162. }
  163. /* Present OPTIONAL or DEFAULT component. */
  164. }
  165. /*
  166. * MICROPHASE 2: Invoke the member-specific decoder.
  167. */
  168. ctx->step |= 1; /* Confirm entering next microphase */
  169. microphase2_decode_continues:
  170. if(elm->flags & ATF_OPEN_TYPE) {
  171. rval = OPEN_TYPE_oer_get(opt_codec_ctx, td, st, elm, ptr, size);
  172. } else {
  173. void *save_memb_ptr; /* Temporary reference. */
  174. void **memb_ptr2; /* Pointer to a pointer to a memmber */
  175. memb_ptr2 = element_ptrptr(st, elm, &save_memb_ptr);
  176. rval = elm->type->op->oer_decoder(
  177. opt_codec_ctx, elm->type,
  178. elm->encoding_constraints.oer_constraints, memb_ptr2, ptr,
  179. size);
  180. }
  181. switch(rval.code) {
  182. case RC_OK:
  183. ADVANCE(rval.consumed);
  184. break;
  185. case RC_WMORE:
  186. ASN_DEBUG("More bytes needed at element %s \"%s\"", td->name,
  187. elm->name);
  188. ADVANCE(rval.consumed);
  189. RETURN(RC_WMORE);
  190. case RC_FAIL:
  191. ASN_DEBUG("Decoding failed at element %s \"%s\"", td->name,
  192. elm->name);
  193. RETURN(RC_FAIL);
  194. }
  195. } /* for(all root members) */
  196. }
  197. NEXT_PHASE(ctx);
  198. /* FALL THROUGH */
  199. case 2:
  200. assert(ctx->ptr);
  201. {
  202. /* Cleanup preamble. */
  203. asn_bit_data_t *preamble = ctx->ptr;
  204. asn_bit_data_t *extadds;
  205. int has_extensions_bit = (specs->first_extension >= 0);
  206. int extensions_present =
  207. has_extensions_bit
  208. && (preamble->buffer == NULL
  209. || (((const uint8_t *)preamble->buffer)[0] & 0x80));
  210. uint8_t unused_bits;
  211. size_t len = 0;
  212. ssize_t len_len;
  213. ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 2", td->name);
  214. preamble->buffer = 0; /* Will do extensions_present==1 next time. */
  215. if(!extensions_present) {
  216. ctx->phase = 10;
  217. RETURN(RC_OK);
  218. }
  219. /*
  220. * X.696 (08/2015) #16.1 (c), #16.4
  221. * Read in the extension addition presence bitmap.
  222. */
  223. len_len = oer_fetch_length(ptr, size, &len);
  224. if(len_len > 0) {
  225. ADVANCE(len_len);
  226. } else if(len_len < 0) {
  227. RETURN(RC_FAIL);
  228. } else {
  229. RETURN(RC_WMORE);
  230. }
  231. if(len == 0) {
  232. /* 16.4.1-2 */
  233. RETURN(RC_FAIL);
  234. } else if(len > size) {
  235. RETURN(RC_WMORE);
  236. }
  237. /* Account for unused bits */
  238. unused_bits = 0x7 & *(const uint8_t *)ptr;
  239. ADVANCE(1);
  240. len--;
  241. if(unused_bits && len == 0) {
  242. RETURN(RC_FAIL);
  243. }
  244. /* Get the extensions map */
  245. extadds = asn_bit_data_new_contiguous(ptr, len * 8 - unused_bits);
  246. if(!extadds) {
  247. RETURN(RC_FAIL);
  248. }
  249. FREEMEM(preamble);
  250. ctx->ptr = extadds;
  251. ADVANCE(len);
  252. }
  253. NEXT_PHASE(ctx);
  254. ctx->step =
  255. (specs->first_extension < 0 ? td->elements_count
  256. : (size_t)specs->first_extension);
  257. /* Fall through */
  258. case 3:
  259. ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 3 (Extensions)", td->name);
  260. for(; ctx->step < (signed)td->elements_count; ctx->step++) {
  261. asn_bit_data_t *extadds = ctx->ptr;
  262. size_t edx = ctx->step;
  263. asn_TYPE_member_t *elm = &td->elements[edx];
  264. void *tmp_memb_ptr;
  265. void **memb_ptr2 = element_ptrptr(st, elm, &tmp_memb_ptr);
  266. switch(asn_get_few_bits(extadds, 1)) {
  267. case -1:
  268. /*
  269. * Not every one of our extensions is known to the remote side.
  270. * Continue filling in their defaults though.
  271. */
  272. /* Fall through */
  273. case 0:
  274. /* Fill-in DEFAULT */
  275. if(elm->default_value_set
  276. && elm->default_value_set(memb_ptr2)) {
  277. RETURN(RC_FAIL);
  278. }
  279. continue;
  280. case 1: {
  281. /* Read OER open type */
  282. ssize_t ot_size =
  283. oer_open_type_get(opt_codec_ctx, elm->type,
  284. elm->encoding_constraints.oer_constraints,
  285. memb_ptr2, ptr, size);
  286. assert(ot_size <= (ssize_t)size);
  287. if(ot_size > 0) {
  288. ADVANCE(ot_size);
  289. } else if(ot_size < 0) {
  290. RETURN(RC_FAIL);
  291. } else {
  292. /* Roll back open type parsing */
  293. asn_get_undo(extadds, 1);
  294. RETURN(RC_WMORE);
  295. }
  296. break;
  297. }
  298. default:
  299. RETURN(RC_FAIL);
  300. }
  301. }
  302. NEXT_PHASE(ctx);
  303. /* Fall through */
  304. case 4:
  305. ASN_DEBUG("OER SEQUENCE %s Decoding PHASE 4", td->name);
  306. /* Read in the rest of Open Types while ignoring them */
  307. for(;;) {
  308. asn_bit_data_t *extadds = ctx->ptr;
  309. switch(asn_get_few_bits(extadds, 1)) {
  310. case 0:
  311. continue;
  312. case 1: {
  313. ssize_t skipped = oer_open_type_skip(ptr, size);
  314. if(skipped > 0) {
  315. ADVANCE(skipped);
  316. } else if(skipped < 0) {
  317. RETURN(RC_FAIL);
  318. } else {
  319. asn_get_undo(extadds, 1);
  320. RETURN(RC_WMORE);
  321. }
  322. continue;
  323. }
  324. case -1:
  325. /* No more Open Type encoded components */
  326. break;
  327. default:
  328. RETURN(RC_FAIL);
  329. }
  330. break;
  331. }
  332. }
  333. RETURN(RC_OK);
  334. }
  335. /*
  336. * Encode as Canonical OER.
  337. */
  338. asn_enc_rval_t
  339. SEQUENCE_encode_oer(const asn_TYPE_descriptor_t *td,
  340. const asn_oer_constraints_t *constraints, const void *sptr,
  341. asn_app_consume_bytes_f *cb, void *app_key) {
  342. const asn_SEQUENCE_specifics_t *specs = (const asn_SEQUENCE_specifics_t *)td->specifics;
  343. size_t computed_size = 0;
  344. int has_extensions_bit = (specs->first_extension >= 0);
  345. size_t preamble_bits = (has_extensions_bit + specs->roms_count);
  346. uint32_t has_extensions = 0;
  347. size_t edx;
  348. int ret;
  349. (void)constraints;
  350. if(preamble_bits) {
  351. asn_bit_outp_t preamble;
  352. memset(&preamble, 0, sizeof(preamble));
  353. preamble.output = cb;
  354. preamble.op_key = app_key;
  355. if(has_extensions_bit) {
  356. for(edx = specs->first_extension; edx < td->elements_count; edx++) {
  357. asn_TYPE_member_t *elm = &td->elements[edx];
  358. const void *memb_ptr = element_ptr(sptr, elm);
  359. if(memb_ptr) {
  360. if(elm->default_value_cmp
  361. && elm->default_value_cmp(memb_ptr) == 0) {
  362. /* Do not encode default values in extensions */
  363. } else {
  364. has_extensions = 1;
  365. break;
  366. }
  367. }
  368. }
  369. ret = asn_put_few_bits(&preamble, has_extensions, 1);
  370. assert(ret == 0);
  371. if(ret < 0) {
  372. ASN__ENCODE_FAILED;
  373. }
  374. }
  375. /*
  376. * Encode optional components bitmap.
  377. */
  378. if(specs->roms_count) {
  379. FOR_IN_ROOT_GROUP(edx) {
  380. asn_TYPE_member_t *elm = &td->elements[edx];
  381. if(IN_EXTENSION_GROUP(specs, edx)) break;
  382. if(elm->optional) {
  383. const void *memb_ptr = element_ptr(sptr, elm);
  384. uint32_t has_component = memb_ptr != NULL;
  385. if(has_component && elm->default_value_cmp
  386. && elm->default_value_cmp(memb_ptr) == 0) {
  387. has_component = 0;
  388. }
  389. ret = asn_put_few_bits(&preamble, has_component, 1);
  390. if(ret < 0) {
  391. ASN__ENCODE_FAILED;
  392. }
  393. }
  394. }
  395. }
  396. asn_put_aligned_flush(&preamble);
  397. computed_size += preamble.flushed_bytes;
  398. } /* if(preamble_bits) */
  399. /*
  400. * Put root components and extensions root.
  401. */
  402. for(edx = 0; edx < td->elements_count; edx++) {
  403. asn_TYPE_member_t *elm = &td->elements[edx];
  404. asn_enc_rval_t er;
  405. const void *memb_ptr;
  406. if(IN_EXTENSION_GROUP(specs, edx)) break;
  407. memb_ptr = element_ptr(sptr, elm);
  408. if(memb_ptr) {
  409. if(elm->default_value_cmp
  410. && elm->default_value_cmp(memb_ptr) == 0) {
  411. /* Skip default values in encoding */
  412. continue;
  413. }
  414. } else {
  415. if(elm->optional) continue;
  416. /* Mandatory element is missing */
  417. ASN__ENCODE_FAILED;
  418. }
  419. if(!elm->type->op->oer_encoder) {
  420. ASN_DEBUG("OER encoder is not defined for type %s", elm->type->name);
  421. ASN__ENCODE_FAILED;
  422. }
  423. er = elm->type->op->oer_encoder(
  424. elm->type, elm->encoding_constraints.oer_constraints, memb_ptr, cb,
  425. app_key);
  426. if(er.encoded == -1) {
  427. ASN_DEBUG("... while encoding %s member \"%s\"\n", td->name,
  428. elm->name);
  429. return er;
  430. }
  431. computed_size += er.encoded;
  432. }
  433. /*
  434. * Before encode extensions, encode extensions additions presense bitmap
  435. # X.696 (08/2015) #16.4.
  436. */
  437. if(has_extensions) {
  438. asn_bit_outp_t extadds;
  439. /* Special case allowing us to use exactly one byte for #8.6 */
  440. size_t aoms_length_bits = specs->aoms_count;
  441. size_t aoms_length_bytes = (7 + aoms_length_bits) >> 3;
  442. uint8_t unused_bits = 0x07 & (8 - (aoms_length_bits & 0x07));
  443. assert(1 + aoms_length_bytes <= 127);
  444. memset(&extadds, 0, sizeof(extadds));
  445. extadds.output = cb;
  446. extadds.op_key = app_key;
  447. /* #8.6 length determinant */
  448. ret = asn_put_few_bits(&extadds, (1 + aoms_length_bytes), 8);
  449. if(ret < 0) ASN__ENCODE_FAILED;
  450. /* Number of unused bytes, #16.4.2 */
  451. ret = asn_put_few_bits(&extadds, unused_bits, 8);
  452. if(ret < 0) ASN__ENCODE_FAILED;
  453. /* Encode presence bitmap #16.4.3 */
  454. for(edx = specs->first_extension; edx < td->elements_count; edx++) {
  455. asn_TYPE_member_t *elm = &td->elements[edx];
  456. const void *memb_ptr = element_ptr(sptr, elm);
  457. if(memb_ptr && elm->default_value_cmp
  458. && elm->default_value_cmp(memb_ptr) == 0) {
  459. memb_ptr = 0; /* Do not encode default value. */
  460. }
  461. ret |= asn_put_few_bits(&extadds, memb_ptr ? 1 : 0, 1);
  462. }
  463. if(ret < 0) ASN__ENCODE_FAILED;
  464. asn_put_aligned_flush(&extadds);
  465. computed_size += extadds.flushed_bytes;
  466. /* Now, encode extensions */
  467. for(edx = specs->first_extension; edx < td->elements_count; edx++) {
  468. asn_TYPE_member_t *elm = &td->elements[edx];
  469. const void *memb_ptr = element_ptr(sptr, elm);
  470. if(memb_ptr) {
  471. if(elm->default_value_cmp
  472. && elm->default_value_cmp(memb_ptr) == 0) {
  473. /* Do not encode default value. */
  474. } else {
  475. ssize_t wrote = oer_open_type_put(
  476. elm->type, elm->encoding_constraints.oer_constraints,
  477. memb_ptr, cb, app_key);
  478. if(wrote == -1) {
  479. ASN__ENCODE_FAILED;
  480. }
  481. computed_size += wrote;
  482. }
  483. } else if(!elm->optional) {
  484. ASN__ENCODE_FAILED;
  485. }
  486. }
  487. } /* if(has_extensions) */
  488. {
  489. asn_enc_rval_t er = {0, 0, 0};
  490. er.encoded = computed_size;
  491. ASN__ENCODED_OK(er);
  492. }
  493. }
  494. #endif /* ASN_DISABLE_OER_SUPPORT */