Skip to content

Compile error: (KeyError) key 10 not found. OTP-23, Elixir 1.11.0 #10431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
demoj1 opened this issue Oct 16, 2020 · 1 comment
Closed

Compile error: (KeyError) key 10 not found. OTP-23, Elixir 1.11.0 #10431

demoj1 opened this issue Oct 16, 2020 · 1 comment

Comments

@demoj1
Copy link

demoj1 commented Oct 16, 2020

Precheck

  • Do not use the issue tracker for help or support (try Elixir Forum, Stack Overflow, IRC, etc.)
  • For proposing a new feature, please start a discussion on the Elixir Core mailing list: https://groups.google.com/group/elixir-lang-core
  • For bugs, do a quick search and make sure the bug has not yet been reported
  • Please disclose security vulnerabilities privately at [email protected]
  • Finally, be nice and have fun!

Environment

  • Elixir & Erlang/OTP versions (elixir --version):
    Erlang/OTP 23 [erts-11.1.1] [source] [64-bit] [smp:3:3] [ds:3:3:10] [async-threads:1] [hipe]
    Elixir 1.11.0 (compiled with Erlang/OTP 23)

  • Operating system:
    Docker with ubuntu 18.04
    Linux abf86ad29340 4.19.76-linuxkit If-statement in body causes warning message #1 SMP Tue May 26 11:42:35 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Dockerfile
FROM ubuntu:18.04

ARG ssh_prv_key
ARG ssh_pub_key
ARG ssh_config

SHELL ["/bin/bash", "-c"]

ENV TZ=Asia \
    LANG=en_US.UTF-8 \
    PHOENIX_VERSION=1.4.13 \
    ERLANG_VERSION=23.1.1 \
    ELIXIR_VERISON=1.11.0-otp-23 \
    PATH="${PATH}:/root/.asdf/shims:/root/.asdf/bin"

# install common
RUN apt-get update && apt-get upgrade -y \
 && apt-get install -y vim \
 && apt-get install -y git \
 && apt-get install -y wget \
 && apt-get install -y curl \
 && apt-get install -y gcc \
 && apt-get install -y build-essential \
 && apt-get install -y libssl-dev \
 && apt-get install -y automake \
 && apt-get install -y autoconf \
 && apt-get install -y libncurses5-dev \
 && apt-get install -y locales

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \
 && locale-gen en_US.UTF-8 \
 && echo $'LANG=en_US.UTF-8 \n\
           LANGUAGE= \n\
           LC_CTYPE="en_US.UTF-8" \n\
           LC_NUMERIC="en_US.UTF-8" \n\
           LC_TIME="en_US.UTF-8" \n\
           LC_COLLATE="en_US.UTF-8" \n\
           LC_MONETARY="en_US.UTF-8" \n\
           LC_MESSAGES="en_US.UTF-8" \n\
           LC_PAPER="en_US.UTF-8" \n\
           LC_NAME="en_US.UTF-8" \n\
           LC_ADDRESS="en_US.UTF-8" \n\
           LC_TELEPHONE="en_US.UTF-8" \n\
           LC_MEASUREMENT="en_US.UTF-8" \n\
           LC_IDENTIFICATION="en_US.UTF-8" \n\
           LC_ALL=' >> /etc/default/locale

# ADD SSH KEYS
RUN apt-get update && apt-get upgrade -y \
 && which ssh-agent || (apt-get install -y openssh-client) \
 && mkdir -p /root/.ssh \
 && echo "$ssh_prv_key" > /root/.ssh/id_rsa \
 && echo "$ssh_pub_key" > /root/.ssh/id_rsa.pub \
 && echo "$ssh_config" > /root/.ssh/config \
 && ssh-keyscan gitlab.com > /root/.ssh/known_hosts \
 && chmod 700 /root/.ssh/id_rsa \
 && chmod 700 /root/.ssh/id_rsa.pub \
 && chmod 600 /root/.ssh/config \
 && chmod 0600 /root/.ssh/known_hosts \
 && echo "Host gitlab.com\n\tStrictHostKeyChecking no\n" > /root/.ssh/config

# install docker-engine
RUN curl -fsSL https://get.docker.com -o get-docker.sh | sh

WORKDIR /opt/build

RUN apt-get install -y unzip

# install erlang/elixir asdf
RUN git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.8.0 \
 && bash $HOME/.asdf/asdf.sh \
 && asdf plugin add erlang \
 && asdf plugin add elixir \
 && asdf install erlang $ERLANG_VERSION \
 && asdf install elixir $ELIXIR_VERISON \
 && asdf global erlang $ERLANG_VERSION \
 && asdf global elixir $ELIXIR_VERISON

# # mix local.hex
# RUN mix local.rebar --force \
#  && mix local.hex --force

# # Install nodejs
# RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
# RUN apt-get install -y nodejs

# # install phoenix
# RUN mix archive.install hex phx_new $PHOENIX_VERSION --force

CMD ["/bin/bash"]

Current behavior

Not compiles with error:

Compile log
warning: Sentry.Event.create_event/1 is undefined (module Sentry.Event is not available or is yet to be defined)
  lib/ms_tender/application.ex:21: MsTender.Application.start/2

warning: Supervisor.Spec.worker/3 is deprecated. Use the new child specifications outlined in the Supervisor module instead
  lib/ms_tender/application.ex:13: MsTender.Application.start/2

warning: MsTender.DatabaseUZ.get_found_by_search_procedures_private/3 is undefined or private. Did you mean one of:

      * get_found_by_search_procedures/1

  lib/rpc_handler_uz.ex:43: RPCHandlerUZ.get_found_by_search_procedures_private/3

** (EXIT from #PID<0.95.0>) an exception was raised:
    ** (Module.Types.Error) found error while checking types for MsTender.Database.tender_own/4

def(tender_own(company_id, offset, limit, filter)) do
  injects? = fn binary -> Kernel.=~(binary, %{__struct__: Regex, opts: "i", re_pattern: {:re_pattern, 0, 0, 0, <<69, 82, 67, 80, 185, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 15, 30, 115, 30, 101, 30, 108, 30, 101, 30, 99, 30, 116, 119, 0, 15, 30, 117, 30, 112, 30, 100, 30, 97, 30, 116, 30, 101, 119, 0, 9, 30, 115, 30, 101, 30, 116, 119, 0, 13, 30, 103, 30, 114, 30, 111, 30, 117, 30, 112, 119, 0, 13, 30, 99, 30, 111, 30, 117, 30, 110, 30, 116, 119, 0, 15, 30, 100, 30, 101, 30, 108, 30, 101, 30, 116, 30, 101, 119, 0, 11, 30, 100, 30, 114, 30, 111, 30, 112, 119, 0, 11, 30, 119, 30, 105, 30, 116, 30, 104, 119, 0, 15, 30, 105, 30, 110, 30, 115, 30, 101, 30, 114, 30, 116, 120, 0, 117, 0>>}, re_version: {"8.44 2020-02-12", :little}, source: "select|update|set|group|count|delete|drop|with|insert"}) end
  statuses = for(status <- case(filter[:status]) do
    x when :erlang.orelse(:erlang."=:="(x, false), :erlang."=:="(x, nil)) ->
      []
    x ->
      x
  end, do: (nil -> case(injects?.(status)) do
    x when :erlang.orelse(:erlang."=:="(x, false), :erlang."=:="(x, nil)) ->
      <<"'", String.Chars.to_string(status)::binary(), "'">>
    _ ->
      nil
  end; acc -> case(injects?.(status)) do
    x when :erlang.orelse(:erlang."=:="(x, false), :erlang."=:="(x, nil)) ->
      <<acc::binary(), ",", "'", String.Chars.to_string(status)::binary(), "'">>
    _ ->
      acc
  end), reduce: nil)
  sql_filter = case(:erlang.==(statuses, nil)) do
    false ->
      <<"AND s.code in (", String.Chars.to_string(statuses)::binary(), ")">>
    true ->
      ""
  end
  sql = <<"\n      SELECT\n        t.title,\n        t.pub_date as publicated,\n        t.start_date as proposals_from,\n        t.end_date,\n        ", String.Chars.to_string(proposals_till())::binary(), " as proposals_till,\n        t.company_id,\n        t.trade_step,\n        t.price_step,\n        t.is_price_step_percent,\n        t.currency,\n        t.lang,\n        t.total_sum,\n        t.is_sell,\n        t.participants_count,\n        s.name as status_name,\n        s.code as status,\n        t.id as id,\n        CASE WHEN t.source='tpro' THEN t.ext_id ELSE null END as tpro_id,\n        t.source as ext_source,\n        t.ext_id as ext_id,\n        t.type_id as type,\n        t.anno,\n        tt.name as type_name\n      FROM tenders t\n      LEFT JOIN tender_status s ON t.status_id = s.id\n      LEFT JOIN tender_type tt ON t.type_id = tt.id\n      WHERE company_id=?\n        AND (t.company_deleted = 0 AND t.deleted_at IS NULL)\n        ", String.Chars.to_string(sql_filter)::binary(), "\n      ORDER BY proposals_till DESC, t.end_date DESC, t.agreement_date DESC, t.close_date DESC, t.start_date DESC\n      LIMIT ?, ?\n    ">>
  bind = [company_id, offset, limit]
  {:ok, rows} = UtilDB.query(sql, bind: bind, into: %{})
  response = Enum.map(rows, fn row ->
    correct_value = correct_value_fn()
    step_decimals = case(row[:is_price_step_percent]) do
      x when :erlang.orelse(:erlang."=:="(x, false), :erlang."=:="(x, nil)) ->
        2
      _ ->
        0
    end
    :maps.put(:price_step, correct_value.(row[:price_step], step_decimals), row)
  end)
  {:ok, response}
end

Please report this bug: https://github.com/elixir-lang/elixir/issues

** (KeyError) key 10 not found in: %{0 => {:var, 0}, 1 => {:var, 1}, 2 => {:var, 2}, 3 => {:var, 3}, 5 => {:var, 4}, 8 => {:var, 6}, 12 => {:var, 5}}
        :erlang.map_get(10, %{0 => {:var, 0}, 1 => {:var, 1}, 2 => {:var, 2}, 3 => {:var, 3}, 5 => {:var, 4}, 8 => {:var, 6}, 12 => {:var, 5}})
        (elixir 1.11.0) lib/module/types/unify.ex:318: Module.Types.Unify.get_var!/2
        (elixir 1.11.0) lib/module/types/expr.ex:112: Module.Types.Expr.of_expr/3
        (elixir 1.11.0) lib/module/types/helpers.ex:106: Module.Types.Helpers.do_map_reduce_ok/3
        (elixir 1.11.0) lib/module/types/expr.ex:83: Module.Types.Expr.of_expr/3
        (elixir 1.11.0) lib/module/types/helpers.ex:106: Module.Types.Helpers.do_map_reduce_ok/3
        (elixir 1.11.0) lib/module/types/expr.ex:374: Module.Types.Expr.of_expr/3
        (elixir 1.11.0) lib/module/types/helpers.ex:106: Module.Types.Helpers.do_map_reduce_ok/3
Source Elixir code
  @doc "тендеры компании с company_id. (или собственные тендеры пользователя)"
  @spec tender_own(integer(), integer(), integer(), Keyword.t)  :: {:ok, any()} | {:error, any()}
  def tender_own(company_id, offset, limit, filter) do
    # избегание sql-инъекций по колхозному, пока не будет ecto
    injects? = fn binary ->
      binary =~ ~r/select|update|set|group|count|delete|drop|with|insert/i
    end
    statuses = for status <- filter[:status] || [], reduce: nil do
      nil -> if injects?.(status), do: nil, else: "'#{status}'"
      acc -> if injects?.(status), do: acc, else: acc <> "," <> "'#{status}'"
    end
    sql_filter = if is_nil(statuses), do: "", else: "AND s.code in (#{statuses})"

    sql = "
      SELECT
        t.title,
        t.pub_date as publicated,
        t.start_date as proposals_from,
        t.end_date,
        #{proposals_till()} as proposals_till,
        t.company_id,
        t.trade_step,
        t.price_step,
        t.is_price_step_percent,
        t.currency,
        t.lang,
        t.total_sum,
        t.is_sell,
        t.participants_count,
        s.name as status_name,
        s.code as status,
        t.id as id,
        CASE WHEN t.source='tpro' THEN t.ext_id ELSE null END as tpro_id,
        t.source as ext_source,
        t.ext_id as ext_id,
        t.type_id as type,
        t.anno,
        tt.name as type_name
      FROM tenders t
      LEFT JOIN tender_status s ON t.status_id = s.id
      LEFT JOIN tender_type tt ON t.type_id = tt.id
      WHERE company_id=?
        AND (t.company_deleted = 0 AND t.deleted_at IS NULL)
        #{sql_filter}
      ORDER BY proposals_till DESC, t.end_date DESC, t.agreement_date DESC, t.close_date DESC, t.start_date DESC
      LIMIT ?, ?
    "

    bind = [company_id, offset, limit]

    {:ok, rows} = UtilDB.query(sql, bind: bind, into: %{})
    response = Enum.map(rows, fn(row) ->
      correct_value = correct_value_fn()
      step_decimals = if row[:is_price_step_percent], do: 0, else: 2
      row
      |> Map.put(:price_step, correct_value.(row[:price_step], step_decimals))
    end)
    {:ok, response}
  end

Expected behavior

Project is compiled without any errors.

Version 1.10.4 and OTP-22 not have this problem.
Erlang/OTP 22 [erts-10.4.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [hipe]
Elixir 1.10.4 (compiled with Erlang/OTP 21)

Short example with same error

defmodule Foo do
  def foo do
    injects? = fn binary ->
      binary =~ ~r/select|update|set|group|count|delete|drop|with|insert/i
    end
    statuses = for status <- ["a"] || [], reduce: nil do
      nil -> if injects?.(status), do: nil, else: "'#{status}'"
      acc -> if injects?.(status), do: acc, else: acc <> "," <> "'#{status}'"
    end
  end
end
Compile log
** (EXIT from #PID<0.95.0>) an exception was raised:
    ** (Module.Types.Error) found error while checking types for Foo.foo/0

def(foo()) do
  injects? = fn binary -> Kernel.=~(binary, %{__struct__: Regex, opts: "i", re_pattern: {:re_pattern, 0, 0, 0, <<69, 82, 67, 80, 185, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, 15, 30, 115, 30, 101, 30, 108, 30, 101, 30, 99, 30, 116, 119, 0, 15, 30, 117, 30, 112, 30, 100, 30, 97, 30, 116, 30, 101, 119, 0, 9, 30, 115, 30, 101, 30, 116, 119, 0, 13, 30, 103, 30, 114, 30, 111, 30, 117, 30, 112, 119, 0, 13, 30, 99, 30, 111, 30, 117, 30, 110, 30, 116, 119, 0, 15, 30, 100, 30, 101, 30, 108, 30, 101, 30, 116, 30, 101, 119, 0, 11, 30, 100, 30, 114, 30, 111, 30, 112, 119, 0, 11, 30, 119, 30, 105, 30, 116, 30, 104, 119, 0, 15, 30, 105, 30, 110, 30, 115, 30, 101, 30, 114, 30, 116, 120, 0, 117, 0>>}, re_version: {"8.44 2020-02-12", :little}, source: "select|update|set|group|count|delete|drop|with|insert"}) end
  statuses = for(status <- case(["a"]) do
    x when :erlang.orelse(:erlang."=:="(x, false), :erlang."=:="(x, nil)) ->
      []
    x ->
      x
  end, do: (nil -> case(injects?.(status)) do
    x when :erlang.orelse(:erlang."=:="(x, false), :erlang."=:="(x, nil)) ->
      <<"'", String.Chars.to_string(status)::binary(), "'">>
    _ ->
      nil
  end; acc -> case(injects?.(status)) do
    x when :erlang.orelse(:erlang."=:="(x, false), :erlang."=:="(x, nil)) ->
      <<acc::binary(), ",", "'", String.Chars.to_string(status)::binary(), "'">>
    _ ->
      acc
  end), reduce: nil)
end
@demoj1 demoj1 changed the title Compile error: (KeyError) key 10 not found in Compile error: (KeyError) key 10 not found. OTP-23, Elixir 1.11.0 Oct 16, 2020
@josevalim
Copy link
Member

Thanks for the report. It has been fixed in master earlier this week. I will cut a new 1.11.1 release today. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants