blob: 2e6d2791654d5a2d80e9891f57929120c220042f [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
11oer_decode(asn_codec_ctx_t *opt_codec_ctx,
12 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
59oer_open_type_get(asn_codec_ctx_t *opt_codec_ctx,
60 struct asn_TYPE_descriptor_s *td,
61 asn_oer_constraints_t *constraints, void **struct_ptr,
62 const void *bufptr, size_t size) {
63
64 asn_dec_rval_t dr;
65 size_t container_len = 0;
66 ssize_t len_len;
67
68 /* Get the size of a length determinant */
69 len_len = oer_fetch_length(bufptr, size, &container_len);
70 if(len_len <= 0) {
71 return len_len; /* Error or more data expected */
72 }
73
74 /*
75 * len_len can't be bigger than size, but size without len_len
76 * should be bigger or equal to container length
77 */
78 if(size - len_len < container_len) {
79 /* More data is expected */
80 return 0;
81 }
82
Bi-Ruei, Chiu1f87ac02017-08-20 01:25:45 +080083 dr = td->op->oer_decoder(opt_codec_ctx, td, constraints, struct_ptr,
Lev Walkin20ea8522017-07-20 14:52:02 +030084 (const uint8_t *)bufptr + len_len, container_len);
85 if(dr.code == RC_OK) {
86 return len_len + container_len;
87 } else {
88 /* Even if RC_WMORE, we can't get more data into a closed container. */
89 ASN_STRUCT_FREE(*td, *struct_ptr);
90 *struct_ptr = 0;
91 return -1;
92 }
93}
94