diff --git a/CHANGELOG.md b/CHANGELOG.md index 44eefc1b..1d4f2b4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [Unreleased] +## [0.8.6] - 2026-01-07 ### Added @@ -122,6 +122,75 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - **Implementation**: Query detection in `utils.rs:should_use_query()`, SQL generation in `connection.ex:explain_query/4` - **Test coverage**: 12 tests across `explain_simple_test.exs` and `explain_query_test.exs` +- **STRICT Table Option Support** + - Added support for SQLite's STRICT table option for stronger type enforcement + - Usage: Pass `options: [strict: true]` to `create table()` in migrations + - Example: + ```elixir + create table(:users, options: [strict: true]) do + add :name, :string + add :age, :integer + end + ``` + - STRICT tables enforce column type constraints at INSERT/UPDATE time + - Helps catch type errors early and ensures data integrity + - Can be combined with other table options + +- **Enhanced JSON and JSONB Functions** + - Added comprehensive JSON manipulation functions for working with JSON data + - SQL injection protection with proper parameter handling + - Functions include `json_extract/2`, `json_type/2`, `json_valid/1`, and more + - Consolidated JSON result handling for consistent behaviour + - Extensive test coverage for all JSON operations + +- **Cross-Connection Security Tests** + - Added comprehensive tests for transaction isolation across connections + - Validates that transactions from one connection cannot be accessed by another + - Tests cover savepoints, prepared statements, and cursors + - Ensures strict connection ownership and prevents security vulnerabilities + +- **Generated/Computed Columns Documentation** + - Added documentation for SQLite's generated column support + - Covers both VIRTUAL and STORED generated columns + - Examples of computed columns in migrations + +### Security + +- **CVE-2025-47736 Protection** + - Comprehensive parameter validation to prevent atom table exhaustion + - Improved parameter extraction to avoid malicious input exploitation + - Validates all named parameters against statement introspection + - Proper error handling for invalid or malicious parameter names + - See [security documentation](SECURITY.md) for details + +### Fixed + +- **Statement Caching Improvements** + - Replaced unbounded `persistent_term` cache with bounded ETS LRU cache + - Prevents memory leaks from unlimited prepared statement caching + - Configurable cache size with automatic eviction of least-recently-used entries + - Improved cache performance and memory footprint + +- **Error Handling Improvements** + - Propagate parameter introspection errors instead of silently falling back + - Return descriptive errors for invalid argument types in parameter normalisation + - Improved error tuple handling in fuzz tests + - Better error messages throughout the codebase + +- **Code Quality Improvements** + - Fixed Credo warnings (nesting, unused variables, assertions) + - Standardised unused variable naming for consistency + - Improved test reliability and reduced flakiness + - Better state threading in security tests + - Fixed binary blob round-trip handling in tests + +### Changed + +- **Rust UTF-8 Validation Cleanup** + - Removed redundant UTF-8 validation comments and tautological boundary checks + - Removed redundant `validate_utf8_sql` function (SQLite already validates UTF-8) + - Cleaner, more maintainable codebase + ## [0.8.3] - 2025-12-29 ### Added diff --git a/Cargo.lock b/Cargo.lock index d3103644..43f50c9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,7 +22,7 @@ dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy 0.8.31", + "zerocopy 0.8.32", ] [[package]] @@ -786,9 +786,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "js-sys" @@ -814,9 +814,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.178" +version = "0.2.179" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" [[package]] name = "libloading" @@ -1179,7 +1179,7 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.8.31", + "zerocopy 0.8.32", ] [[package]] @@ -1194,9 +1194,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" dependencies = [ "unicode-ident", ] @@ -1251,9 +1251,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.42" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" dependencies = [ "proc-macro2", ] @@ -1591,9 +1591,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.147" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af14725505314343e673e9ecb7cd7e8a36aa9791eb936235a3567cc31447ae4" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", @@ -1664,9 +1664,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.111" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -1714,9 +1714,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.48.0" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ "bytes", "libc", @@ -1763,9 +1763,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", @@ -1774,9 +1774,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.17" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", @@ -2057,14 +2057,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.4", + "webpki-roots 1.0.5", ] [[package]] name = "webpki-roots" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" +checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" dependencies = [ "rustls-pki-types", ] @@ -2323,11 +2323,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.31" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +checksum = "1fabae64378cb18147bb18bca364e63bdbe72a0ffe4adf0addfec8aa166b2c56" dependencies = [ - "zerocopy-derive 0.8.31", + "zerocopy-derive 0.8.32", ] [[package]] @@ -2343,9 +2343,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.31" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +checksum = "c9c2d862265a8bb4471d87e033e730f536e2a285cc7cb05dbce09a2a97075f90" dependencies = [ "proc-macro2", "quote", @@ -2360,6 +2360,6 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zmij" -version = "0.1.10" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4af59da1029247450b54ba43e0b62c8e376582464bbe5504dd525fe521e7e8fd" +checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8" diff --git a/mix.exs b/mix.exs index 614464ac..7b10e3b3 100644 --- a/mix.exs +++ b/mix.exs @@ -1,7 +1,7 @@ defmodule EctoLibSql.MixProject do use Mix.Project - @version "0.8.3" + @version "0.8.6" @source_url "https://github.com/ocean/ecto_libsql" def project do diff --git a/native/ecto_libsql/Cargo.toml b/native/ecto_libsql/Cargo.toml index 7ff6e754..19b8717a 100644 --- a/native/ecto_libsql/Cargo.toml +++ b/native/ecto_libsql/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ecto_libsql" -version = "0.8.3" +version = "0.8.6" authors = [] edition = "2021" description = "Rust NIF (Native Implemented Function) for EctoLibSql - High-performance Ecto adapter for LibSQL/Turso databases"