From 99de72c1f7745d97814776ac64ad22ed55828a13 Mon Sep 17 00:00:00 2001 From: Reed Semmel Date: Sun, 1 Feb 2026 20:56:15 -0600 Subject: [PATCH] Fix Client PID encoding in Login7 structure (#180) The `dword()` encoding type was configured to use big endian instead of little endian. It is only used for the PID and a zero value in this module. Additionally, this replaces the Tds.Protocol.Login7.pid! implementation with one that uses System.pid() instead of the internal erlang runtime pid, for better parity with other SQL Server clients. Also adds a test case for this. --- lib/tds/binary_utils.ex | 2 +- lib/tds/protocol/login7.ex | 20 +++++++++----------- test/host_id_test.exs | 13 +++++++++++++ 3 files changed, 23 insertions(+), 12 deletions(-) create mode 100644 test/host_id_test.exs diff --git a/lib/tds/binary_utils.ex b/lib/tds/binary_utils.ex index f751eb1..1d8c9b0 100644 --- a/lib/tds/binary_utils.ex +++ b/lib/tds/binary_utils.ex @@ -50,7 +50,7 @@ defmodule Tds.BinaryUtils do @doc """ An unsigned 4-byte (32-bit) value. The range when used as a numeric value is 0 to (2^32)- 1. """ - defmacro dword, do: quote(do: unsigned - 32) + defmacro dword, do: quote(do: little - unsigned - 32) @doc """ An unsigned single byte (8-bit) value representing a character. The range is 0 to 255. diff --git a/lib/tds/protocol/login7.ex b/lib/tds/protocol/login7.ex index ac16f57..c5dd5f5 100644 --- a/lib/tds/protocol/login7.ex +++ b/lib/tds/protocol/login7.ex @@ -197,16 +197,14 @@ defmodule Tds.Protocol.Login7 do # Return the current pid # If that fails return a "default" pid defp pid! do - value = - self() - |> :erlang.pid_to_list() - |> to_string() - |> String.split(".") - |> Enum.at(1) - |> String.to_integer() - - <> - rescue - _ -> @client_pid + System.pid() + |> Integer.parse() + |> case do + {pid, ""} -> + <> + + _ -> + @client_pid + end end end diff --git a/test/host_id_test.exs b/test/host_id_test.exs new file mode 100644 index 0000000..ea132e5 --- /dev/null +++ b/test/host_id_test.exs @@ -0,0 +1,13 @@ +defmodule HostIdTest do + use ExUnit.Case, async: true + + import Tds.TestHelper, only: [opts: 0] + + test "Check that SELECT HOST_ID() matches System.pid()" do + {:ok, conn} = Tds.start_link(opts()) + {:ok, %Tds.Result{rows: [[host_id]]}} = Tds.query(conn, "SELECT HOST_ID()", []) + + pid = System.pid() + assert pid === String.trim(host_id) + end +end