bool BytecodeUtil::getAbiVersion()

in plugins/experimental/wasm/lib/src/bytecode_util.cc [31:97]


bool BytecodeUtil::getAbiVersion(std::string_view bytecode, proxy_wasm::AbiVersion &ret) {
  ret = proxy_wasm::AbiVersion::Unknown;
  // Check Wasm header.
  if (!checkWasmHeader(bytecode)) {
    return false;
  }

  // Skip the Wasm header.
  const char *pos = bytecode.data() + 8;
  const char *end = bytecode.data() + bytecode.size();
  while (pos < end) {
    if (pos + 1 > end) {
      return false;
    }
    const auto section_type = *pos++;
    uint32_t section_len = 0;
    if (!parseVarint(pos, end, section_len) || pos + section_len > end) {
      return false;
    }
    if (section_type == 7 /* export section */) {
      const char *section_end = pos + section_len;
      uint32_t export_vector_size = 0;
      if (!parseVarint(pos, section_end, export_vector_size) ||
          pos + export_vector_size > section_end) {
        return false;
      }
      // Search thourgh exports.
      for (uint32_t i = 0; i < export_vector_size; i++) {
        // Parse name of the export.
        uint32_t export_name_size = 0;
        if (!parseVarint(pos, section_end, export_name_size) ||
            pos + export_name_size > section_end) {
          return false;
        }
        const auto *const name_begin = pos;
        pos += export_name_size;
        if (pos + 1 > end) {
          return false;
        }
        // Check if it is a function type export
        if (*pos++ == 0x00 /* function */) {
          const std::string export_name = {name_begin, export_name_size};
          // Check the name of the function.
          if (export_name == "proxy_abi_version_0_1_0") {
            ret = AbiVersion::ProxyWasm_0_1_0;
            return true;
          }
          if (export_name == "proxy_abi_version_0_2_0") {
            ret = AbiVersion::ProxyWasm_0_2_0;
            return true;
          }
          if (export_name == "proxy_abi_version_0_2_1") {
            ret = AbiVersion::ProxyWasm_0_2_1;
            return true;
          }
        }
        // Skip export's index.
        if (!parseVarint(pos, end, export_name_size)) {
          return false;
        }
      }
      return true;
    }
    pos += section_len;
  }
  return true;
}