blob: e803ad224ca214ee3a5b5958f7d13ee240119f79 [file] [log] [blame]
Lev Walkine7b73c42017-07-07 10:06:17 -07001/*
2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
4 */
5#include <asn_internal.h>
6
7/*
8 * The OER decoder of any type.
9 */
10asn_dec_rval_t
Lev Walkinafbf2a92017-09-12 23:30:27 -070011oer_decode(const asn_codec_ctx_t *opt_codec_ctx,
Lev Walkine7b73c42017-07-07 10:06:17 -070012 asn_TYPE_descriptor_t *type_descriptor,
13 void **struct_ptr, const void *ptr, size_t size) {
14 asn_codec_ctx_t s_codec_ctx;
15
16 /*
17 * Stack checker requires that the codec context
18 * must be allocated on the stack.
19 */
20 if(opt_codec_ctx) {
21 if(opt_codec_ctx->max_stack_size) {
22 s_codec_ctx = *opt_codec_ctx;
23 opt_codec_ctx = &s_codec_ctx;
24 }
25 } else {
26 /* If context is not given, be security-conscious anyway */
27 memset(&s_codec_ctx, 0, sizeof(s_codec_ctx));
28 s_codec_ctx.max_stack_size = ASN__DEFAULT_STACK_MAX;
29 opt_codec_ctx = &s_codec_ctx;
30 }
31
32 /*
33 * Invoke type-specific decoder.
34 */
Bi-Ruei, Chiu1f87ac02017-08-20 01:25:45 +080035 return type_descriptor->op->oer_decoder(opt_codec_ctx, type_descriptor, 0,
Lev Walkine7b73c42017-07-07 10:06:17 -070036 struct_ptr, /* Pointer to the destination structure */
37 ptr, size /* Buffer and its size */
38 );
39}
Lev Walkin20ea8522017-07-20 14:52:02 +030040
41/*
42 * Open Type is encoded as a length (#8.6) followed by that number of bytes.
43 * Since we're just skipping, reading the length would be enough.
44 */
45ssize_t
46oer_open_type_skip(const void *bufptr, size_t size) {
47 size_t len = 0;
48 return oer_fetch_length(bufptr, size, &len);
49}
50
51/*
52 * Read the Open Type (X.696 (08/2015), #30).
53 * RETURN VALUES:
54 * 0: More data expected than bufptr contains.
55 * -1: Fatal error deciphering length.
56 * >0: Number of bytes used from bufptr.
57 */
58ssize_t
Lev Walkinafbf2a92017-09-12 23:30:27 -070059oer_open_type_get(const asn_codec_ctx_t *opt_codec_ctx,
Lev Walkin20ea8522017-07-20 14:52:02 +030060 struct asn_TYPE_descriptor_s *td,
Lev Walkina5972be2017-09-29 23:15:58 -070061 const asn_oer_constraints_t *constraints, void **struct_ptr,
Lev Walkin20ea8522017-07-20 14:52:02 +030062 const void *bufptr, size_t size) {
Lev Walkin20ea8522017-07-20 14:52:02 +030063 asn_dec_rval_t dr;
64 size_t container_len = 0;
65 ssize_t len_len;
66
67 /* Get the size of a length determinant */
68 len_len = oer_fetch_length(bufptr, size, &container_len);
69 if(len_len <= 0) {
70 return len_len; /* Error or more data expected */
71 }
72
73 /*
74 * len_len can't be bigger than size, but size without len_len
75 * should be bigger or equal to container length
76 */
77 if(size - len_len < container_len) {
78 /* More data is expected */
79 return 0;
80 }
81
Bi-Ruei, Chiu1f87ac02017-08-20 01:25:45 +080082 dr = td->op->oer_decoder(opt_codec_ctx, td, constraints, struct_ptr,
Lev Walkin20ea8522017-07-20 14:52:02 +030083 (const uint8_t *)bufptr + len_len, container_len);
84 if(dr.code == RC_OK) {
85 return len_len + container_len;
86 } else {
87 /* Even if RC_WMORE, we can't get more data into a closed container. */
88 ASN_STRUCT_FREE(*td, *struct_ptr);
89 *struct_ptr = 0;
90 return -1;
91 }
92}
93