diff options
author | Björn Gustavsson <[email protected]> | 2013-01-25 12:45:26 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2013-01-25 12:45:26 +0100 |
commit | 9afbb879f0397a650a7c403911a8cc30daa6dbbe (patch) | |
tree | 8e0d77907994cd3e6397b12349abd35a63375235 /lib/asn1/c_src/asn1_erl_nif.c | |
parent | 61f8a41388d95f6b8c0e2e5a06de586cecf184c6 (diff) | |
parent | b06cbaf8cf12a9b6dcbdc6eab873a6212206ef58 (diff) | |
download | otp-9afbb879f0397a650a7c403911a8cc30daa6dbbe.tar.gz otp-9afbb879f0397a650a7c403911a8cc30daa6dbbe.tar.bz2 otp-9afbb879f0397a650a7c403911a8cc30daa6dbbe.zip |
Merge branch 'bjorn/asn1/further-cleanup/OTP-10588'
* bjorn/asn1/further-cleanup/OTP-10588: (28 commits)
Don't export encode_disp/2 and decode_disp/2 in generated modules
Remove vestiges of support for the {TypeName,Value} notation
Simplify the functions for decoding lengths
per,uper: Optimize decoding of the remaining data types
per,uper: Optimize decoding of the remaining string types
Share all code for dec_gen_prim/3 between per/uper back-ends
per,uper: Optimize decoding of the string data types
testPrimStrings: Test some constraints
By default, encode BIT STRING to bitstrings
Teach encode functions to accept a bitstring term for a BIT STRING
Fix EXTERNAL 1990/1994 conversion information loss
uper: Look up some SizeConstraints at compile-time
Enumeration decoding: Don't emit a default clause if it cannot match
Slightly optimize per encoding of large INTEGERs with constraints
BER run-time: Refactor decoding of string data types
Refactor decoding of BIT STRINGs
Optimize encoding of ENUMERATED in per and uper
Remove the unused run-time modules
eldap: Remove calls to undocumented asn1rt* functions
BER: Correct bug in 'undec_rest'
...
Diffstat (limited to 'lib/asn1/c_src/asn1_erl_nif.c')
-rw-r--r-- | lib/asn1/c_src/asn1_erl_nif.c | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/lib/asn1/c_src/asn1_erl_nif.c b/lib/asn1/c_src/asn1_erl_nif.c index dbff14f9b3..7f1870d5b0 100644 --- a/lib/asn1/c_src/asn1_erl_nif.c +++ b/lib/asn1/c_src/asn1_erl_nif.c @@ -27,7 +27,6 @@ #define ASN1_OK 0 #define ASN1_ERROR -1 #define ASN1_COMPL_ERROR 1 -#define ASN1_MEMORY_ERROR 0 #define ASN1_DECODE_ERROR 2 #define ASN1_TAG_ERROR -3 #define ASN1_LEN_ERROR -4 @@ -851,11 +850,8 @@ int ber_decode_begin(ErlNifEnv* env, ERL_NIF_TERM *term, unsigned char *in_buf, }; // The remaining binary after one ASN1 segment has been decoded - if ((rest_data = enif_make_new_binary(env, in_buf_len - ib_index, &rest)) - == NULL) { - *term = enif_make_atom(env, "could_not_alloc_binary"); - return ASN1_ERROR; - } + rest_data = enif_make_new_binary(env, in_buf_len - ib_index, &rest); + memcpy(rest_data, in_buf+ib_index, in_buf_len - ib_index); *term = enif_make_tuple2(env, decoded_term, rest); return ASN1_OK; @@ -1221,7 +1217,33 @@ static ERL_NIF_TERM encode_per_complete(ErlNifEnv* env, int argc, return enif_make_binary(env, &out_binary); } -static ERL_NIF_TERM decode_ber_tlv(ErlNifEnv* env, int argc, +static ERL_NIF_TERM +make_ber_error_term(ErlNifEnv* env, unsigned int return_code, + unsigned int err_pos) +{ + ERL_NIF_TERM reason; + ERL_NIF_TERM t; + + switch (return_code) { + case ASN1_TAG_ERROR: + reason = enif_make_atom(env, "invalid_tag"); + break; + case ASN1_LEN_ERROR: + case ASN1_INDEF_LEN_ERROR: + reason = enif_make_atom(env, "invalid_length"); + break; + case ASN1_VALUE_ERROR: + reason = enif_make_atom(env, "invalid_value"); + break; + default: + reason = enif_make_atom(env, "unknown"); + break; + } + t = enif_make_tuple2(env, reason, enif_make_int(env, err_pos)); + return enif_make_tuple2(env, enif_make_atom(env, "error"), t); +} + +static ERL_NIF_TERM decode_ber_tlv_raw(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary in_binary; ERL_NIF_TERM return_term; @@ -1230,11 +1252,11 @@ static ERL_NIF_TERM decode_ber_tlv(ErlNifEnv* env, int argc, if (!enif_inspect_iolist_as_binary(env, argv[0], &in_binary)) return enif_make_badarg(env); - if ((return_code = ber_decode_begin(env, &return_term, in_binary.data, - in_binary.size, &err_pos)) != ASN1_OK - ) - return enif_make_tuple2(env, enif_make_atom(env,"error"), enif_make_tuple2(env, - enif_make_int(env, return_code),enif_make_int(env, err_pos))); + return_code = ber_decode_begin(env, &return_term, in_binary.data, + in_binary.size, &err_pos); + if (return_code != ASN1_OK) { + return make_ber_error_term(env, return_code, err_pos); + } return return_term; } @@ -1297,8 +1319,10 @@ static void unload(ErlNifEnv* env, void* priv_data) { } -static ErlNifFunc nif_funcs[] = { { "encode_per_complete", 1, - encode_per_complete }, { "decode_ber_tlv", 1, decode_ber_tlv }, { - "encode_ber_tlv", 1, encode_ber_tlv } }; +static ErlNifFunc nif_funcs[] = { + { "encode_per_complete", 1, encode_per_complete }, + { "decode_ber_tlv_raw", 1, decode_ber_tlv_raw }, + { "encode_ber_tlv", 1, encode_ber_tlv }, +}; ERL_NIF_INIT(asn1rt_nif, nif_funcs, load, NULL, upgrade, unload) |