text: /***********************************************************************
   * Copyright (c) 2015 Pieter Wuille                                    *
   * Distributed under the MIT software license, see the accompanying    *
   * file COPYING or https://www.opensource.org/licenses/mit-license.php.*
   ***********************************************************************/
  
  #include <string.h>
  #include <secp256k1.h>
  
  #include "lax_der_parsing.h"
  
  int rustsecp256k1zkp_v0_5_0_ecdsa_signature_parse_der_lax(const rustsecp256k1zkp_v0_5_0_context* ctx, rustsecp256k1zkp_v0_5_0_ecdsa_signature* sig, const unsigned char *input, size_t inputlen) {
      size_t rpos, rlen, spos, slen;
      size_t pos = 0;
      size_t lenbyte;
      unsigned char tmpsig[64] = {0};
      int overflow = 0;
  
      /* Hack to initialize sig with a correctly-parsed but invalid signature. */
      rustsecp256k1zkp_v0_5_0_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
  
      /* Sequence tag byte */
      if (pos == inputlen || input[pos] != 0x30) {
          return 0;
      }
      pos++;
  
      /* Sequence length bytes */
      if (pos == inputlen) {
          return 0;
      }
      lenbyte = input[pos++];
      if (lenbyte & 0x80) {
          lenbyte -= 0x80;
          if (lenbyte > inputlen - pos) {
              return 0;
          }
          pos += lenbyte;
      }
  
      /* Integer tag byte for R */
      if (pos == inputlen || input[pos] != 0x02) {
          return 0;
      }
      pos++;
  
      /* Integer length for R */
      if (pos == inputlen) {
          return 0;
      }
      lenbyte = input[pos++];
      if (lenbyte & 0x80) {
          lenbyte -= 0x80;
          if (lenbyte > inputlen - pos) {
              return 0;
          }
          while (lenbyte > 0 && input[pos] == 0) {
              pos++;
              lenbyte--;
          }
          if (lenbyte >= sizeof(size_t)) {
              return 0;
          }
          rlen = 0;
          while (lenbyte > 0) {
              rlen = (rlen << 8) + input[pos];
              pos++;
              lenbyte--;
          }
      } else {
          rlen = lenbyte;
      }
      if (rlen > inputlen - pos) {
          return 0;
      }
      rpos = pos;
      pos += rlen;
  
      /* Integer tag byte for S */
      if (pos == inputlen || input[pos] != 0x02) {
          return 0;
      }
      pos++;
  
      /* Integer length for S */
      if (pos == inputlen) {
          return 0;
      }
      lenbyte = input[pos++];
      if (lenbyte & 0x80) {
          lenbyte -= 0x80;
          if (lenbyte > inputlen - pos) {
              return 0;
          }
          while (lenbyte > 0 && input[pos] == 0) {
              pos++;
              lenbyte--;
          }
          if (lenbyte >= sizeof(size_t)) {
              return 0;
          }
          slen = 0;
          while (lenbyte > 0) {
              slen = (slen << 8) + input[pos];
              pos++;
              lenbyte--;
          }
      } else {
          slen = lenbyte;
      }
      if (slen > inputlen - pos) {
          return 0;
      }
      spos = pos;
  
      /* Ignore leading zeroes in R */
      while (rlen > 0 && input[rpos] == 0) {
          rlen--;
          rpos++;
      }
      /* Copy R value */
      if (rlen > 32) {
          overflow = 1;
      } else {
          memcpy(tmpsig + 32 - rlen, input + rpos, rlen);
      }
  
      /* Ignore leading zeroes in S */
      while (slen > 0 && input[spos] == 0) {
          slen--;
          spos++;
      }
      /* Copy S value */
      if (slen > 32) {
          overflow = 1;
      } else {
          memcpy(tmpsig + 64 - slen, input + spos, slen);
      }
  
      if (!overflow) {
          overflow = !rustsecp256k1zkp_v0_5_0_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
      }
      if (overflow) {
          memset(tmpsig, 0, 64);
          rustsecp256k1zkp_v0_5_0_ecdsa_signature_parse_compact(ctx, sig, tmpsig);
      }
      return 1;
  }
  
  