INTEGER.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353
  1. /*
  2. * Copyright (c) 2003-2019 Lev Walkin <vlm@lionet.info>.
  3. * All rights reserved.
  4. * Redistribution and modifications are permitted subject to BSD license.
  5. */
  6. #include <asn_internal.h>
  7. #include <INTEGER.h>
  8. #include <asn_codecs_prim.h> /* Encoder and decoder of a primitive type */
  9. #include <errno.h>
  10. /*
  11. * INTEGER basic type description.
  12. */
  13. static const ber_tlv_tag_t asn_DEF_INTEGER_tags[] = {
  14. (ASN_TAG_CLASS_UNIVERSAL | (2 << 2))
  15. };
  16. asn_TYPE_operation_t asn_OP_INTEGER = {
  17. INTEGER_free,
  18. INTEGER_print,
  19. INTEGER_compare,
  20. ber_decode_primitive,
  21. INTEGER_encode_der,
  22. INTEGER_decode_xer,
  23. INTEGER_encode_xer,
  24. #ifdef ASN_DISABLE_OER_SUPPORT
  25. 0,
  26. 0,
  27. #else
  28. INTEGER_decode_oer, /* OER decoder */
  29. INTEGER_encode_oer, /* Canonical OER encoder */
  30. #endif /* ASN_DISABLE_OER_SUPPORT */
  31. #ifdef ASN_DISABLE_PER_SUPPORT
  32. 0,
  33. 0,
  34. #else
  35. INTEGER_decode_uper, /* Unaligned PER decoder */
  36. INTEGER_encode_uper, /* Unaligned PER encoder */
  37. #endif /* ASN_DISABLE_PER_SUPPORT */
  38. INTEGER_random_fill,
  39. 0 /* Use generic outmost tag fetcher */
  40. };
  41. asn_TYPE_descriptor_t asn_DEF_INTEGER = {
  42. "INTEGER",
  43. "INTEGER",
  44. &asn_OP_INTEGER,
  45. asn_DEF_INTEGER_tags,
  46. sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
  47. asn_DEF_INTEGER_tags, /* Same as above */
  48. sizeof(asn_DEF_INTEGER_tags) / sizeof(asn_DEF_INTEGER_tags[0]),
  49. { 0, 0, asn_generic_no_constraint },
  50. 0, 0, /* No members */
  51. 0 /* No specifics */
  52. };
  53. /*
  54. * Encode INTEGER type using DER.
  55. */
  56. asn_enc_rval_t
  57. INTEGER_encode_der(const asn_TYPE_descriptor_t *td, const void *sptr,
  58. int tag_mode, ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb,
  59. void *app_key) {
  60. const INTEGER_t *st = (const INTEGER_t *)sptr;
  61. asn_enc_rval_t rval;
  62. INTEGER_t effective_integer;
  63. ASN_DEBUG("%s %s as INTEGER (tm=%d)",
  64. cb?"Encoding":"Estimating", td->name, tag_mode);
  65. /*
  66. * Canonicalize integer in the buffer.
  67. * (Remove too long sign extension, remove some first 0x00 bytes)
  68. */
  69. if(st->buf) {
  70. uint8_t *buf = st->buf;
  71. uint8_t *end1 = buf + st->size - 1;
  72. int shift;
  73. /* Compute the number of superfluous leading bytes */
  74. for(; buf < end1; buf++) {
  75. /*
  76. * If the contents octets of an integer value encoding
  77. * consist of more than one octet, then the bits of the
  78. * first octet and bit 8 of the second octet:
  79. * a) shall not all be ones; and
  80. * b) shall not all be zero.
  81. */
  82. switch(*buf) {
  83. case 0x00: if((buf[1] & 0x80) == 0)
  84. continue;
  85. break;
  86. case 0xff: if((buf[1] & 0x80))
  87. continue;
  88. break;
  89. }
  90. break;
  91. }
  92. /* Remove leading superfluous bytes from the integer */
  93. shift = buf - st->buf;
  94. if(shift) {
  95. union {
  96. const uint8_t *c_buf;
  97. uint8_t *nc_buf;
  98. } unconst;
  99. unconst.c_buf = st->buf;
  100. effective_integer.buf = unconst.nc_buf + shift;
  101. effective_integer.size = st->size - shift;
  102. st = &effective_integer;
  103. }
  104. }
  105. rval = der_encode_primitive(td, st, tag_mode, tag, cb, app_key);
  106. if(rval.structure_ptr == &effective_integer) {
  107. rval.structure_ptr = sptr;
  108. }
  109. return rval;
  110. }
  111. static const asn_INTEGER_enum_map_t *INTEGER_map_enum2value(
  112. const asn_INTEGER_specifics_t *specs, const char *lstart,
  113. const char *lstop);
  114. /*
  115. * INTEGER specific human-readable output.
  116. */
  117. static ssize_t
  118. INTEGER__dump(const asn_TYPE_descriptor_t *td, const INTEGER_t *st, asn_app_consume_bytes_f *cb, void *app_key, int plainOrXER) {
  119. const asn_INTEGER_specifics_t *specs =
  120. (const asn_INTEGER_specifics_t *)td->specifics;
  121. char scratch[32];
  122. uint8_t *buf = st->buf;
  123. uint8_t *buf_end = st->buf + st->size;
  124. intmax_t value;
  125. ssize_t wrote = 0;
  126. char *p;
  127. int ret;
  128. if(specs && specs->field_unsigned)
  129. ret = asn_INTEGER2umax(st, (uintmax_t *)&value);
  130. else
  131. ret = asn_INTEGER2imax(st, &value);
  132. /* Simple case: the integer size is small */
  133. if(ret == 0) {
  134. const asn_INTEGER_enum_map_t *el;
  135. el = (value >= 0 || !specs || !specs->field_unsigned)
  136. ? INTEGER_map_value2enum(specs, value) : 0;
  137. if(el) {
  138. if(plainOrXER == 0)
  139. return asn__format_to_callback(cb, app_key,
  140. "%" ASN_PRIdMAX " (%s)", value, el->enum_name);
  141. else
  142. return asn__format_to_callback(cb, app_key,
  143. "<%s/>", el->enum_name);
  144. } else if(plainOrXER && specs && specs->strict_enumeration) {
  145. ASN_DEBUG("ASN.1 forbids dealing with "
  146. "unknown value of ENUMERATED type");
  147. errno = EPERM;
  148. return -1;
  149. } else {
  150. return asn__format_to_callback(cb, app_key,
  151. (specs && specs->field_unsigned)
  152. ? "%" ASN_PRIuMAX
  153. : "%" ASN_PRIdMAX,
  154. value);
  155. }
  156. } else if(plainOrXER && specs && specs->strict_enumeration) {
  157. /*
  158. * Here and earlier, we cannot encode the ENUMERATED values
  159. * if there is no corresponding identifier.
  160. */
  161. ASN_DEBUG("ASN.1 forbids dealing with "
  162. "unknown value of ENUMERATED type");
  163. errno = EPERM;
  164. return -1;
  165. }
  166. /* Output in the long xx:yy:zz... format */
  167. /* TODO: replace with generic algorithm (Knuth TAOCP Vol 2, 4.3.1) */
  168. for(p = scratch; buf < buf_end; buf++) {
  169. const char * const h2c = "0123456789ABCDEF";
  170. if((p - scratch) >= (ssize_t)(sizeof(scratch) - 4)) {
  171. /* Flush buffer */
  172. if(cb(scratch, p - scratch, app_key) < 0)
  173. return -1;
  174. wrote += p - scratch;
  175. p = scratch;
  176. }
  177. *p++ = h2c[*buf >> 4];
  178. *p++ = h2c[*buf & 0x0F];
  179. *p++ = 0x3a; /* ":" */
  180. }
  181. if(p != scratch)
  182. p--; /* Remove the last ":" */
  183. wrote += p - scratch;
  184. return (cb(scratch, p - scratch, app_key) < 0) ? -1 : wrote;
  185. }
  186. /*
  187. * INTEGER specific human-readable output.
  188. */
  189. int
  190. INTEGER_print(const asn_TYPE_descriptor_t *td, const void *sptr, int ilevel,
  191. asn_app_consume_bytes_f *cb, void *app_key) {
  192. const INTEGER_t *st = (const INTEGER_t *)sptr;
  193. ssize_t ret;
  194. (void)ilevel;
  195. if(!st || !st->buf)
  196. ret = cb("<absent>", 8, app_key);
  197. else
  198. ret = INTEGER__dump(td, st, cb, app_key, 0);
  199. return (ret < 0) ? -1 : 0;
  200. }
  201. struct e2v_key {
  202. const char *start;
  203. const char *stop;
  204. const asn_INTEGER_enum_map_t *vemap;
  205. const unsigned int *evmap;
  206. };
  207. static int
  208. INTEGER__compar_enum2value(const void *kp, const void *am) {
  209. const struct e2v_key *key = (const struct e2v_key *)kp;
  210. const asn_INTEGER_enum_map_t *el = (const asn_INTEGER_enum_map_t *)am;
  211. const char *ptr, *end, *name;
  212. /* Remap the element (sort by different criterion) */
  213. el = key->vemap + key->evmap[el - key->vemap];
  214. /* Compare strings */
  215. for(ptr = key->start, end = key->stop, name = el->enum_name;
  216. ptr < end; ptr++, name++) {
  217. if(*ptr != *name || !*name)
  218. return *(const unsigned char *)ptr
  219. - *(const unsigned char *)name;
  220. }
  221. return name[0] ? -1 : 0;
  222. }
  223. static const asn_INTEGER_enum_map_t *
  224. INTEGER_map_enum2value(const asn_INTEGER_specifics_t *specs, const char *lstart,
  225. const char *lstop) {
  226. const asn_INTEGER_enum_map_t *el_found;
  227. int count = specs ? specs->map_count : 0;
  228. struct e2v_key key;
  229. const char *lp;
  230. if(!count) return NULL;
  231. /* Guaranteed: assert(lstart < lstop); */
  232. /* Figure out the tag name */
  233. for(lstart++, lp = lstart; lp < lstop; lp++) {
  234. switch(*lp) {
  235. case 9: case 10: case 11: case 12: case 13: case 32: /* WSP */
  236. case 0x2f: /* '/' */ case 0x3e: /* '>' */
  237. break;
  238. default:
  239. continue;
  240. }
  241. break;
  242. }
  243. if(lp == lstop) return NULL; /* No tag found */
  244. lstop = lp;
  245. key.start = lstart;
  246. key.stop = lstop;
  247. key.vemap = specs->value2enum;
  248. key.evmap = specs->enum2value;
  249. el_found = (asn_INTEGER_enum_map_t *)bsearch(&key,
  250. specs->value2enum, count, sizeof(specs->value2enum[0]),
  251. INTEGER__compar_enum2value);
  252. if(el_found) {
  253. /* Remap enum2value into value2enum */
  254. el_found = key.vemap + key.evmap[el_found - key.vemap];
  255. }
  256. return el_found;
  257. }
  258. static int
  259. INTEGER__compar_value2enum(const void *kp, const void *am) {
  260. long a = *(const long *)kp;
  261. const asn_INTEGER_enum_map_t *el = (const asn_INTEGER_enum_map_t *)am;
  262. long b = el->nat_value;
  263. if(a < b) return -1;
  264. else if(a == b) return 0;
  265. else return 1;
  266. }
  267. const asn_INTEGER_enum_map_t *
  268. INTEGER_map_value2enum(const asn_INTEGER_specifics_t *specs, long value) {
  269. int count = specs ? specs->map_count : 0;
  270. if(!count) return 0;
  271. return (asn_INTEGER_enum_map_t *)bsearch(&value, specs->value2enum,
  272. count, sizeof(specs->value2enum[0]),
  273. INTEGER__compar_value2enum);
  274. }
  275. static int
  276. INTEGER_st_prealloc(INTEGER_t *st, int min_size) {
  277. void *p = MALLOC(min_size + 1);
  278. if(p) {
  279. void *b = st->buf;
  280. st->size = 0;
  281. st->buf = p;
  282. FREEMEM(b);
  283. return 0;
  284. } else {
  285. return -1;
  286. }
  287. }
  288. /*
  289. * Decode the chunk of XML text encoding INTEGER.
  290. */
  291. static enum xer_pbd_rval
  292. INTEGER__xer_body_decode(const asn_TYPE_descriptor_t *td, void *sptr,
  293. const void *chunk_buf, size_t chunk_size) {
  294. INTEGER_t *st = (INTEGER_t *)sptr;
  295. intmax_t dec_value;
  296. intmax_t hex_value = 0;
  297. const char *lp;
  298. const char *lstart = (const char *)chunk_buf;
  299. const char *lstop = lstart + chunk_size;
  300. enum {
  301. ST_LEADSPACE,
  302. ST_SKIPSPHEX,
  303. ST_WAITDIGITS,
  304. ST_DIGITS,
  305. ST_DIGITS_TRAILSPACE,
  306. ST_HEXDIGIT1,
  307. ST_HEXDIGIT2,
  308. ST_HEXDIGITS_TRAILSPACE,
  309. ST_HEXCOLON,
  310. ST_END_ENUM,
  311. ST_UNEXPECTED
  312. } state = ST_LEADSPACE;
  313. const char *dec_value_start = 0; /* INVARIANT: always !0 in ST_DIGITS */
  314. const char *dec_value_end = 0;
  315. if(chunk_size)
  316. ASN_DEBUG("INTEGER body %ld 0x%2x..0x%2x",
  317. (long)chunk_size, *lstart, lstop[-1]);
  318. if(INTEGER_st_prealloc(st, (chunk_size/3) + 1))
  319. return XPBD_SYSTEM_FAILURE;
  320. /*
  321. * We may have received a tag here. It will be processed inline.
  322. * Use strtoul()-like code and serialize the result.
  323. */
  324. for(lp = lstart; lp < lstop; lp++) {
  325. int lv = *lp;
  326. switch(lv) {
  327. case 0x09: case 0x0a: case 0x0d: case 0x20:
  328. switch(state) {
  329. case ST_LEADSPACE:
  330. case ST_DIGITS_TRAILSPACE:
  331. case ST_HEXDIGITS_TRAILSPACE:
  332. case ST_SKIPSPHEX:
  333. continue;
  334. case ST_DIGITS:
  335. dec_value_end = lp;
  336. state = ST_DIGITS_TRAILSPACE;
  337. continue;
  338. case ST_HEXCOLON:
  339. state = ST_HEXDIGITS_TRAILSPACE;
  340. continue;
  341. default:
  342. break;
  343. }
  344. break;
  345. case 0x2d: /* '-' */
  346. if(state == ST_LEADSPACE) {
  347. dec_value = 0;
  348. dec_value_start = lp;
  349. state = ST_WAITDIGITS;
  350. continue;
  351. }
  352. break;
  353. case 0x2b: /* '+' */
  354. if(state == ST_LEADSPACE) {
  355. dec_value = 0;
  356. dec_value_start = lp;
  357. state = ST_WAITDIGITS;
  358. continue;
  359. }
  360. break;
  361. case 0x30: case 0x31: case 0x32: case 0x33: case 0x34:
  362. case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
  363. switch(state) {
  364. case ST_DIGITS: continue;
  365. case ST_SKIPSPHEX: /* Fall through */
  366. case ST_HEXDIGIT1:
  367. hex_value = (lv - 0x30) << 4;
  368. state = ST_HEXDIGIT2;
  369. continue;
  370. case ST_HEXDIGIT2:
  371. hex_value += (lv - 0x30);
  372. state = ST_HEXCOLON;
  373. st->buf[st->size++] = (uint8_t)hex_value;
  374. continue;
  375. case ST_HEXCOLON:
  376. return XPBD_BROKEN_ENCODING;
  377. case ST_LEADSPACE:
  378. dec_value = 0;
  379. dec_value_start = lp;
  380. /* FALL THROUGH */
  381. case ST_WAITDIGITS:
  382. state = ST_DIGITS;
  383. continue;
  384. default:
  385. break;
  386. }
  387. break;
  388. case 0x3c: /* '<', start of XML encoded enumeration */
  389. if(state == ST_LEADSPACE) {
  390. const asn_INTEGER_enum_map_t *el;
  391. el = INTEGER_map_enum2value(
  392. (const asn_INTEGER_specifics_t *)
  393. td->specifics, lstart, lstop);
  394. if(el) {
  395. ASN_DEBUG("Found \"%s\" => %ld",
  396. el->enum_name, el->nat_value);
  397. dec_value = el->nat_value;
  398. state = ST_END_ENUM;
  399. lp = lstop - 1;
  400. continue;
  401. }
  402. ASN_DEBUG("Unknown identifier for INTEGER");
  403. }
  404. return XPBD_BROKEN_ENCODING;
  405. case 0x3a: /* ':' */
  406. if(state == ST_HEXCOLON) {
  407. /* This colon is expected */
  408. state = ST_HEXDIGIT1;
  409. continue;
  410. } else if(state == ST_DIGITS) {
  411. /* The colon here means that we have
  412. * decoded the first two hexadecimal
  413. * places as a decimal value.
  414. * Switch decoding mode. */
  415. ASN_DEBUG("INTEGER re-evaluate as hex form");
  416. state = ST_SKIPSPHEX;
  417. dec_value_start = 0;
  418. lp = lstart - 1;
  419. continue;
  420. } else {
  421. ASN_DEBUG("state %d at %ld", state, (long)(lp - lstart));
  422. break;
  423. }
  424. /* [A-Fa-f] */
  425. case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:
  426. case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:
  427. switch(state) {
  428. case ST_SKIPSPHEX:
  429. case ST_LEADSPACE: /* Fall through */
  430. case ST_HEXDIGIT1:
  431. hex_value = lv - ((lv < 0x61) ? 0x41 : 0x61);
  432. hex_value += 10;
  433. hex_value <<= 4;
  434. state = ST_HEXDIGIT2;
  435. continue;
  436. case ST_HEXDIGIT2:
  437. hex_value += lv - ((lv < 0x61) ? 0x41 : 0x61);
  438. hex_value += 10;
  439. st->buf[st->size++] = (uint8_t)hex_value;
  440. state = ST_HEXCOLON;
  441. continue;
  442. case ST_DIGITS:
  443. ASN_DEBUG("INTEGER re-evaluate as hex form");
  444. state = ST_SKIPSPHEX;
  445. dec_value_start = 0;
  446. lp = lstart - 1;
  447. continue;
  448. default:
  449. break;
  450. }
  451. break;
  452. }
  453. /* Found extra non-numeric stuff */
  454. ASN_DEBUG("INTEGER :: Found non-numeric 0x%2x at %ld",
  455. lv, (long)(lp - lstart));
  456. state = ST_UNEXPECTED;
  457. break;
  458. }
  459. switch(state) {
  460. case ST_END_ENUM:
  461. /* Got a complete and valid enumeration encoded as a tag. */
  462. break;
  463. case ST_DIGITS:
  464. dec_value_end = lstop;
  465. /* FALL THROUGH */
  466. case ST_DIGITS_TRAILSPACE:
  467. /* The last symbol encountered was a digit. */
  468. switch(asn_strtoimax_lim(dec_value_start, &dec_value_end, &dec_value)) {
  469. case ASN_STRTOX_OK:
  470. if(dec_value >= LONG_MIN && dec_value <= LONG_MAX) {
  471. break;
  472. } else {
  473. /*
  474. * We model INTEGER on long for XER,
  475. * to avoid rewriting all the tests at once.
  476. */
  477. ASN_DEBUG("INTEGER exceeds long range");
  478. }
  479. /* Fall through */
  480. case ASN_STRTOX_ERROR_RANGE:
  481. ASN_DEBUG("INTEGER decode %s hit range limit", td->name);
  482. return XPBD_DECODER_LIMIT;
  483. case ASN_STRTOX_ERROR_INVAL:
  484. case ASN_STRTOX_EXPECT_MORE:
  485. case ASN_STRTOX_EXTRA_DATA:
  486. return XPBD_BROKEN_ENCODING;
  487. }
  488. break;
  489. case ST_HEXCOLON:
  490. case ST_HEXDIGITS_TRAILSPACE:
  491. st->buf[st->size] = 0; /* Just in case termination */
  492. return XPBD_BODY_CONSUMED;
  493. case ST_HEXDIGIT1:
  494. case ST_HEXDIGIT2:
  495. case ST_SKIPSPHEX:
  496. return XPBD_BROKEN_ENCODING;
  497. case ST_LEADSPACE:
  498. /* Content not found */
  499. return XPBD_NOT_BODY_IGNORE;
  500. case ST_WAITDIGITS:
  501. case ST_UNEXPECTED:
  502. ASN_DEBUG("INTEGER: No useful digits (state %d)", state);
  503. return XPBD_BROKEN_ENCODING; /* No digits */
  504. }
  505. /*
  506. * Convert the result of parsing of enumeration or a straight
  507. * decimal value into a BER representation.
  508. */
  509. if(asn_imax2INTEGER(st, dec_value)) {
  510. ASN_DEBUG("INTEGER decode %s conversion failed", td->name);
  511. return XPBD_SYSTEM_FAILURE;
  512. }
  513. return XPBD_BODY_CONSUMED;
  514. }
  515. asn_dec_rval_t
  516. INTEGER_decode_xer(const asn_codec_ctx_t *opt_codec_ctx,
  517. const asn_TYPE_descriptor_t *td, void **sptr,
  518. const char *opt_mname, const void *buf_ptr, size_t size) {
  519. return xer_decode_primitive(opt_codec_ctx, td,
  520. sptr, sizeof(INTEGER_t), opt_mname,
  521. buf_ptr, size, INTEGER__xer_body_decode);
  522. }
  523. asn_enc_rval_t
  524. INTEGER_encode_xer(const asn_TYPE_descriptor_t *td, const void *sptr,
  525. int ilevel, enum xer_encoder_flags_e flags,
  526. asn_app_consume_bytes_f *cb, void *app_key) {
  527. const INTEGER_t *st = (const INTEGER_t *)sptr;
  528. asn_enc_rval_t er;
  529. (void)ilevel;
  530. (void)flags;
  531. if(!st || !st->buf)
  532. ASN__ENCODE_FAILED;
  533. er.encoded = INTEGER__dump(td, st, cb, app_key, 1);
  534. if(er.encoded < 0) ASN__ENCODE_FAILED;
  535. ASN__ENCODED_OK(er);
  536. }
  537. #ifndef ASN_DISABLE_PER_SUPPORT
  538. asn_dec_rval_t
  539. INTEGER_decode_uper(const asn_codec_ctx_t *opt_codec_ctx,
  540. const asn_TYPE_descriptor_t *td,
  541. const asn_per_constraints_t *constraints, void **sptr,
  542. asn_per_data_t *pd) {
  543. const asn_INTEGER_specifics_t *specs =
  544. (const asn_INTEGER_specifics_t *)td->specifics;
  545. asn_dec_rval_t rval = { RC_OK, 0 };
  546. INTEGER_t *st = (INTEGER_t *)*sptr;
  547. const asn_per_constraint_t *ct;
  548. int repeat;
  549. (void)opt_codec_ctx;
  550. if(!st) {
  551. st = (INTEGER_t *)(*sptr = CALLOC(1, sizeof(*st)));
  552. if(!st) ASN__DECODE_FAILED;
  553. }
  554. if(!constraints) constraints = td->encoding_constraints.per_constraints;
  555. ct = constraints ? &constraints->value : 0;
  556. if(ct && ct->flags & APC_EXTENSIBLE) {
  557. int inext = per_get_few_bits(pd, 1);
  558. if(inext < 0) ASN__DECODE_STARVED;
  559. if(inext) ct = 0;
  560. }
  561. FREEMEM(st->buf);
  562. st->buf = 0;
  563. st->size = 0;
  564. if(ct) {
  565. if(ct->flags & APC_SEMI_CONSTRAINED) {
  566. st->buf = (uint8_t *)CALLOC(1, 2);
  567. if(!st->buf) ASN__DECODE_FAILED;
  568. st->size = 1;
  569. } else if(ct->flags & APC_CONSTRAINED && ct->range_bits >= 0) {
  570. size_t size = (ct->range_bits + 7) >> 3;
  571. st->buf = (uint8_t *)MALLOC(1 + size + 1);
  572. if(!st->buf) ASN__DECODE_FAILED;
  573. st->size = size;
  574. }
  575. }
  576. /* X.691-2008/11, #13.2.2, constrained whole number */
  577. if(ct && ct->flags != APC_UNCONSTRAINED) {
  578. /* #11.5.6 */
  579. ASN_DEBUG("Integer with range %d bits", ct->range_bits);
  580. if(ct->range_bits >= 0) {
  581. if((size_t)ct->range_bits > 8 * sizeof(unsigned long))
  582. ASN__DECODE_FAILED;
  583. if(specs && specs->field_unsigned) {
  584. unsigned long uvalue = 0;
  585. if(uper_get_constrained_whole_number(pd,
  586. &uvalue, ct->range_bits))
  587. ASN__DECODE_STARVED;
  588. ASN_DEBUG("Got value %lu + low %ld",
  589. uvalue, ct->lower_bound);
  590. uvalue += ct->lower_bound;
  591. if(asn_ulong2INTEGER(st, uvalue))
  592. ASN__DECODE_FAILED;
  593. } else {
  594. unsigned long uvalue = 0;
  595. long svalue;
  596. if(uper_get_constrained_whole_number(pd,
  597. &uvalue, ct->range_bits))
  598. ASN__DECODE_STARVED;
  599. ASN_DEBUG("Got value %lu + low %ld",
  600. uvalue, ct->lower_bound);
  601. if(per_long_range_unrebase(uvalue, ct->lower_bound,
  602. ct->upper_bound, &svalue)
  603. || asn_long2INTEGER(st, svalue)) {
  604. ASN__DECODE_FAILED;
  605. }
  606. }
  607. return rval;
  608. }
  609. } else {
  610. ASN_DEBUG("Decoding unconstrained integer %s", td->name);
  611. }
  612. /* X.691, #12.2.3, #12.2.4 */
  613. do {
  614. ssize_t len = 0;
  615. void *p = NULL;
  616. int ret = 0;
  617. /* Get the PER length */
  618. len = uper_get_length(pd, -1, 0, &repeat);
  619. if(len < 0) ASN__DECODE_STARVED;
  620. p = REALLOC(st->buf, st->size + len + 1);
  621. if(!p) ASN__DECODE_FAILED;
  622. st->buf = (uint8_t *)p;
  623. ret = per_get_many_bits(pd, &st->buf[st->size], 0, 8 * len);
  624. if(ret < 0) ASN__DECODE_STARVED;
  625. st->size += len;
  626. } while(repeat);
  627. st->buf[st->size] = 0; /* JIC */
  628. /* #12.2.3 */
  629. if(ct && ct->lower_bound) {
  630. /*
  631. * TODO: replace by in-place arithmetics.
  632. */
  633. long value = 0;
  634. if(asn_INTEGER2long(st, &value))
  635. ASN__DECODE_FAILED;
  636. if(asn_imax2INTEGER(st, value + ct->lower_bound))
  637. ASN__DECODE_FAILED;
  638. }
  639. return rval;
  640. }
  641. asn_enc_rval_t
  642. INTEGER_encode_uper(const asn_TYPE_descriptor_t *td,
  643. const asn_per_constraints_t *constraints, const void *sptr,
  644. asn_per_outp_t *po) {
  645. const asn_INTEGER_specifics_t *specs =
  646. (const asn_INTEGER_specifics_t *)td->specifics;
  647. asn_enc_rval_t er;
  648. const INTEGER_t *st = (const INTEGER_t *)sptr;
  649. const uint8_t *buf;
  650. const uint8_t *end;
  651. const asn_per_constraint_t *ct;
  652. long value = 0;
  653. if(!st || st->size == 0) ASN__ENCODE_FAILED;
  654. if(!constraints) constraints = td->encoding_constraints.per_constraints;
  655. ct = constraints ? &constraints->value : 0;
  656. er.encoded = 0;
  657. if(ct) {
  658. int inext = 0;
  659. if(specs && specs->field_unsigned) {
  660. unsigned long uval;
  661. if(asn_INTEGER2ulong(st, &uval))
  662. ASN__ENCODE_FAILED;
  663. /* Check proper range */
  664. if(ct->flags & APC_SEMI_CONSTRAINED) {
  665. if(uval < (unsigned long)ct->lower_bound)
  666. inext = 1;
  667. } else if(ct->range_bits >= 0) {
  668. if(uval < (unsigned long)ct->lower_bound
  669. || uval > (unsigned long)ct->upper_bound)
  670. inext = 1;
  671. }
  672. ASN_DEBUG("Value %lu (%02x/%" ASN_PRI_SIZE ") lb %lu ub %lu %s",
  673. uval, st->buf[0], st->size,
  674. ct->lower_bound, ct->upper_bound,
  675. inext ? "ext" : "fix");
  676. value = uval;
  677. } else {
  678. if(asn_INTEGER2long(st, &value))
  679. ASN__ENCODE_FAILED;
  680. /* Check proper range */
  681. if(ct->flags & APC_SEMI_CONSTRAINED) {
  682. if(value < ct->lower_bound)
  683. inext = 1;
  684. } else if(ct->range_bits >= 0) {
  685. if(value < ct->lower_bound
  686. || value > ct->upper_bound)
  687. inext = 1;
  688. }
  689. ASN_DEBUG("Value %ld (%02x/%" ASN_PRI_SIZE ") lb %ld ub %ld %s",
  690. value, st->buf[0], st->size,
  691. ct->lower_bound, ct->upper_bound,
  692. inext ? "ext" : "fix");
  693. }
  694. if(ct->flags & APC_EXTENSIBLE) {
  695. if(per_put_few_bits(po, inext, 1))
  696. ASN__ENCODE_FAILED;
  697. if(inext) ct = 0;
  698. } else if(inext) {
  699. ASN__ENCODE_FAILED;
  700. }
  701. }
  702. /* X.691-11/2008, #13.2.2, test if constrained whole number */
  703. if(ct && ct->range_bits >= 0) {
  704. unsigned long v;
  705. /* #11.5.6 -> #11.3 */
  706. ASN_DEBUG("Encoding integer %ld (%lu) with range %d bits",
  707. value, value - ct->lower_bound, ct->range_bits);
  708. if(per_long_range_rebase(value, ct->lower_bound, ct->upper_bound, &v)) {
  709. ASN__ENCODE_FAILED;
  710. }
  711. if(uper_put_constrained_whole_number_u(po, v, ct->range_bits))
  712. ASN__ENCODE_FAILED;
  713. ASN__ENCODED_OK(er);
  714. }
  715. if(ct && ct->lower_bound) {
  716. ASN_DEBUG("Adjust lower bound to %ld", ct->lower_bound);
  717. /* TODO: adjust lower bound */
  718. ASN__ENCODE_FAILED;
  719. }
  720. for(buf = st->buf, end = st->buf + st->size; buf < end;) {
  721. int need_eom = 0;
  722. ssize_t mayEncode = uper_put_length(po, end - buf, &need_eom);
  723. if(mayEncode < 0)
  724. ASN__ENCODE_FAILED;
  725. if(per_put_many_bits(po, buf, 8 * mayEncode))
  726. ASN__ENCODE_FAILED;
  727. buf += mayEncode;
  728. if(need_eom && uper_put_length(po, 0, 0)) ASN__ENCODE_FAILED;
  729. }
  730. ASN__ENCODED_OK(er);
  731. }
  732. #endif /* ASN_DISABLE_PER_SUPPORT */
  733. static intmax_t
  734. asn__integer_convert(const uint8_t *b, const uint8_t *end) {
  735. uintmax_t value;
  736. /* Perform the sign initialization */
  737. /* Actually value = -(*b >> 7); gains nothing, yet unreadable! */
  738. if((*b >> 7)) {
  739. value = (uintmax_t)(-1);
  740. } else {
  741. value = 0;
  742. }
  743. /* Conversion engine */
  744. for(; b < end; b++) {
  745. value = (value << 8) | *b;
  746. }
  747. return value;
  748. }
  749. int
  750. asn_INTEGER2imax(const INTEGER_t *iptr, intmax_t *lptr) {
  751. uint8_t *b, *end;
  752. size_t size;
  753. /* Sanity checking */
  754. if(!iptr || !iptr->buf || !lptr) {
  755. errno = EINVAL;
  756. return -1;
  757. }
  758. /* Cache the begin/end of the buffer */
  759. b = iptr->buf; /* Start of the INTEGER buffer */
  760. size = iptr->size;
  761. end = b + size; /* Where to stop */
  762. if(size > sizeof(intmax_t)) {
  763. uint8_t *end1 = end - 1;
  764. /*
  765. * Slightly more advanced processing,
  766. * able to process INTEGERs with >sizeof(intmax_t) bytes
  767. * when the actual value is small, e.g. for intmax_t == int32_t
  768. * (0x0000000000abcdef INTEGER would yield a fine 0x00abcdef int32_t)
  769. */
  770. /* Skip out the insignificant leading bytes */
  771. for(; b < end1; b++) {
  772. switch(*b) {
  773. case 0x00: if((b[1] & 0x80) == 0) continue; break;
  774. case 0xff: if((b[1] & 0x80) != 0) continue; break;
  775. }
  776. break;
  777. }
  778. size = end - b;
  779. if(size > sizeof(intmax_t)) {
  780. /* Still cannot fit the sizeof(intmax_t) */
  781. errno = ERANGE;
  782. return -1;
  783. }
  784. }
  785. /* Shortcut processing of a corner case */
  786. if(end == b) {
  787. *lptr = 0;
  788. return 0;
  789. }
  790. *lptr = asn__integer_convert(b, end);
  791. return 0;
  792. }
  793. /* FIXME: negative INTEGER values are silently interpreted as large unsigned ones. */
  794. int
  795. asn_INTEGER2umax(const INTEGER_t *iptr, uintmax_t *lptr) {
  796. uint8_t *b, *end;
  797. uintmax_t value;
  798. size_t size;
  799. if(!iptr || !iptr->buf || !lptr) {
  800. errno = EINVAL;
  801. return -1;
  802. }
  803. b = iptr->buf;
  804. size = iptr->size;
  805. end = b + size;
  806. /* If all extra leading bytes are zeroes, ignore them */
  807. for(; size > sizeof(value); b++, size--) {
  808. if(*b) {
  809. /* Value won't fit into uintmax_t */
  810. errno = ERANGE;
  811. return -1;
  812. }
  813. }
  814. /* Conversion engine */
  815. for(value = 0; b < end; b++)
  816. value = (value << 8) | *b;
  817. *lptr = value;
  818. return 0;
  819. }
  820. int
  821. asn_umax2INTEGER(INTEGER_t *st, uintmax_t value) {
  822. uint8_t *buf;
  823. uint8_t *end;
  824. uint8_t *b;
  825. int shr;
  826. if(value <= ((~(uintmax_t)0) >> 1)) {
  827. return asn_imax2INTEGER(st, value);
  828. }
  829. buf = (uint8_t *)MALLOC(1 + sizeof(value));
  830. if(!buf) return -1;
  831. end = buf + (sizeof(value) + 1);
  832. buf[0] = 0; /* INTEGERs are signed. 0-byte indicates positive. */
  833. for(b = buf + 1, shr = (sizeof(value) - 1) * 8; b < end; shr -= 8, b++)
  834. *b = (uint8_t)(value >> shr);
  835. if(st->buf) FREEMEM(st->buf);
  836. st->buf = buf;
  837. st->size = 1 + sizeof(value);
  838. return 0;
  839. }
  840. int
  841. asn_imax2INTEGER(INTEGER_t *st, intmax_t value) {
  842. uint8_t *buf, *bp;
  843. uint8_t *p;
  844. uint8_t *pstart;
  845. uint8_t *pend1;
  846. int littleEndian = 1; /* Run-time detection */
  847. int add;
  848. if(!st) {
  849. errno = EINVAL;
  850. return -1;
  851. }
  852. buf = (uint8_t *)(long *)MALLOC(sizeof(value));
  853. if(!buf) return -1;
  854. if(*(char *)&littleEndian) {
  855. pstart = (uint8_t *)&value + sizeof(value) - 1;
  856. pend1 = (uint8_t *)&value;
  857. add = -1;
  858. } else {
  859. pstart = (uint8_t *)&value;
  860. pend1 = pstart + sizeof(value) - 1;
  861. add = 1;
  862. }
  863. /*
  864. * If the contents octet consists of more than one octet,
  865. * then bits of the first octet and bit 8 of the second octet:
  866. * a) shall not all be ones; and
  867. * b) shall not all be zero.
  868. */
  869. for(p = pstart; p != pend1; p += add) {
  870. switch(*p) {
  871. case 0x00: if((*(p+add) & 0x80) == 0)
  872. continue;
  873. break;
  874. case 0xff: if((*(p+add) & 0x80))
  875. continue;
  876. break;
  877. }
  878. break;
  879. }
  880. /* Copy the integer body */
  881. for(bp = buf, pend1 += add; p != pend1; p += add)
  882. *bp++ = *p;
  883. if(st->buf) FREEMEM(st->buf);
  884. st->buf = buf;
  885. st->size = bp - buf;
  886. return 0;
  887. }
  888. int
  889. asn_INTEGER2long(const INTEGER_t *iptr, long *l) {
  890. intmax_t v;
  891. if(asn_INTEGER2imax(iptr, &v) == 0) {
  892. if(v < LONG_MIN || v > LONG_MAX) {
  893. errno = ERANGE;
  894. return -1;
  895. }
  896. *l = v;
  897. return 0;
  898. } else {
  899. return -1;
  900. }
  901. }
  902. int
  903. asn_INTEGER2ulong(const INTEGER_t *iptr, unsigned long *l) {
  904. uintmax_t v;
  905. if(asn_INTEGER2umax(iptr, &v) == 0) {
  906. if(v > ULONG_MAX) {
  907. errno = ERANGE;
  908. return -1;
  909. }
  910. *l = v;
  911. return 0;
  912. } else {
  913. return -1;
  914. }
  915. }
  916. int
  917. asn_long2INTEGER(INTEGER_t *st, long value) {
  918. return asn_imax2INTEGER(st, value);
  919. }
  920. int
  921. asn_ulong2INTEGER(INTEGER_t *st, unsigned long value) {
  922. return asn_imax2INTEGER(st, value);
  923. }
  924. /*
  925. * Parse the number in the given string until the given *end position,
  926. * returning the position after the last parsed character back using the
  927. * same (*end) pointer.
  928. * WARNING: This behavior is different from the standard strtol/strtoimax(3).
  929. */
  930. enum asn_strtox_result_e
  931. asn_strtoimax_lim(const char *str, const char **end, intmax_t *intp) {
  932. int sign = 1;
  933. intmax_t value;
  934. const intmax_t asn1_intmax_max = ((~(uintmax_t)0) >> 1);
  935. const intmax_t upper_boundary = asn1_intmax_max / 10;
  936. intmax_t last_digit_max = asn1_intmax_max % 10;
  937. if(str >= *end) return ASN_STRTOX_ERROR_INVAL;
  938. switch(*str) {
  939. case '-':
  940. last_digit_max++;
  941. sign = -1;
  942. /* FALL THROUGH */
  943. case '+':
  944. str++;
  945. if(str >= *end) {
  946. *end = str;
  947. return ASN_STRTOX_EXPECT_MORE;
  948. }
  949. }
  950. for(value = 0; str < (*end); str++) {
  951. if(*str >= 0x30 && *str <= 0x39) {
  952. int d = *str - '0';
  953. if(value < upper_boundary) {
  954. value = value * 10 + d;
  955. } else if(value == upper_boundary) {
  956. if(d <= last_digit_max) {
  957. if(sign > 0) {
  958. value = value * 10 + d;
  959. } else {
  960. sign = 1;
  961. value = -value * 10 - d;
  962. }
  963. str += 1;
  964. if(str < *end) {
  965. // If digits continue, we're guaranteed out of range.
  966. *end = str;
  967. if(*str >= 0x30 && *str <= 0x39) {
  968. return ASN_STRTOX_ERROR_RANGE;
  969. } else {
  970. *intp = sign * value;
  971. return ASN_STRTOX_EXTRA_DATA;
  972. }
  973. }
  974. break;
  975. } else {
  976. *end = str;
  977. return ASN_STRTOX_ERROR_RANGE;
  978. }
  979. } else {
  980. *end = str;
  981. return ASN_STRTOX_ERROR_RANGE;
  982. }
  983. } else {
  984. *end = str;
  985. *intp = sign * value;
  986. return ASN_STRTOX_EXTRA_DATA;
  987. }
  988. }
  989. *end = str;
  990. *intp = sign * value;
  991. return ASN_STRTOX_OK;
  992. }
  993. /*
  994. * Parse the number in the given string until the given *end position,
  995. * returning the position after the last parsed character back using the
  996. * same (*end) pointer.
  997. * WARNING: This behavior is different from the standard strtoul/strtoumax(3).
  998. */
  999. enum asn_strtox_result_e
  1000. asn_strtoumax_lim(const char *str, const char **end, uintmax_t *uintp) {
  1001. uintmax_t value;
  1002. const uintmax_t asn1_uintmax_max = ((~(uintmax_t)0));
  1003. const uintmax_t upper_boundary = asn1_uintmax_max / 10;
  1004. uintmax_t last_digit_max = asn1_uintmax_max % 10;
  1005. if(str >= *end) return ASN_STRTOX_ERROR_INVAL;
  1006. switch(*str) {
  1007. case '-':
  1008. return ASN_STRTOX_ERROR_INVAL;
  1009. case '+':
  1010. str++;
  1011. if(str >= *end) {
  1012. *end = str;
  1013. return ASN_STRTOX_EXPECT_MORE;
  1014. }
  1015. }
  1016. for(value = 0; str < (*end); str++) {
  1017. if(*str >= 0x30 && *str <= 0x39) {
  1018. unsigned int d = *str - '0';
  1019. if(value < upper_boundary) {
  1020. value = value * 10 + d;
  1021. } else if(value == upper_boundary) {
  1022. if(d <= last_digit_max) {
  1023. value = value * 10 + d;
  1024. str += 1;
  1025. if(str < *end) {
  1026. // If digits continue, we're guaranteed out of range.
  1027. *end = str;
  1028. if(*str >= 0x30 && *str <= 0x39) {
  1029. return ASN_STRTOX_ERROR_RANGE;
  1030. } else {
  1031. *uintp = value;
  1032. return ASN_STRTOX_EXTRA_DATA;
  1033. }
  1034. }
  1035. break;
  1036. } else {
  1037. *end = str;
  1038. return ASN_STRTOX_ERROR_RANGE;
  1039. }
  1040. } else {
  1041. *end = str;
  1042. return ASN_STRTOX_ERROR_RANGE;
  1043. }
  1044. } else {
  1045. *end = str;
  1046. *uintp = value;
  1047. return ASN_STRTOX_EXTRA_DATA;
  1048. }
  1049. }
  1050. *end = str;
  1051. *uintp = value;
  1052. return ASN_STRTOX_OK;
  1053. }
  1054. enum asn_strtox_result_e
  1055. asn_strtol_lim(const char *str, const char **end, long *lp) {
  1056. intmax_t value;
  1057. switch(asn_strtoimax_lim(str, end, &value)) {
  1058. case ASN_STRTOX_ERROR_RANGE:
  1059. return ASN_STRTOX_ERROR_RANGE;
  1060. case ASN_STRTOX_ERROR_INVAL:
  1061. return ASN_STRTOX_ERROR_INVAL;
  1062. case ASN_STRTOX_EXPECT_MORE:
  1063. return ASN_STRTOX_EXPECT_MORE;
  1064. case ASN_STRTOX_OK:
  1065. if(value >= LONG_MIN && value <= LONG_MAX) {
  1066. *lp = value;
  1067. return ASN_STRTOX_OK;
  1068. } else {
  1069. return ASN_STRTOX_ERROR_RANGE;
  1070. }
  1071. case ASN_STRTOX_EXTRA_DATA:
  1072. if(value >= LONG_MIN && value <= LONG_MAX) {
  1073. *lp = value;
  1074. return ASN_STRTOX_EXTRA_DATA;
  1075. } else {
  1076. return ASN_STRTOX_ERROR_RANGE;
  1077. }
  1078. }
  1079. assert(!"Unreachable");
  1080. return ASN_STRTOX_ERROR_INVAL;
  1081. }
  1082. enum asn_strtox_result_e
  1083. asn_strtoul_lim(const char *str, const char **end, unsigned long *ulp) {
  1084. uintmax_t value;
  1085. switch(asn_strtoumax_lim(str, end, &value)) {
  1086. case ASN_STRTOX_ERROR_RANGE:
  1087. return ASN_STRTOX_ERROR_RANGE;
  1088. case ASN_STRTOX_ERROR_INVAL:
  1089. return ASN_STRTOX_ERROR_INVAL;
  1090. case ASN_STRTOX_EXPECT_MORE:
  1091. return ASN_STRTOX_EXPECT_MORE;
  1092. case ASN_STRTOX_OK:
  1093. if(value <= ULONG_MAX) {
  1094. *ulp = value;
  1095. return ASN_STRTOX_OK;
  1096. } else {
  1097. return ASN_STRTOX_ERROR_RANGE;
  1098. }
  1099. case ASN_STRTOX_EXTRA_DATA:
  1100. if(value <= ULONG_MAX) {
  1101. *ulp = value;
  1102. return ASN_STRTOX_EXTRA_DATA;
  1103. } else {
  1104. return ASN_STRTOX_ERROR_RANGE;
  1105. }
  1106. }
  1107. assert(!"Unreachable");
  1108. return ASN_STRTOX_ERROR_INVAL;
  1109. }
  1110. int
  1111. INTEGER_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
  1112. const void *bptr) {
  1113. const INTEGER_t *a = aptr;
  1114. const INTEGER_t *b = bptr;
  1115. (void)td;
  1116. if(a && b) {
  1117. if(a->size && b->size) {
  1118. int sign_a = (a->buf[0] & 0x80) ? -1 : 1;
  1119. int sign_b = (b->buf[0] & 0x80) ? -1 : 1;
  1120. if(sign_a < sign_b) return -1;
  1121. if(sign_a > sign_b) return 1;
  1122. /* The shortest integer wins, unless comparing negatives */
  1123. if(a->size < b->size) {
  1124. return -1 * sign_a;
  1125. } else if(a->size > b->size) {
  1126. return 1 * sign_b;
  1127. }
  1128. return sign_a * memcmp(a->buf, b->buf, a->size);
  1129. } else if(a->size) {
  1130. int sign = (a->buf[0] & 0x80) ? -1 : 1;
  1131. return (1) * sign;
  1132. } else if(b->size) {
  1133. int sign = (a->buf[0] & 0x80) ? -1 : 1;
  1134. return (-1) * sign;
  1135. } else {
  1136. return 0;
  1137. }
  1138. } else if(!a && !b) {
  1139. return 0;
  1140. } else if(!a) {
  1141. return -1;
  1142. } else {
  1143. return 1;
  1144. }
  1145. }
  1146. asn_random_fill_result_t
  1147. INTEGER_random_fill(const asn_TYPE_descriptor_t *td, void **sptr,
  1148. const asn_encoding_constraints_t *constraints,
  1149. size_t max_length) {
  1150. const asn_INTEGER_specifics_t *specs =
  1151. (const asn_INTEGER_specifics_t *)td->specifics;
  1152. asn_random_fill_result_t result_ok = {ARFILL_OK, 1};
  1153. asn_random_fill_result_t result_failed = {ARFILL_FAILED, 0};
  1154. asn_random_fill_result_t result_skipped = {ARFILL_SKIPPED, 0};
  1155. INTEGER_t *st = *sptr;
  1156. const asn_INTEGER_enum_map_t *emap;
  1157. size_t emap_len;
  1158. intmax_t value;
  1159. int find_inside_map;
  1160. if(max_length == 0) return result_skipped;
  1161. if(st == NULL) {
  1162. st = (INTEGER_t *)CALLOC(1, sizeof(*st));
  1163. if(st == NULL) {
  1164. return result_failed;
  1165. }
  1166. }
  1167. if(specs) {
  1168. emap = specs->value2enum;
  1169. emap_len = specs->map_count;
  1170. if(specs->strict_enumeration) {
  1171. find_inside_map = emap_len > 0;
  1172. } else {
  1173. find_inside_map = emap_len ? asn_random_between(0, 1) : 0;
  1174. }
  1175. } else {
  1176. emap = 0;
  1177. emap_len = 0;
  1178. find_inside_map = 0;
  1179. }
  1180. if(find_inside_map) {
  1181. assert(emap_len > 0);
  1182. value = emap[asn_random_between(0, emap_len - 1)].nat_value;
  1183. } else {
  1184. const asn_per_constraints_t *ct;
  1185. static const long variants[] = {
  1186. -65536, -65535, -65534, -32769, -32768, -32767, -16385, -16384,
  1187. -16383, -257, -256, -255, -254, -129, -128, -127,
  1188. -126, -1, 0, 1, 126, 127, 128, 129,
  1189. 254, 255, 256, 257, 16383, 16384, 16385, 32767,
  1190. 32768, 32769, 65534, 65535, 65536, 65537};
  1191. if(specs && specs->field_unsigned) {
  1192. assert(variants[18] == 0);
  1193. value = variants[asn_random_between(
  1194. 18, sizeof(variants) / sizeof(variants[0]) - 1)];
  1195. } else {
  1196. value = variants[asn_random_between(
  1197. 0, sizeof(variants) / sizeof(variants[0]) - 1)];
  1198. }
  1199. if(!constraints) constraints = &td->encoding_constraints;
  1200. ct = constraints ? constraints->per_constraints : 0;
  1201. if(ct && (ct->value.flags & APC_CONSTRAINED)) {
  1202. if(value < ct->value.lower_bound || value > ct->value.upper_bound) {
  1203. value = asn_random_between(ct->value.lower_bound,
  1204. ct->value.upper_bound);
  1205. }
  1206. }
  1207. }
  1208. if(asn_imax2INTEGER(st, value)) {
  1209. if(st == *sptr) {
  1210. ASN_STRUCT_RESET(*td, st);
  1211. } else {
  1212. ASN_STRUCT_FREE(*td, st);
  1213. }
  1214. return result_failed;
  1215. } else {
  1216. *sptr = st;
  1217. result_ok.length = st->size;
  1218. return result_ok;
  1219. }
  1220. }