From eb03b043f0b6335ff33154c640dd423372a822a6 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 29 May 2026 20:13:54 +0300 Subject: [PATCH] libsql-ffi: Update vendored SQLite3MultipleCiphers to 1.9.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This updates the vendored SQLite3 Multiple Ciphers encryption extension from 1.8.1 to 1.9.0, the release that targets upstream SQLite 3.47.0 (the base version we now ship). The previous 1.8.1 vendoring lagged the SQLite base and was missing several upstream fixes, including a crash in sqlite3mcSetCodec(). The import replaces all upstream files with their v1.9.0 contents and re-applies libSQL's local patches via 3-way merge (base v1.8.1, ours libSQL, theirs v1.9.0). All merges were clean (no conflicts), and `cargo build -p libsql-ffi --features multiple-ciphers` builds. == Preserved as-is (not upstream sqlite3mc) == src/sqlite3.c, src/sqlite3.h — libSQL's own SQLite amalgamation, not sqlite3mc's vanilla copy. build.rs overwrites src/sqlite3.c with libsql-sqlite3's amalgamation at build time regardless, so these are left untouched. == Re-applied libSQL patches (3-way merged onto 1.9.0) == CMakeLists.txt — libSQL build options (LIBSQL_ENCRYPTION, LIBSQL_CUSTOM_PAGER_CODEC, LIBSQL_EXTRA_PRAGMAS, LIBSQL_ENABLE_WASM_RUNTIME), AES256-only cipher selection, and the arm/aarch64 guards around -msse4.2/-maes. src/sqlite3mc.c — `#include "sqlite3.c"` instead of "sqlite3patched.c" so the amalgamation pulls in libSQL's SQLite. src/codecext.c, src/sqlite3mc_vfs.c — libSQL codec hooks libsql_db_has_codec(), libsql_pager_codec_impl() (replacing sqlite3mcPagerHasCodec()/sqlite3mcPagerCodec()), and the cached hasCodec update in the rekey success path. src/cipher_config.c — libsql_extra_pragma(). src/cipher_wxaes256.c — libsql_generate_aes256_key(). src/codec_algos.c — libsql_generate_initial_vector(). == Notable upstream fixes now picked up == src/sqlite3mc_vfs.c — sqlite3mcSetCodec() now passes the VFS located by mcFindVfs() (pVfsMC) to mcFindDbMainFileName() instead of blindly casting db->pVfs. When the Multiple Ciphers VFS is not the top-level VFS (another VFS stacked on top), db->pVfs is not an sqlite3mc_vfs and the cast made mcFindDbMainFileName() dereference a bogus ->mutex and crash. This matches the fix already present in sqlite3mcGetCodec(). src/sqlite3mc_vfs.c — the mcRead* helpers now propagate codec errors via sqlite3mcGetCodecLastError() instead of silently resetting rc to SQLITE_OK after decryption. --- .../SQLite3MultipleCiphers/.editorconfig | 16 + .../SQLite3MultipleCiphers/CHANGELOG.md | 74 +- .../SQLite3MultipleCiphers/CMakeLists.txt | 9 +- .../bundled/SQLite3MultipleCiphers/LICENSE | 2 +- .../SQLite3MultipleCiphers/Makefile.am | 4 +- .../SQLite3MultipleCiphers/configure.ac | 4 +- .../SQLite3MultipleCiphers/premake5.lua | 16 +- .../bundled/SQLite3MultipleCiphers/readme.md | 8 +- .../scripts/patchshell.sh | 7 +- .../scripts/patchsqlite3.sh | 5 +- .../SQLite3MultipleCiphers/src/aes_hardware.c | 12 +- .../SQLite3MultipleCiphers/src/ascon/aead.c | 4 +- .../src/ascon/crypto_aead.h | 6 + .../src/ascon/crypto_hash.h | 5 + .../src/ascon/crypto_pbkdf2.h | 5 + .../SQLite3MultipleCiphers/src/ascon/hash.c | 1 + .../SQLite3MultipleCiphers/src/ascon/pbkdf2.c | 13 +- .../SQLite3MultipleCiphers/src/ascon/prolog.h | 2 +- .../SQLite3MultipleCiphers/src/ascon/word.h | 14 +- .../SQLite3MultipleCiphers/src/carray.c | 14 +- .../src/chacha20poly1305.c | 6 +- .../SQLite3MultipleCiphers/src/cipher_ascon.c | 11 +- .../src/cipher_chacha20.c | 14 +- .../src/cipher_common.c | 59 +- .../src/cipher_common.h | 4 + .../src/cipher_config.c | 24 +- .../src/cipher_config.h | 2 +- .../src/cipher_sds_rc4.c | 4 +- .../src/cipher_sqlcipher.c | 68 +- .../src/cipher_wxaes128.c | 4 +- .../src/cipher_wxaes256.c | 4 +- .../SQLite3MultipleCiphers/src/codec_algos.c | 4 +- .../SQLite3MultipleCiphers/src/codecext.c | 76 +- .../SQLite3MultipleCiphers/src/compress.c | 6 +- .../bundled/SQLite3MultipleCiphers/src/csv.c | 20 +- .../src/extensionfunctions.c | 96 +- .../SQLite3MultipleCiphers/src/fastpbkdf2.c | 4 + .../SQLite3MultipleCiphers/src/fastpbkdf2.h | 8 + .../SQLite3MultipleCiphers/src/fileio.c | 43 +- .../bundled/SQLite3MultipleCiphers/src/md5.c | 32 +- .../src/memory_secure.c | 37 - .../SQLite3MultipleCiphers/src/miniz.c | 160 +- .../SQLite3MultipleCiphers/src/miniz.h | 24 +- .../SQLite3MultipleCiphers/src/mystdint.h | 2 +- .../SQLite3MultipleCiphers/src/regexp.c | 12 +- .../SQLite3MultipleCiphers/src/rekeyvacuum.c | 25 +- .../SQLite3MultipleCiphers/src/rijndael.c | 132 +- .../SQLite3MultipleCiphers/src/rijndael.h | 44 +- .../SQLite3MultipleCiphers/src/series.c | 264 +- .../bundled/SQLite3MultipleCiphers/src/sha1.c | 8 +- .../bundled/SQLite3MultipleCiphers/src/sha1.h | 12 +- .../bundled/SQLite3MultipleCiphers/src/sha2.c | 31 +- .../bundled/SQLite3MultipleCiphers/src/sha2.h | 56 +- .../SQLite3MultipleCiphers/src/shathree.c | 231 +- .../SQLite3MultipleCiphers/src/shell.c | 8781 ++++-- .../SQLite3MultipleCiphers/src/sqlar.c | 13 +- .../SQLite3MultipleCiphers/src/sqlite3mc.c | 65 +- .../SQLite3MultipleCiphers/src/sqlite3mc.def | 4 - .../SQLite3MultipleCiphers/src/sqlite3mc.h | 8 +- .../SQLite3MultipleCiphers/src/sqlite3mc.rc | 2 +- .../src/sqlite3mc_config.h | 16 +- .../src/sqlite3mc_shell.rc | 2 +- .../src/sqlite3mc_version.h | 8 +- .../src/sqlite3mc_vfs.c | 89 +- .../src/sqlite3mc_vfs.h | 1 + .../src/sqlite3patched.c | 23914 ++++++++++------ .../src/sqlite3userauth.h | 2 +- .../SQLite3MultipleCiphers/src/tclsqlite.c | 179 +- .../SQLite3MultipleCiphers/src/userauth.c | 6 +- .../bundled/SQLite3MultipleCiphers/src/uuid.c | 2 +- .../SQLite3MultipleCiphers/src/zipfile.c | 86 +- 71 files changed, 23578 insertions(+), 11348 deletions(-) create mode 100644 libsql-ffi/bundled/SQLite3MultipleCiphers/.editorconfig diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/.editorconfig b/libsql-ffi/bundled/SQLite3MultipleCiphers/.editorconfig new file mode 100644 index 0000000000..b259d5da6a --- /dev/null +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/.editorconfig @@ -0,0 +1,16 @@ +# This is the EditorConfig (http://editorconfig.org/) coding style file for +# SQLite3 Multiple Ciphers. + +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true + +[makefile.*] +indent_style = tab +indent_size = 8 diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/CHANGELOG.md b/libsql-ffi/bundled/SQLite3MultipleCiphers/CHANGELOG.md index 748450afae..a304d0ba85 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/CHANGELOG.md +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/CHANGELOG.md @@ -7,6 +7,70 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.9.0] - 2024-10-22 + +### Changed + +- Based on SQLite version 3.47.0 +- Changed signature of cipher scheme method `GenerateKey` (affects only developers of dynamic cipher schemes) + +### Fixed + +- Using differing KDF and HMAC algorithms resulted in databases incompatible with the original SQLCipher library. Setting the parameter `hmac_algorithm_compat` to 0 restores the (incompatible) behaviour. + +## [1.8.7] - 2024-08-14 + +### Changed + +- Based on SQLite version 3.46.1 + +## [1.8.6] - 2024-06-14 + +### Changed + +- Removed extern keyword in function declarations +- Cleaned up white space +- Added SQLITE_PRIVATE for several internal functions +- The cipher configuration parameter `legacy_page_size` now accepts only valid page sizes +- The cipher configuration parameter `plaintext_header_size` now accepts only values that are multiples of 16 + +### Fixed + +- Fixed issue [#156](../../issues/156)) - corrupted database if MMAP_SIZE > 0 was used +- Fixed issue [#158](../../issues/158)) - add check to verify compatibility of source and target database in backup operation +- Fixed issue [#160](../../issues/160)) - fix accessing memory out of array bounds +- Fixed issue [#162](../../issues/162)) - fix loading/storing misaligned data +- Fixed issue [#164](../../issues/164)) - fix return of error messages from rekey +- Fixed issue [#165](../../issues/165)) - fix rekey function by enforcing page size and number of reserved bytes per page +- Fixed issue [#166](../../issues/166)) - missing attribute SQLITE_PRIVATE for several internal functions +- Fixed issue [#167](../../issues/167)) - improve VFS error reporting +- Fixed issue [#168](../../issues/168)) - add check for encryption support + +## [1.8.5] - 2024-05-24 + +### Changed + +- Based on SQLite version 3.46.0 + +## [1.8.4] - 2024-03-14 + +### Changed + +- Based on SQLite version 3.45.2 +- Disable user authentication extension by default + +## [1.8.3] - 2024-01-31 + +### Changed + +- Based on SQLite version 3.45.1 + +## [1.8.2] - 2024-01-16 + +### Changed + +- Based on SQLite version 3.45.0 + ## [1.8.1] - 2023-12-02 ### Changed @@ -469,7 +533,15 @@ The following ciphers are supported: - AES 256 Bit CBC - SHA1/SHA256/SHA512 HMAC ([SQLCipher](https://www.zetetic.net/sqlcipher/), database versions 1, 2, 3, and 4) - RC4 - No HMAC ([System.Data.SQLite](http://system.data.sqlite.org)) -[Unreleased]: ../../compare/v1.8.0...HEAD +[Unreleased]: ../../compare/v1.9.0...HEAD +[1.9.0]: ../../compare/v1.8.7...v1.9.0 +[1.8.7]: ../../compare/v1.8.6...v1.8.7 +[1.8.6]: ../../compare/v1.8.5...v1.8.6 +[1.8.5]: ../../compare/v1.8.4...v1.8.5 +[1.8.4]: ../../compare/v1.8.3...v1.8.4 +[1.8.3]: ../../compare/v1.8.2...v1.8.3 +[1.8.2]: ../../compare/v1.8.1...v1.8.2 +[1.8.1]: ../../compare/v1.8.0...v1.8.1 [1.8.0]: ../../compare/v1.7.4...v1.8.0 [1.7.4]: ../../compare/v1.7.3...v1.7.4 [1.7.3]: ../../compare/v1.7.2...v1.7.3 diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/CMakeLists.txt b/libsql-ffi/bundled/SQLite3MultipleCiphers/CMakeLists.txt index e178589249..40fd03a36b 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/CMakeLists.txt +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/CMakeLists.txt @@ -32,7 +32,7 @@ OPTION(SQLITE_ENABLE_JSON1 "Enable extension 'json1'" ON) OPTION(SQLITE_ENABLE_RTREE "Enable extension 'rtree'" ON) OPTION(SQLITE_ENABLE_UUID "Enable extension 'uuid'" ON) OPTION(SQLITE_USE_URI "Enable the URI filename process logic" ON) -OPTION(SQLITE_USER_AUTHENTICATION "Enable extension 'user authentication'" ON) +OPTION(SQLITE_USER_AUTHENTICATION "Enable extension 'user authentication'" OFF) OPTION(SQLITE_ENABLE_PREUPDATE_HOOK "Enable preupdate hooks" OFF) OPTION(SQLITE_ENABLE_SESSION "Enable session extension" OFF) OPTION(SQLITE_SHELL_IS_UTF8 "Shell command line arguments in UTF-8 encoding" ON) @@ -64,7 +64,6 @@ OPTION(SQLITE3MC_USE_SQLCIPHER_LEGACY "Use sqlcipher legacy mode as default" OFF # Additional memory security (filling freed memory allocations with zeros or random data) OPTION(SQLITE3MC_SECURE_MEMORY "Enable pragma to secure freed memory" OFF) -OPTION(SQLITE3MC_USE_RANDOM_FILL_MEMORY "Fill freed memory with random data" OFF) # Omit AES hardware support OPTION(SQLITE3MC_OMIT_AES_HARDWARE_SUPPORT "Omit AES hardware support" OFF) @@ -182,12 +181,6 @@ if(SQLITE3MC_SECURE_MEMORY) SQLITE3MC_SECURE_MEMORY=1 ) endif() -if(SQLITE3MC_USE_RANDOM_FILL_MEMORY) - set(SQLITE3MC_BASE_DEFINITIONS - ${SQLITE3MC_BASE_DEFINITIONS} - SQLITE3MC_USE_RANDOM_FILL_MEMORY=1 - ) -endif() if(SQLITE3MC_USE_MINIZ OR _SQLITE3MC_REQUIRE_ZLIB) if(_SQLITE3MC_REQUIRE_ZLIB) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/LICENSE b/libsql-ffi/bundled/SQLite3MultipleCiphers/LICENSE index 3317557506..074d3c71ac 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/LICENSE +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019-2020 Ulrich Telle +Copyright (c) 2019-2024 Ulrich Telle Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/Makefile.am b/libsql-ffi/bundled/SQLite3MultipleCiphers/Makefile.am index 900cac9cd6..ff4fd8251d 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/Makefile.am +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/Makefile.am @@ -24,7 +24,7 @@ ACLOCAL_AMFLAGS = -I admin/m4 AM_CXXFLAGS = -I$(top_srcdir)/src AM_CFLAGS = -I$(top_srcdir)/src -AM_CFLAGS += -std=c99 -DSQLITE_THREADSAFE=1 -DSQLITE_DQS=0 -DSQLITE_MAX_ATTACHED=10 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_SECURE_DELETE=1 -DSQLITE_ENABLE_DESERIALIZE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_CORE=1 -DSQLITE_ENABLE_EXTFUNC=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1 -DSQLITE_ENABLE_CSV=1 -DSQLITE_ENABLE_SHA3=1 -DSQLITE_ENABLE_CARRAY=1 -DSQLITE_ENABLE_FILEIO=1 -DSQLITE_ENABLE_SERIES=1 -DSQLITE_ENABLE_UUID=1 -DSQLITE_ENABLE_REGEXP=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_USE_URI=1 -DSQLITE_USER_AUTHENTICATION=1 $(X86_FLAGS) $(ARM_FLAGS) +AM_CFLAGS += -std=c99 -DSQLITE_THREADSAFE=1 -DSQLITE_DQS=0 -DSQLITE_MAX_ATTACHED=10 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_SECURE_DELETE=1 -DSQLITE_ENABLE_DESERIALIZE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_CORE=1 -DSQLITE_ENABLE_EXTFUNC=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1 -DSQLITE_ENABLE_CSV=1 -DSQLITE_ENABLE_SHA3=1 -DSQLITE_ENABLE_CARRAY=1 -DSQLITE_ENABLE_FILEIO=1 -DSQLITE_ENABLE_SERIES=1 -DSQLITE_ENABLE_UUID=1 -DSQLITE_ENABLE_REGEXP=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_USE_URI=1 -DSQLITE_USER_AUTHENTICATION=0 $(X86_FLAGS) $(ARM_FLAGS) if HOST_WINDOWS AM_CFLAGS += -DSQLITE_API=__declspec\(dllexport\) @@ -138,7 +138,7 @@ sqlite3shell_SOURCES = \ src/sqlite3mc.c \ src/shell.c -sqlite3shell_CFLAGS = -I$(top_srcdir)/src -std=c99 -D_GNU_SOURCE -DSQLITE_THREADSAFE=1 -DSQLITE_DQS=0 -DSQLITE_MAX_ATTACHED=10 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_SECURE_DELETE=1 -DSQLITE_ENABLE_DESERIALIZE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_CORE=1 -DSQLITE_ENABLE_EXTFUNC=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1 -DSQLITE_ENABLE_CSV=1 -DSQLITE_ENABLE_CARRAY=1 -DSQLITE_ENABLE_UUID=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_USE_URI=1 -DSQLITE_USER_AUTHENTICATION=1 -DSQLITE_ENABLE_DBPAGE_VTAB=1 -DSQLITE_ENABLE_DBSTAT_VTAB=1 -DSQLITE_ENABLE_STMTVTAB=1 -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1 $(X86_FLAGS) $(ARM_FLAGS) +sqlite3shell_CFLAGS = -I$(top_srcdir)/src -std=c99 -D_GNU_SOURCE -DSQLITE_THREADSAFE=1 -DSQLITE_DQS=0 -DSQLITE_MAX_ATTACHED=10 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_SECURE_DELETE=1 -DSQLITE_ENABLE_DESERIALIZE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_JSON1=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_GEOPOLY=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 -DSQLITE_ENABLE_SESSION=1 -DSQLITE_CORE=1 -DSQLITE_ENABLE_EXTFUNC=1 -DSQLITE_ENABLE_MATH_FUNCTIONS=1 -DSQLITE_ENABLE_CSV=1 -DSQLITE_ENABLE_CARRAY=1 -DSQLITE_ENABLE_UUID=1 -DSQLITE_TEMP_STORE=2 -DSQLITE_USE_URI=1 -DSQLITE_USER_AUTHENTICATION=0 -DSQLITE_ENABLE_DBPAGE_VTAB=1 -DSQLITE_ENABLE_DBSTAT_VTAB=1 -DSQLITE_ENABLE_STMTVTAB=1 -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1 $(X86_FLAGS) $(ARM_FLAGS) if HOST_WINDOWS sqlite3shell_LDADD = diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/configure.ac b/libsql-ffi/bundled/SQLite3MultipleCiphers/configure.ac index 355f6b5786..573979655c 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/configure.ac +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/configure.ac @@ -1,10 +1,10 @@ dnl Process this script with autoconf to create configure for sqlite3mc library dnl -dnl Copyright (C) 2019-2023 Ulrich Telle +dnl Copyright (C) 2019-2024 Ulrich Telle dnl dnl This file is covered by the same licence as the entire SQLite3 Multiple Ciphers package. -AC_INIT([sqlite3mc], [1.8.1], [ulrich@telle-online.de]) +AC_INIT([sqlite3mc], [1.9.0], [ulrich@telle-online.de]) dnl This is the version tested with, might work with earlier ones. AC_PREREQ([2.69]) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/premake5.lua b/libsql-ffi/bundled/SQLite3MultipleCiphers/premake5.lua index b304564412..2c27a68f20 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/premake5.lua +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/premake5.lua @@ -92,10 +92,9 @@ project "sqlite3mc_lib" -- "SQLITE_ENABLE_SQLAR=1" -- "SQLITE_ENABLE_ZIPFILE=1" "SQLITE3MC_SECURE_MEMORY=$(SQLITE3MC_SECURE_MEMORY)", --- "SQLITE3MC_USE_RANDOM_FILL_MEMORY=$(SQLITE3MC_USE_RANDOM_FILL_MEMORY)", "SQLITE_TEMP_STORE=2", "SQLITE_USE_URI=1", - "SQLITE_USER_AUTHENTICATION=1", + "SQLITE_USER_AUTHENTICATION=0", -- Compatibility with official SQLite3 shell "SQLITE_ENABLE_DBPAGE_VTAB=1", "SQLITE_ENABLE_DBSTAT_VTAB=1", @@ -190,10 +189,9 @@ project "sqlite3mc_dll" -- "SQLITE_ENABLE_SQLAR=1" -- "SQLITE_ENABLE_ZIPFILE=1" "SQLITE3MC_SECURE_MEMORY=$(SQLITE3MC_SECURE_MEMORY)", --- "SQLITE3MC_USE_RANDOM_FILL_MEMORY=$(SQLITE3MC_USE_RANDOM_FILL_MEMORY)", "SQLITE_TEMP_STORE=2", "SQLITE_USE_URI=1", - "SQLITE_USER_AUTHENTICATION=1" + "SQLITE_USER_AUTHENTICATION=0" } -- Intermediate directory @@ -251,7 +249,7 @@ project "sqlite3mc_shell" "SQLITE_SHELL_IS_UTF8=1", "SQLITE_ENABLE_SESSION=1", "SQLITE_ENABLE_DBPAGE_VTAB=1", - "SQLITE_USER_AUTHENTICATION=1" + "SQLITE_USER_AUTHENTICATION=0" } -- Intermediate directory @@ -342,10 +340,9 @@ project "sqlite3mc_libicu" -- "SQLITE_ENABLE_SQLAR=1" -- "SQLITE_ENABLE_ZIPFILE=1" "SQLITE3MC_SECURE_MEMORY=$(SQLITE3MC_SECURE_MEMORY)", --- "SQLITE3MC_USE_RANDOM_FILL_MEMORY=$(SQLITE3MC_USE_RANDOM_FILL_MEMORY)", "SQLITE_TEMP_STORE=2", "SQLITE_USE_URI=1", - "SQLITE_USER_AUTHENTICATION=1", + "SQLITE_USER_AUTHENTICATION=0", -- Compatibility with official SQLite3 shell "SQLITE_ENABLE_DBPAGE_VTAB=1", "SQLITE_ENABLE_DBSTAT_VTAB=1", @@ -453,10 +450,9 @@ project "sqlite3mc_dllicu" -- "SQLITE_ENABLE_SQLAR=1" -- "SQLITE_ENABLE_ZIPFILE=1" "SQLITE3MC_SECURE_MEMORY=$(SQLITE3MC_SECURE_MEMORY)", --- "SQLITE3MC_USE_RANDOM_FILL_MEMORY=$(SQLITE3MC_USE_RANDOM_FILL_MEMORY)", "SQLITE_TEMP_STORE=2", "SQLITE_USE_URI=1", - "SQLITE_USER_AUTHENTICATION=1" + "SQLITE_USER_AUTHENTICATION=0" } -- Intermediate directory @@ -526,7 +522,7 @@ project "sqlite3mc_shellicu" "SQLITE_SHELL_IS_UTF8=1", "SQLITE_ENABLE_SESSION=1", "SQLITE_ENABLE_DBPAGE_VTAB=1", - "SQLITE_USER_AUTHENTICATION=1" + "SQLITE_USER_AUTHENTICATION=0" } -- Intermediate directory diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/readme.md b/libsql-ffi/bundled/SQLite3MultipleCiphers/readme.md index 1ab5f9d684..e525ad0cf6 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/readme.md +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/readme.md @@ -10,10 +10,10 @@ The code was mainly developed under Windows, but was tested under Linux as well. ## Version information -* 1.8.1 - *December 2023* - - Based on SQLite version 3.44.2 - - Fixed issue #133 - missing API symbols - - Applied several modifications to improve support for [SQLite3 WASM](https://sqlite.org/wasm/) +* 1.9.0 - *October 2024* + - Based on SQLite version 3.47.0 + - Changed signature of cipher scheme method `GenerateKey` (affects only developers of dynamic cipher schemes) + - Using differing KDF and HMAC algorithms resulted in databases incompatible with the original SQLCipher library. Setting the parameter `hmac_algorithm_compat` to 0 restores the (incompatible) behaviour. For further version information please consult the [CHANGELOG](CHANGELOG.md). diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/scripts/patchshell.sh b/libsql-ffi/bundled/SQLite3MultipleCiphers/scripts/patchshell.sh index 65c1873b93..56151b4886 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/scripts/patchshell.sh +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/scripts/patchshell.sh @@ -14,7 +14,10 @@ die() { exit 2 } -sed -e '/^ oputf("SQLite version/{n;N;d}' "$INPUT" \ +sed -e '/^ sputf(stdout, "SQLite version/{n;N;d}' "$INPUT" \ | sed '/#ifdef SQLITE_CUSTOM_INCLUDE/!{p;d;};n;n;n;a #if SQLITE3MC_USE_MINIZ != 0 && !defined(SQLITE_ENABLE_COMPRESS)\n#include "miniz.c"\n#ifdef SQLITE_HAVE_ZLIB\n#undef SQLITE_HAVE_ZLIB\n#endif\n#define SQLITE_HAVE_ZLIB 1\n#endif\n' \ | sed '/#include /c #include "zlibwrap.h"' \ - | sed '/^ oputf("SQLite version/c \ extern char* sqlite3mc_version();\n oputf("SQLite version \%s \%.19s%s" \/\*extra-version-info\*\/\n " (\%s)\\n" \/\*SQLite3-Multiple-Ciphers-version-info\*\/\n "Enter \\".help\\" for usage hints.\\n\",\n sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET, sqlite3mc_version());' + | sed '/^ sqlite3_fprintf(stdout,$/c \ extern char* sqlite3mc_version();\n sqlite3_fprintf(stdout,' \ + | sed '/^ "SQLite version/c \ "SQLite version \%s \%.19s%s" \/\*extra-version-info\*\/\n " (\%s)\\n" \/\*SQLite3-Multiple-Ciphers-version-info\*\/' \ + | sed '/^ sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);/c \ sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET, sqlite3mc_version());' \ + | sed '/^ sqlite3_libversion(), sqlite3_sourceid());/a \ extern char* sqlite3mc_version();\n sqlite3_fprintf(p->out, "\%s\\n", sqlite3mc_version());' diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/scripts/patchsqlite3.sh b/libsql-ffi/bundled/SQLite3MultipleCiphers/scripts/patchsqlite3.sh index 30625482a6..5a689f596a 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/scripts/patchsqlite3.sh +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/scripts/patchsqlite3.sh @@ -17,7 +17,7 @@ die() { # 1) Intercept VFS pragma handling # 2) Add handling of KEY parameter in ATTACH statements sed 's/sqlite3_file_control\(.*SQLITE_FCNTL_PRAGMA\)/sqlite3mcFileControlPragma\1/' "$INPUT" \ - | sed '/\#endif \/\* SQLITE3\_H \*\//a \ \n\/\* Function prototypes of SQLite3 Multiple Ciphers \*\/\nSQLITE_PRIVATE int sqlite3mcCheckVfs(const char*);\nSQLITE_PRIVATE int sqlite3mcFileControlPragma(sqlite3*, const char*, int, void*);\nSQLITE_PRIVATE int sqlite3mcHandleAttachKey(sqlite3*, const char*, const char*, sqlite3_value*, char**);\nSQLITE_PRIVATE int sqlite3mcHandleMainKey(sqlite3*, const char*);\ntypedef struct PgHdr PgHdrMC;\nSQLITE_PRIVATE void* sqlite3mcPagerCodec(PgHdrMC* pPg);\ntypedef struct Pager PagerMC;\nSQLITE_PRIVATE int sqlite3mcPagerHasCodec(PagerMC* pPager);\nSQLITE_PRIVATE void sqlite3mcInitMemoryMethods();' \ + | sed '/\#endif \/\* SQLITE3\_H \*\//a \ \n\/\* Function prototypes of SQLite3 Multiple Ciphers \*\/\nSQLITE_PRIVATE int sqlite3mcCheckVfs(const char*);\nSQLITE_PRIVATE int sqlite3mcFileControlPragma(sqlite3*, const char*, int, void*);\nSQLITE_PRIVATE int sqlite3mcHandleAttachKey(sqlite3*, const char*, const char*, sqlite3_value*, char**);\nSQLITE_PRIVATE int sqlite3mcHandleMainKey(sqlite3*, const char*);\ntypedef struct PgHdr PgHdrMC;\nSQLITE_PRIVATE void* sqlite3mcPagerCodec(PgHdrMC* pPg);\ntypedef struct Pager PagerMC;\nSQLITE_PRIVATE int sqlite3mcPagerHasCodec(PagerMC* pPager);\nSQLITE_PRIVATE void sqlite3mcInitMemoryMethods();\nSQLITE_PRIVATE int sqlite3mcIsBackupSupported(sqlite3*, const char*, sqlite3*, const char*);' \ | sed '/\#define MAX\_PATHNAME 512/c #if SQLITE3MC\_MAX\_PATHNAME \> 512\n#define MAX_PATHNAME SQLITE3MC\_MAX\_PATHNAME\n#else\n#define MAX_PATHNAME 512\n#endif' \ | sed '/pData = pPage->pData;/c \ if( (pData = sqlite3mcPagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT;' \ | sed '/pData = p->pData;/c \ if( (pData = sqlite3mcPagerCodec(p))==0 ) return SQLITE_NOMEM;' \ @@ -26,4 +26,5 @@ sed 's/sqlite3_file_control\(.*SQLITE_FCNTL_PRAGMA\)/sqlite3mcFileControlPragma\ | sed '/sqlite3_free_filename(zOpen);/i \\n \/\* Handle encryption related URI parameters. \*\/\n if( rc==SQLITE_OK ){\n rc = sqlite3mcHandleMainKey(db, zOpen);\n }' \ | sed '/^ if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0;/a \ if( sqlite3mcPagerHasCodec(pPager) != 0 ) return 0;' \ | sed '/^ }else if( USEFETCH(pPager) ){/c \ }else if( USEFETCH(pPager) && sqlite3mcPagerHasCodec(pPager) == 0 ){' \ - | sed '/^ if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0));/a \\n \/\* Initialize wrapper for memory management.\*\/\n if( rc==SQLITE_OK ) {\n sqlite3mcInitMemoryMethods();\n }\n' + | sed '/^ if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0));/a \\n \/\* Initialize wrapper for memory management.\*\/\n if( rc==SQLITE_OK ) {\n sqlite3mcInitMemoryMethods();\n }\n' \ + | sed '/Lock the source database handle./i \ \/\* Check whether databases are compatible with backup \*\/\n if (!sqlite3mcIsBackupSupported(pSrcDb, zSrcDb, pDestDb, zDestDb)){\n sqlite3ErrorWithMsg(pDestDb, SQLITE_ERROR, \"backup is not supported with incompatible source and target databases\");\n return NULL;\n }\n' diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aes_hardware.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aes_hardware.c index 2787712f00..9a45b9fb90 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aes_hardware.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/aes_hardware.c @@ -198,7 +198,7 @@ aesGenKeyEncrypt(const unsigned char* userKey, const int bits, unsigned char* ke { int numberOfRounds = (bits == 128) ? 10 : (bits == 192) ? 12 : (bits == 256) ? 14 : 0; int rc = (!userKey || !keyData) ? -1 : (numberOfRounds > 0) ? 0 : -2; - + if (rc == 0) { __m128i tempKey[_MAX_ROUNDS + 1]; @@ -347,7 +347,7 @@ aesDecryptCBC(const unsigned char* in, int offset; --numBlocks; offset = numBlocks * 16; - + /* Decrypt the last plain block. */ last_in = _mm_loadu_si128(&((__m128i*) in)[numBlocks]); data = _mm_xor_si128(last_in, key[numberOfRounds - 0]); @@ -477,7 +477,7 @@ aesGenKeyEncryptInternal(const unsigned char* userKey, const int bits, uint8x16_ int i; int j; int numberOfRounds = (bits == 128) ? 10 : (bits == 192) ? 12 : (bits == 256) ? 14 : 0; - int keyWords = bits / 32; + int keyWords = bits / 32; int schedWords = (numberOfRounds + 1) * 4; /* @@ -538,7 +538,7 @@ aesGenKeyEncrypt(const unsigned char* userKey, const int bits, unsigned char* ke { int numberOfRounds = (bits == 128) ? 10 : (bits == 192) ? 12 : (bits == 256) ? 14 : 0; int rc = (!userKey || !keyData) ? -1 : (numberOfRounds > 0) ? 0 : -2; - + if (rc == 0) { uint8x16_t tempKey[_MAX_ROUNDS + 1]; @@ -648,7 +648,7 @@ aesEncryptCBC(const unsigned char* in, } feedback = vaeseq_u8(feedback, key[numberOfRounds-1]); feedback = veorq_u8(feedback, key[numberOfRounds]); \ - + vst1q_u8(&out[(numBlocks-1)*16], feedback); memcpy(&out[numBlocks*16], lastblock, lenFrag); @@ -689,7 +689,7 @@ aesDecryptCBC(const unsigned char* in, int offset; --numBlocks; offset = numBlocks * 16; - + /* Decrypt the last plain block. */ last_in = vld1q_u8(&in[numBlocks*16]); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/aead.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/aead.c index 1d9132e267..b65e63e360 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/aead.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/aead.c @@ -88,7 +88,7 @@ forceinline void ascon_adata(ascon_state_t* s, const uint8_t* ad, ASCON_P(s, nr); } /* domain separation */ - s->x[4] ^= 1; + s->x[4] ^= ASCON_DSEP(); ascon_printstate("domain separation", s); } @@ -197,6 +197,7 @@ forceinline void ascon_final(ascon_state_t* s, const ascon_key_t* key) { ascon_printstate("final 2nd key xor", s); } +SQLITE_PRIVATE int ascon_aead_encrypt(uint8_t* ctext, uint8_t tag[ASCON_AEAD_TAG_LEN], const uint8_t* mtext, uint64_t mlen, @@ -220,6 +221,7 @@ int ascon_aead_encrypt(uint8_t* ctext, return 0; } +SQLITE_PRIVATE int ascon_aead_decrypt(uint8_t* mtext, const uint8_t* ctext, uint64_t clen, const uint8_t* ad, uint64_t adlen, diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_aead.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_aead.h index 0955c7638e..4c205bacb4 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_aead.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_aead.h @@ -13,6 +13,10 @@ #ifndef CRYPTO_AEAD_H #define CRYPTO_AEAD_H +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + #include /* @@ -27,6 +31,7 @@ ** \param nonce Buffer with nonce data ** \param k Buffer with key data */ +SQLITE_PRIVATE int ascon_aead_encrypt(uint8_t* ctext, uint8_t tag[ASCON_AEAD_TAG_LEN], const uint8_t* mtext, uint64_t mlen, const uint8_t* ad, uint64_t adlen, @@ -45,6 +50,7 @@ int ascon_aead_encrypt(uint8_t* ctext, uint8_t tag[ASCON_AEAD_TAG_LEN], ** \param nonce Buffer with nonce data ** \param k Buffer with key data */ +SQLITE_PRIVATE int ascon_aead_decrypt(uint8_t* mtext, const uint8_t* ctext, uint64_t clen, const uint8_t* ad, uint64_t adlen, const uint8_t tag[ASCON_AEAD_TAG_LEN], diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_hash.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_hash.h index af9b04e29d..4f326f1e12 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_hash.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_hash.h @@ -13,6 +13,10 @@ #ifndef CRYPTO_HASH_H #define CRYPTO_HASH_H +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + #include /* @@ -22,6 +26,7 @@ ** \param in Buffer with input data ** \param passwordlen Length of input data in bytes */ +SQLITE_PRIVATE int ascon_hash(uint8_t* out, const uint8_t* in, uint64_t inlen); #endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_pbkdf2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_pbkdf2.h index 95d7f9d743..d9f247b824 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_pbkdf2.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/crypto_pbkdf2.h @@ -17,6 +17,10 @@ #ifndef ASCON_PBKDF2_H #define ASCON_PBKDF2_H +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + #include /* @@ -35,6 +39,7 @@ ** \param saltlen Number of bytes in the salt ** \param count Number of iterations to perform */ +SQLITE_PRIVATE void ascon_pbkdf2(uint8_t* out, uint32_t outlen, const uint8_t* password, uint32_t passwordlen, const uint8_t* salt, uint32_t saltlen, uint32_t count) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/hash.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/hash.c index 46d17623ec..ae400f10e3 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/hash.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/hash.c @@ -89,6 +89,7 @@ forceinline void ascon_squeeze(ascon_state_t* s, uint8_t* out, ascon_printstate("squeeze output", s); } +SQLITE_PRIVATE int ascon_hash(uint8_t* out, const uint8_t* in, uint64_t inlen) { ascon_state_t s; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/pbkdf2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/pbkdf2.c index 8db33c998d..1f84d551cf 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/pbkdf2.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/pbkdf2.c @@ -15,6 +15,7 @@ #define ASCON_HASH_SIZE 32 #define ASCON_PBKDF2_SIZE 32 +SQLITE_PRIVATE void ascon_pbkdf2_init(ascon_state_t* state, const char* functionName, const unsigned char* custom, uint32_t customlen, uint32_t outlen) { @@ -60,10 +61,11 @@ void ascon_pbkdf2_init(ascon_state_t* state, const char* functionName, * Note: Instead of HMAC like in RFC 8018, use the following PRF: * PRF(P, X) = ASCON-cXOF(X, 256, "PBKDF2", P) */ -static void ascon_pbkdf2_f(ascon_state_t* state, - uint8_t* T, /*uint8_t* U,*/ - const uint8_t* salt, uint32_t saltlen, - uint32_t count, uint32_t blocknum) +static +void ascon_pbkdf2_f(ascon_state_t* state, + uint8_t* T, /*uint8_t* U,*/ + const uint8_t* salt, uint32_t saltlen, + uint32_t count, uint32_t blocknum) { uint32_t asconSaltLen = (saltlen < ASCON_SALT_LEN) ? saltlen : ASCON_SALT_LEN; uint8_t temp[ASCON_SALT_LEN+4]; @@ -73,7 +75,7 @@ static void ascon_pbkdf2_f(ascon_state_t* state, memset(temp, 0, ASCON_SALT_LEN); memcpy(temp, salt, asconSaltLen); STORE32_BE(temp+ASCON_SALT_LEN, blocknum); - + /* Copy initial state */ for (j = 0; j < 5; ++j) state2.x[j] = state->x[j]; @@ -109,6 +111,7 @@ static void ascon_pbkdf2_f(ascon_state_t* state, sqlite3mcSecureZeroMemory(&state2, sizeof(ascon_state_t)); } +SQLITE_PRIVATE void ascon_pbkdf2(uint8_t* out, uint32_t outlen, const uint8_t* password, uint32_t passwordlen, const uint8_t* salt, uint32_t saltlen, uint32_t count) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/prolog.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/prolog.h index 4e65e45cdd..5efe9ba0ae 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/prolog.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/prolog.h @@ -1,6 +1,6 @@ /* ** Name: prolog.h -** Purpose: Include important header files, before +** Purpose: Include important header files, before ** Based on: Public domain Ascon reference implementation ** and optimized variants for 32- and 64-bit ** (see https://github.com/ascon/ascon-c) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/word.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/word.h index cfd960a00e..972b55d2f0 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/word.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/ascon/word.h @@ -15,6 +15,8 @@ typedef union { #define ASCON_U64TOWORD(x) ASCON_U64BIG(x) #define ASCON_WORDTOU64(x) ASCON_U64BIG(x) +#define ASCON_LOAD(b, n) ASCON_LOADBYTES(b, n) +#define ASCON_STORE(b, w, n) ASCON_STOREBYTES(b, w, n) forceinline uint64_t ASCON_ROR(uint64_t x, int n) { return x >> n | x << (-n & 63); } @@ -32,6 +34,8 @@ forceinline int ASCON_NOTZERO(uint64_t a, uint64_t b) { forceinline uint64_t ASCON_PAD(int i) { return 0x80ull << (56 - 8 * i); } +forceinline uint64_t ASCON_DSEP() { return 0x01; } + forceinline uint64_t ASCON_PRFS_MLEN(uint64_t len) { return len << 51; } forceinline uint64_t ASCON_CLEAR(uint64_t w, int n) { @@ -45,16 +49,6 @@ forceinline uint64_t ASCON_MASK(int n) { return ~0ull >> (64 - 8 * n); } -forceinline uint64_t ASCON_LOAD(const uint8_t* bytes, int n) { - uint64_t x = *(uint64_t*)bytes & ASCON_MASK(n); - return ASCON_U64TOWORD(x); -} - -forceinline void ASCON_STORE(uint8_t* bytes, uint64_t w, int n) { - *(uint64_t*)bytes &= ~ASCON_MASK(n); - *(uint64_t*)bytes |= ASCON_WORDTOU64(w); -} - forceinline uint64_t ASCON_LOADBYTES(const uint8_t* bytes, int n) { uint64_t x = 0; memcpy(&x, bytes, n); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/carray.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/carray.c index b1caa98c3f..28806d5ea6 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/carray.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/carray.c @@ -46,7 +46,7 @@ ** ctype TEXT HIDDEN ** ); ** -** If the hidden columns "pointer" and "count" are unconstrained, then +** If the hidden columns "pointer" and "count" are unconstrained, then ** the virtual table has no rows. Otherwise, the virtual table interprets ** the integer value of "pointer" as a pointer to the array and "count" ** as the number of elements in the array. The virtual table steps through @@ -64,7 +64,7 @@ SQLITE_EXTENSION_INIT1 #else # include #endif - + /* Allowed values for the mFlags parameter to sqlite3_carray_bind(). ** Must exactly match the definitions in carray.h. */ @@ -271,7 +271,7 @@ static int carrayEof(sqlite3_vtab_cursor *cur){ ** to the first row of output. */ static int carrayFilter( - sqlite3_vtab_cursor *pVtabCursor, + sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ @@ -385,7 +385,7 @@ static int carrayBestIndex( } /* -** This following structure defines all the methods for the +** This following structure defines all the methods for the ** carray virtual table. */ static sqlite3_module carrayModule = { @@ -468,7 +468,7 @@ SQLITE_API int sqlite3_carray_bind( for(i=0; iaData = sqlite3_malloc64( sz ); if( pNew->aData==0 ){ sqlite3_free(pNew); @@ -542,8 +542,8 @@ static void inttoptrFunc( #endif /* SQLITE_OMIT_VIRTUALTABLE */ SQLITE_API int sqlite3_carray_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/chacha20poly1305.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/chacha20poly1305.c index 57a96931b6..13bdad6e6a 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/chacha20poly1305.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/chacha20poly1305.c @@ -74,6 +74,7 @@ static void chacha20_block(uint32_t x[16]) #undef CC20QR } +SQLITE_PRIVATE void chacha20_xor(void* buffer, size_t n, const uint8_t key[32], const uint8_t nonce[12], uint32_t counter) { @@ -141,6 +142,7 @@ void chacha20_xor(void* buffer, size_t n, const uint8_t key[32], /* * Poly1305 authentication tags */ +SQLITE_PRIVATE void poly1305(const uint8_t* msg, size_t n, const uint8_t key[32], uint8_t tag[16]) { @@ -210,6 +212,7 @@ void poly1305(const uint8_t* msg, size_t n, const uint8_t key[32], s4 = d4; STORE32_LE(tag + 12, s4); } +SQLITE_PRIVATE int poly1305_tagcmp(const uint8_t tag1[16], const uint8_t tag2[16]) { uint8_t d = 0; @@ -286,7 +289,7 @@ static size_t entropy(void* buf, size_t n) } #else - + #include #define RtlGenRandom SystemFunction036 BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); @@ -405,6 +408,7 @@ static size_t entropy(void* buf, size_t n) /* * ChaCha20 random number generator */ +SQLITE_PRIVATE void chacha20_rng(void* out, size_t n) { static uint8_t key[32], nonce[12], buffer[64] = { 0 }; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_ascon.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_ascon.c index 89d658a621..c702104f77 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_ascon.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_ascon.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher Ascon ** Author: Ulrich Telle ** Created: 2023-11-13 -** Copyright: (c) 2023-2023 Ulrich Telle +** Copyright: (c) 2023-2024 Ulrich Telle ** License: MIT */ @@ -114,21 +114,18 @@ GetSaltAscon128Cipher(void* cipher) } static void -GenerateKeyAscon128Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeyAscon128Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { Ascon128Cipher* ascon128Cipher = (Ascon128Cipher*) cipher; int bypass = 0; - Pager *pPager = pBt->pPager; - sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL; - int keyOnly = 1; - if (rekey || fd == NULL || sqlite3OsRead(fd, ascon128Cipher->m_salt, SALTLENGTH_ASCON128, 0) != SQLITE_OK) + if (rekey || cipherSalt == NULL) { chacha20_rng(ascon128Cipher->m_salt, SALTLENGTH_ASCON128); keyOnly = 0; } - else if (cipherSalt != NULL) + else { memcpy(ascon128Cipher->m_salt, cipherSalt, SALTLENGTH_ASCON128); } diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_chacha20.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_chacha20.c index f93a867468..67dca9c51e 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_chacha20.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_chacha20.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher ChaCha20 - Poly1305 ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2020 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -140,21 +140,18 @@ GetSaltChaCha20Cipher(void* cipher) } static void -GenerateKeyChaCha20Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeyChaCha20Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { ChaCha20Cipher* chacha20Cipher = (ChaCha20Cipher*) cipher; int bypass = 0; - Pager *pPager = pBt->pPager; - sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL; - int keyOnly = 1; - if (rekey || fd == NULL || sqlite3OsRead(fd, chacha20Cipher->m_salt, SALTLENGTH_CHACHA20, 0) != SQLITE_OK) + if (rekey || cipherSalt == NULL) { chacha20_rng(chacha20Cipher->m_salt, SALTLENGTH_CHACHA20); keyOnly = 0; } - else if (cipherSalt != NULL) + else { memcpy(chacha20Cipher->m_salt, cipherSalt, SALTLENGTH_CHACHA20); } @@ -274,7 +271,8 @@ EncryptPageChaCha20Cipher(void* cipher, int page, unsigned char* data, int len, return rc; } -int chacha20_ismemset(const void* v, unsigned char value, int len) +static int +chacha20_ismemset(const void* v, unsigned char value, int len) { const unsigned char* a = v; int i = 0, result = 0; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.c index 6e4eed953d..2075a7874e 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of SQLite codecs ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2022 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -144,7 +144,7 @@ sqlite3mcGetCipherType(sqlite3* db) { CodecParameter* codecParams = (db != NULL) ? sqlite3mcGetCodecParams(db) : globalCodecParameterTable; CipherParams* cipherParamTable = (codecParams != NULL) ? codecParams[0].m_params : commonParams; - int cipherType = CODEC_TYPE; + int cipherType = CODEC_TYPE_UNKNOWN; CipherParams* cipher = cipherParamTable; for (; cipher->m_name[0] != 0; ++cipher) { @@ -207,6 +207,7 @@ sqlite3mcCodecInit(Codec* codec) memset(codec->m_page, 0, sizeof(codec->m_page)); codec->m_pageSize = 0; codec->m_reserved = 0; + codec->m_lastError = SQLITE_OK; codec->m_hasKeySalt = 0; memset(codec->m_keySalt, 0, sizeof(codec->m_keySalt)); } @@ -245,6 +246,10 @@ sqlite3mcCodecSetup(Codec* codec, int cipherType, char* userPassword, int passwo { int rc = SQLITE_OK; CipherParams* globalParams = sqlite3mcGetCipherParams(codec->m_db, CIPHER_NAME_GLOBAL); + if (cipherType <= CODEC_TYPE_UNKNOWN) + { + return SQLITE_ERROR; + } codec->m_isEncrypted = 1; codec->m_hmacCheck = sqlite3mcGetCipherParameter(globalParams, "hmac_check"); codec->m_walLegacy = sqlite3mcGetCipherParameter(globalParams, "mc_legacy_wal"); @@ -270,6 +275,10 @@ sqlite3mcSetupWriteCipher(Codec* codec, int cipherType, char* userPassword, int { int rc = SQLITE_OK; CipherParams* globalParams = sqlite3mcGetCipherParams(codec->m_db, CIPHER_NAME_GLOBAL); + if (cipherType <= CODEC_TYPE_UNKNOWN) + { + return SQLITE_ERROR; + } if (codec->m_writeCipher != NULL) { globalCodecDescriptorTable[codec->m_writeCipherType-1].m_freeCipher(codec->m_writeCipher); @@ -414,7 +423,7 @@ sqlite3mcGetLegacyWriteCipher(Codec* codec) SQLITE_PRIVATE int sqlite3mcGetPageSizeReadCipher(Codec* codec) { - int pageSize = (codec->m_hasReadCipher && codec->m_readCipher != NULL) ? globalCodecDescriptorTable[codec->m_readCipherType - 1].m_getPageSize(codec->m_readCipher) : 0; + int pageSize = (codec->m_hasReadCipher && codec->m_readCipher != NULL) ? globalCodecDescriptorTable[codec->m_readCipherType - 1].m_getPageSize(codec->m_readCipher) : -1; return pageSize; } @@ -447,6 +456,21 @@ sqlite3mcReservedEqual(Codec* codec) return (readReserved == writeReserved); } +SQLITE_PRIVATE void +sqlite3mcSetCodecLastError(Codec* codec, int error) +{ + if (codec) + { + codec->m_lastError = error; + } +} + +SQLITE_PRIVATE int +sqlite3mcGetCodecLastError(Codec* codec) +{ + return codec ? codec->m_lastError : SQLITE_OK; +} + SQLITE_PRIVATE unsigned char* sqlite3mcGetSaltWriteCipher(Codec* codec) { @@ -500,6 +524,9 @@ sqlite3mcCodecCopy(Codec* codec, Codec* other) codec->m_bt = other->m_bt; #endif codec->m_btShared = other->m_btShared; + + codec->m_lastError = SQLITE_OK; + return rc; } @@ -570,16 +597,30 @@ sqlite3mcPadPassword(char* password, int pswdlen, unsigned char pswd[32]) } } +SQLITE_PRIVATE unsigned char* mcReadDatabaseHeader(Codec* codec, unsigned char* dbHeader) +{ + Pager* pPager = codec->m_btShared->pPager; + sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL; + if (fd == NULL || sqlite3OsRead(fd, dbHeader, KEYSALT_LENGTH, 0) != SQLITE_OK) + return NULL; + else + return dbHeader; +} + SQLITE_PRIVATE void sqlite3mcGenerateReadKey(Codec* codec, char* userPassword, int passwordLength, unsigned char* cipherSalt) { - globalCodecDescriptorTable[codec->m_readCipherType-1].m_generateKey(codec->m_readCipher, codec->m_btShared, userPassword, passwordLength, 0, cipherSalt); + unsigned char dbHeader[KEYSALT_LENGTH]; + unsigned char* pDbHeader = (cipherSalt == NULL) ? mcReadDatabaseHeader(codec, dbHeader) : cipherSalt; + globalCodecDescriptorTable[codec->m_readCipherType-1].m_generateKey(codec->m_readCipher, userPassword, passwordLength, 0, pDbHeader); } SQLITE_PRIVATE void sqlite3mcGenerateWriteKey(Codec* codec, char* userPassword, int passwordLength, unsigned char* cipherSalt) { - globalCodecDescriptorTable[codec->m_writeCipherType-1].m_generateKey(codec->m_writeCipher, codec->m_btShared, userPassword, passwordLength, 1, cipherSalt); + unsigned char dbHeader[KEYSALT_LENGTH]; + unsigned char* pDbHeader = (cipherSalt == NULL) ? mcReadDatabaseHeader(codec, dbHeader) : cipherSalt; + globalCodecDescriptorTable[codec->m_writeCipherType-1].m_generateKey(codec->m_writeCipher, userPassword, passwordLength, 1, pDbHeader); } SQLITE_PRIVATE int @@ -610,10 +651,10 @@ sqlite3mcConfigureSQLCipherVersion(sqlite3* db, int configDefault, int legacyVer static char* defNames[] = { "default:legacy_page_size", "default:kdf_iter", "default:hmac_use", "default:kdf_algorithm", "default:hmac_algorithm", NULL }; static int versionParams[SQLCIPHER_VERSION_MAX][5] = { - { 1024, 4000, 0, SQLCIPHER_KDF_ALGORITHM_SHA1, SQLCIPHER_HMAC_ALGORITHM_SHA1 }, - { 1024, 4000, 1, SQLCIPHER_KDF_ALGORITHM_SHA1, SQLCIPHER_HMAC_ALGORITHM_SHA1 }, - { 1024, 64000, 1, SQLCIPHER_KDF_ALGORITHM_SHA1, SQLCIPHER_HMAC_ALGORITHM_SHA1 }, - { 4096, 256000, 1, SQLCIPHER_KDF_ALGORITHM_SHA512, SQLCIPHER_HMAC_ALGORITHM_SHA512 } + { 1024, 4000, 0, SQLCIPHER_ALGORITHM_SHA1, SQLCIPHER_ALGORITHM_SHA1 }, + { 1024, 4000, 1, SQLCIPHER_ALGORITHM_SHA1, SQLCIPHER_ALGORITHM_SHA1 }, + { 1024, 64000, 1, SQLCIPHER_ALGORITHM_SHA1, SQLCIPHER_ALGORITHM_SHA1 }, + { 4096, 256000, 1, SQLCIPHER_ALGORITHM_SHA512, SQLCIPHER_ALGORITHM_SHA512 } }; if (legacyVersion > 0 && legacyVersion <= SQLCIPHER_VERSION_MAX) { diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.h index a1bae217c1..15bee4c5aa 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_common.h @@ -87,6 +87,7 @@ typedef struct _Codec unsigned char m_page[SQLITE_MAX_PAGE_SIZE + 24]; int m_pageSize; int m_reserved; + int m_lastError; int m_hasKeySalt; unsigned char m_keySalt[KEYSALT_LENGTH]; } Codec; @@ -158,6 +159,9 @@ SQLITE_PRIVATE int sqlite3mcGetReservedWriteCipher(Codec* codec); SQLITE_PRIVATE int sqlite3mcReservedEqual(Codec* codec); +SQLITE_PRIVATE void sqlite3mcSetCodecLastError(Codec* codec, int error); +SQLITE_PRIVATE int sqlite3mcGetCodecLastError(Codec* codec); + SQLITE_PRIVATE unsigned char* sqlite3mcGetSaltWriteCipher(Codec* codec); SQLITE_PRIVATE int sqlite3mcCodecCopy(Codec* codec, Codec* other); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.c index 6937968d7b..2dd63f15c4 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.c @@ -3,7 +3,7 @@ ** Purpose: Configuration of SQLite codecs ** Author: Ulrich Telle ** Created: 2020-03-02 -** Copyright: (c) 2006-2023 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -188,6 +188,21 @@ sqlite3mc_cipher_name(int cipherIndex) return cipherName; } +static +int checkParameterValue(const char* paramName, int value) +{ + int ok = 1; + if (sqlite3_stricmp(paramName, "legacy_page_size") == 0 && value > 0) + { + ok = value >= 512 && value <= SQLITE_MAX_PAGE_SIZE && ((value - 1) & value) == 0; + } + if (ok && sqlite3_stricmp(paramName, "plaintext_header_size") == 0 && value > 0) + { + ok = value % 16 == 0; + } + return ok; +} + SQLITE_API int sqlite3mc_config_cipher(sqlite3* db, const char* cipherName, const char* paramName, int newValue) { @@ -294,7 +309,8 @@ sqlite3mc_config_cipher(sqlite3* db, const char* cipherName, const char* paramNa value = (hasDefaultPrefix) ? param->m_default : (hasMinPrefix) ? param->m_minValue : (hasMaxPrefix) ? param->m_maxValue : param->m_value; if (!hasMinPrefix && !hasMaxPrefix) { - if (newValue >= 0 && newValue >= param->m_minValue && newValue <= param->m_maxValue) + if (newValue >= 0 && newValue >= param->m_minValue && newValue <= param->m_maxValue && + checkParameterValue(paramName, newValue)) { if (hasDefaultPrefix) { @@ -772,11 +788,11 @@ sqlite3mcConfigureFromUri(sqlite3* db, const char *zDbName, int configDefault) if (value >= 0) { /* Configure cipher parameter if it was given in the URI */ - char* param = (configDefault) ? sqlite3_mprintf("default:%s", cipherParams[j].m_name) : cipherParams[j].m_name; + const char* param = (configDefault) ? sqlite3_mprintf("default:%s", cipherParams[j].m_name) : cipherParams[j].m_name; sqlite3mc_config_cipher(db, cipherName, param, value); if (configDefault) { - sqlite3_free(param); + sqlite3_free((char*) param); } } } diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.h index 5a57c70359..451b98ac54 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_config.h @@ -16,7 +16,7 @@ SQLITE_PRIVATE void sqlite3mcConfigTable(sqlite3_context* context, int argc, sql SQLITE_PRIVATE CodecParameter* sqlite3mcGetCodecParams(sqlite3* db); /* Forward declaration */ -static unsigned char* sqlite3mcGetSaltWriteCipher(Codec* codec); +SQLITE_PRIVATE unsigned char* sqlite3mcGetSaltWriteCipher(Codec* codec); SQLITE_PRIVATE void sqlite3mcCodecDataSql(sqlite3_context* context, int argc, sqlite3_value** argv); SQLITE_PRIVATE void sqlite3mcConfigParams(sqlite3_context* context, int argc, sqlite3_value** argv); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sds_rc4.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sds_rc4.c index eda420f88c..2b940984b1 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sds_rc4.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sds_rc4.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher System.Data.SQLite3 RC4 ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2020 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -116,7 +116,7 @@ GetSaltRC4Cipher(void* cipher) } static void -GenerateKeyRC4Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeyRC4Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { RC4Cipher* rc4Cipher = (RC4Cipher*) cipher; unsigned char digest[SHA1_DIGEST_SIZE]; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sqlcipher.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sqlcipher.c index e97467ff24..f356fe0723 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sqlcipher.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_sqlcipher.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher SQLCipher (version 1 to 4) ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2020 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -31,13 +31,11 @@ #define SQLCIPHER_HMAC_PGNO_NATIVE 0 #define SQLCIPHER_HMAC_SALT_MASK 0x3a -#define SQLCIPHER_KDF_ALGORITHM_SHA1 0 -#define SQLCIPHER_KDF_ALGORITHM_SHA256 1 -#define SQLCIPHER_KDF_ALGORITHM_SHA512 2 +#define SQLCIPHER_ALGORITHM_SHA1 0 +#define SQLCIPHER_ALGORITHM_SHA256 1 +#define SQLCIPHER_ALGORITHM_SHA512 2 -#define SQLCIPHER_HMAC_ALGORITHM_SHA1 0 -#define SQLCIPHER_HMAC_ALGORITHM_SHA256 1 -#define SQLCIPHER_HMAC_ALGORITHM_SHA512 2 +#define SQLCIPHER_HMAC_ALGO_COMPAT 1 #define SQLCIPHER_VERSION_1 1 #define SQLCIPHER_VERSION_2 2 @@ -58,13 +56,13 @@ #if SQLCIPHER_VERSION_DEFAULT < SQLCIPHER_VERSION_4 #define SQLCIPHER_KDF_ITER 64000 #define SQLCIPHER_LEGACY_PAGE_SIZE 1024 -#define SQLCIPHER_KDF_ALGORITHM SQLCIPHER_KDF_ALGORITHM_SHA1 -#define SQLCIPHER_HMAC_ALGORITHM SQLCIPHER_HMAC_ALGORITHM_SHA1 +#define SQLCIPHER_KDF_ALGORITHM SQLCIPHER_ALGORITHM_SHA1 +#define SQLCIPHER_HMAC_ALGORITHM SQLCIPHER_ALGORITHM_SHA1 #else #define SQLCIPHER_KDF_ITER 256000 #define SQLCIPHER_LEGACY_PAGE_SIZE 4096 -#define SQLCIPHER_KDF_ALGORITHM SQLCIPHER_KDF_ALGORITHM_SHA512 -#define SQLCIPHER_HMAC_ALGORITHM SQLCIPHER_HMAC_ALGORITHM_SHA512 +#define SQLCIPHER_KDF_ALGORITHM SQLCIPHER_ALGORITHM_SHA512 +#define SQLCIPHER_HMAC_ALGORITHM SQLCIPHER_ALGORITHM_SHA512 #endif SQLITE_PRIVATE CipherParams mcSQLCipherParams[] = @@ -78,6 +76,7 @@ SQLITE_PRIVATE CipherParams mcSQLCipherParams[] = { "hmac_salt_mask", SQLCIPHER_HMAC_SALT_MASK, SQLCIPHER_HMAC_SALT_MASK, 0x00, 0xff }, { "kdf_algorithm", SQLCIPHER_KDF_ALGORITHM, SQLCIPHER_KDF_ALGORITHM, 0, 2 }, { "hmac_algorithm", SQLCIPHER_HMAC_ALGORITHM, SQLCIPHER_HMAC_ALGORITHM, 0, 2 }, + { "hmac_algorithm_compat", SQLCIPHER_HMAC_ALGO_COMPAT, SQLCIPHER_HMAC_ALGO_COMPAT, 0, 1 }, { "plaintext_header_size", 0, 0, 0, 100 /* restrict to db header size */ }, CIPHER_PARAMS_SENTINEL }; @@ -98,6 +97,7 @@ typedef struct _sqlCipherCipher int m_hmacSaltMask; int m_kdfAlgorithm; int m_hmacAlgorithm; + int m_hmacAlgorithmCompat; int m_plaintextHeaderSize; int m_keyLength; uint8_t m_key[KEYLENGTH_SQLCIPHER]; @@ -139,6 +139,7 @@ AllocateSQLCipherCipher(sqlite3* db) sqlCipherCipher->m_hmacSaltMask = sqlite3mcGetCipherParameter(cipherParams, "hmac_salt_mask"); sqlCipherCipher->m_kdfAlgorithm = sqlite3mcGetCipherParameter(cipherParams, "kdf_algorithm"); sqlCipherCipher->m_hmacAlgorithm = sqlite3mcGetCipherParameter(cipherParams, "hmac_algorithm"); + sqlCipherCipher->m_hmacAlgorithmCompat = sqlite3mcGetCipherParameter(cipherParams, "hmac_algorithm_compat"); if (sqlCipherCipher->m_legacy >= SQLCIPHER_VERSION_4) { int plaintextHeaderSize = sqlite3mcGetCipherParameter(cipherParams, "plaintext_header_size"); @@ -176,6 +177,7 @@ CloneSQLCipherCipher(void* cipherTo, void* cipherFrom) sqlCipherCipherTo->m_hmacSaltMask = sqlCipherCipherFrom->m_hmacSaltMask; sqlCipherCipherTo->m_kdfAlgorithm = sqlCipherCipherFrom->m_kdfAlgorithm; sqlCipherCipherTo->m_hmacAlgorithm = sqlCipherCipherFrom->m_hmacAlgorithm; + sqlCipherCipherTo->m_hmacAlgorithmCompat = sqlCipherCipherFrom->m_hmacAlgorithmCompat; sqlCipherCipherTo->m_plaintextHeaderSize = sqlCipherCipherFrom->m_plaintextHeaderSize; sqlCipherCipherTo->m_keyLength = sqlCipherCipherFrom->m_keyLength; memcpy(sqlCipherCipherTo->m_key, sqlCipherCipherFrom->m_key, KEYLENGTH_SQLCIPHER); @@ -217,11 +219,11 @@ GetReservedSQLCipherCipher(void* cipher) { switch (sqlCipherCipher->m_hmacAlgorithm) { - case SQLCIPHER_HMAC_ALGORITHM_SHA1: - case SQLCIPHER_HMAC_ALGORITHM_SHA256: + case SQLCIPHER_ALGORITHM_SHA1: + case SQLCIPHER_ALGORITHM_SHA256: reserved += SHA256_DIGEST_SIZE; break; - case SQLCIPHER_HMAC_ALGORITHM_SHA512: + case SQLCIPHER_ALGORITHM_SHA512: default: reserved += SHA512_DIGEST_SIZE; break; @@ -238,18 +240,15 @@ GetSaltSQLCipherCipher(void* cipher) } static void -GenerateKeySQLCipherCipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeySQLCipherCipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { SQLCipherCipher* sqlCipherCipher = (SQLCipherCipher*) cipher; - Pager *pPager = pBt->pPager; - sqlite3_file* fd = (isOpen(pPager->fd)) ? pPager->fd : NULL; - - if (rekey || fd == NULL || sqlite3OsRead(fd, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER, 0) != SQLITE_OK) + if (rekey || cipherSalt == NULL) { chacha20_rng(sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER); } - else if (cipherSalt != NULL) + else { memcpy(sqlCipherCipher->m_salt, cipherSalt, SALTLENGTH_SQLCIPHER); } @@ -271,19 +270,19 @@ GenerateKeySQLCipherCipher(void* cipher, BtShared* pBt, char* userPassword, int { switch (sqlCipherCipher->m_kdfAlgorithm) { - case SQLCIPHER_KDF_ALGORITHM_SHA1: + case SQLCIPHER_ALGORITHM_SHA1: fastpbkdf2_hmac_sha1((unsigned char*) userPassword, passwordLength, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER, sqlCipherCipher->m_kdfIter, sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER); break; - case SQLCIPHER_KDF_ALGORITHM_SHA256: + case SQLCIPHER_ALGORITHM_SHA256: fastpbkdf2_hmac_sha256((unsigned char*) userPassword, passwordLength, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER, sqlCipherCipher->m_kdfIter, sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER); break; - case SQLCIPHER_KDF_ALGORITHM_SHA512: + case SQLCIPHER_ALGORITHM_SHA512: default: fastpbkdf2_hmac_sha512((unsigned char*) userPassword, passwordLength, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER, @@ -296,6 +295,7 @@ GenerateKeySQLCipherCipher(void* cipher, BtShared* pBt, char* userPassword, int if (sqlCipherCipher->m_hmacUse != 0) { int j; + int algorithm = (sqlCipherCipher->m_hmacAlgorithmCompat) ? sqlCipherCipher->m_kdfAlgorithm : sqlCipherCipher->m_hmacAlgorithm; unsigned char hmacSaltMask = sqlCipherCipher->m_hmacSaltMask; unsigned char hmacSalt[SALTLENGTH_SQLCIPHER]; memcpy(hmacSalt, sqlCipherCipher->m_salt, SALTLENGTH_SQLCIPHER); @@ -303,21 +303,21 @@ GenerateKeySQLCipherCipher(void* cipher, BtShared* pBt, char* userPassword, int { hmacSalt[j] ^= hmacSaltMask; } - switch (sqlCipherCipher->m_hmacAlgorithm) + switch (algorithm) { - case SQLCIPHER_HMAC_ALGORITHM_SHA1: + case SQLCIPHER_ALGORITHM_SHA1: fastpbkdf2_hmac_sha1(sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER, hmacSalt, SALTLENGTH_SQLCIPHER, sqlCipherCipher->m_fastKdfIter, sqlCipherCipher->m_hmacKey, KEYLENGTH_SQLCIPHER); break; - case SQLCIPHER_HMAC_ALGORITHM_SHA256: + case SQLCIPHER_ALGORITHM_SHA256: fastpbkdf2_hmac_sha256(sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER, hmacSalt, SALTLENGTH_SQLCIPHER, sqlCipherCipher->m_fastKdfIter, sqlCipherCipher->m_hmacKey, KEYLENGTH_SQLCIPHER); break; - case SQLCIPHER_HMAC_ALGORITHM_SHA512: + case SQLCIPHER_ALGORITHM_SHA512: default: fastpbkdf2_hmac_sha512(sqlCipherCipher->m_key, KEYLENGTH_SQLCIPHER, hmacSalt, SALTLENGTH_SQLCIPHER, @@ -334,11 +334,13 @@ GetHmacSizeSQLCipherCipher(int algorithm) int hmacSize = SHA512_DIGEST_SIZE; switch (algorithm) { - case SQLCIPHER_HMAC_ALGORITHM_SHA1: + case SQLCIPHER_ALGORITHM_SHA1: hmacSize = SHA1_DIGEST_SIZE; break; - case SQLCIPHER_HMAC_ALGORITHM_SHA256: - case SQLCIPHER_HMAC_ALGORITHM_SHA512: + case SQLCIPHER_ALGORITHM_SHA256: + hmacSize = SHA256_DIGEST_SIZE; + break; + case SQLCIPHER_ALGORITHM_SHA512: default: hmacSize = SHA512_DIGEST_SIZE; break; @@ -356,7 +358,7 @@ EncryptPageSQLCipherCipher(void* cipher, int page, unsigned char* data, int len, int n = len - nReserved; int offset = (page == 1) ? (sqlCipherCipher->m_legacy != 0) ? 16 : 24 : 0; int blen; - unsigned char iv[64]; + unsigned char iv[128]; int usePlaintextHeader = 0; /* Check whether a plaintext header should be used */ @@ -373,10 +375,10 @@ EncryptPageSQLCipherCipher(void* cipher, int page, unsigned char* data, int len, } /* Generate nonce (64 bytes) */ - memset(iv, 0, 64); + memset(iv, 0, 128); if (nReserved > 0) { - chacha20_rng(iv, 64); + chacha20_rng(iv, 128); } else { diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes128.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes128.c index e84a88009f..67be9c21a7 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes128.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes128.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher wxSQLite3 AES 128-bit ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2020 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -130,7 +130,7 @@ GetSaltAES128Cipher(void* cipher) } static void -GenerateKeyAES128Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeyAES128Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { AES128Cipher* aesCipher = (AES128Cipher*) cipher; unsigned char userPad[32]; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes256.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes256.c index 906888a555..5fa8ba76b6 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes256.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/cipher_wxaes256.c @@ -3,7 +3,7 @@ ** Purpose: Implementation of cipher wxSQLite3 AES 256-bit ** Author: Ulrich Telle ** Created: 2020-02-02 -** Copyright: (c) 2006-2020 Ulrich Telle +** Copyright: (c) 2006-2024 Ulrich Telle ** License: MIT */ @@ -136,7 +136,7 @@ GetSaltAES256Cipher(void* cipher) } static void -GenerateKeyAES256Cipher(void* cipher, BtShared* pBt, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) +GenerateKeyAES256Cipher(void* cipher, char* userPassword, int passwordLength, int rekey, unsigned char* cipherSalt) { AES256Cipher* aesCipher = (AES256Cipher*) cipher; unsigned char userPad[32]; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codec_algos.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codec_algos.c index 7efa5db7c9..3c1951a2d5 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codec_algos.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codec_algos.c @@ -135,7 +135,7 @@ sqlite3mcAES128(Rijndael* aesCtx, int page, int encrypt, unsigned char encryptio { len = RijndaelBlockDecrypt(aesCtx, datain, datalen*8, dataout); } - + /* It is a good idea to check the error code */ if (len < 0) { @@ -189,7 +189,7 @@ sqlite3mcAES256(Rijndael* aesCtx, int page, int encrypt, unsigned char encryptio { len = RijndaelBlockDecrypt(aesCtx, datain, datalen*8, dataout); } - + /* It is a good idea to check the error code */ if (len < 0) { diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codecext.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codecext.c index 6754109ebc..fca5b11000 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codecext.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/codecext.c @@ -65,7 +65,7 @@ sqlite3_activate_see(const char *info) /* ** Free the encryption data structure associated with a pager instance. -** (called from the modified code in pager.c) +** (called from the modified code in pager.c) */ SQLITE_PRIVATE void sqlite3mcCodecFree(void *pCodecArg) @@ -95,12 +95,15 @@ mcReportCodecError(BtShared* pBt, int error) { pBt->pPager->eState = PAGER_ERROR; } - setGetterMethod(pBt->pPager); if (error == SQLITE_OK) { /* Clear cache to force reread of database after a new passphrase has been set */ sqlite3PagerClearCache(pBt->pPager); + /* unlock required? + pager_unlock(pBt->pPager); + */ } + setGetterMethod(pBt->pPager); } /* @@ -119,6 +122,7 @@ sqlite3mcCodec(void* pCodecArg, void* data, Pgno nPageNum, int nMode) codec = (Codec*) pCodecArg; if (!sqlite3mcIsEncrypted(codec)) { + sqlite3mcSetCodecLastError(codec, rc); return data; } @@ -132,7 +136,11 @@ sqlite3mcCodec(void* pCodecArg, void* data, Pgno nPageNum, int nMode) if (sqlite3mcHasReadCipher(codec)) { rc = sqlite3mcDecrypt(codec, nPageNum, (unsigned char*) data, pageSize); - if (rc != SQLITE_OK) mcReportCodecError(sqlite3mcGetBtShared(codec), rc); + if (rc != SQLITE_OK) + { + mcReportCodecError(sqlite3mcGetBtShared(codec), rc); + memset(data, 0, pageSize); + } } break; @@ -166,6 +174,7 @@ sqlite3mcCodec(void* pCodecArg, void* data, Pgno nPageNum, int nMode) } break; } + sqlite3mcSetCodecLastError(codec, rc); return data; } @@ -175,6 +184,9 @@ sqlite3mcGetMainCodec(sqlite3* db); SQLITE_PRIVATE void sqlite3mcSetCodec(sqlite3* db, const char* zDbName, const char* zFileName, Codec* codec); +SQLITE_PRIVATE int +sqlite3mcIsEncryptionSupported(sqlite3* db, const char* zDbName); + static int mcAdjustBtree(Btree* pBt, int nPageSize, int nReserved, int isLegacy) { @@ -190,11 +202,12 @@ mcAdjustBtree(Btree* pBt, int nPageSize, int nReserved, int isLegacy) /* Adjust the page size and the reserved area */ if (pager->pageSize != pagesize || pager->nReserve != nReserved) { + int reserved = (nReserved >= 0) ? nReserved : 0; if (isLegacy != 0) { pBt->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; } - rc = sqlite3BtreeSetPageSize(pBt, pagesize, nReserved, 0); + rc = sqlite3BtreeSetPageSize(pBt, pagesize, reserved, 0); } return rc; } @@ -332,6 +345,11 @@ SQLITE_API int sqlite3_key_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) { int rc = SQLITE_ERROR; + if (!sqlite3mcIsEncryptionSupported(db, zDbName)) + { + sqlite3ErrorWithMsg(db, rc, "Setting key failed. Encryption is not supported by the VFS."); + return rc; + } if (zKey != NULL && nKey < 0) { /* Key is zero-terminated string */ @@ -384,7 +402,15 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) int nReserved; Pager* pPager; Codec* codec; + int codecAllocated = 0; int rc = SQLITE_ERROR; + char* err = NULL; + + if (!sqlite3mcIsEncryptionSupported(db, zDbName)) + { + sqlite3ErrorWithMsg(db, rc, "Rekeying failed. Encryption is not supported by the VFS."); + return rc; + } if (zKey != NULL && nKey < 0) { /* Key is zero-terminated string */ @@ -417,10 +443,10 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) sqlite3ErrorWithMsg(db, rc, "Rekeying is not supported in WAL journal mode."); return rc; } - + if ((zKey == NULL || nKey == 0) && (codec == NULL || !sqlite3mcIsEncrypted(codec))) { - /* Database not encrypted and key not specified, therefore do nothing */ + /* Database not encrypted and key not specified, therefore do nothing */ return SQLITE_OK; } @@ -428,9 +454,10 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) if (codec == NULL || !sqlite3mcIsEncrypted(codec)) { - /* Database not encrypted, but key specified, therefore encrypt database */ + /* Database not encrypted, but key specified, therefore encrypt database */ if (codec == NULL) { + codecAllocated = 1; codec = (Codec*) sqlite3_malloc(sizeof(Codec)); rc = (codec != NULL) ? sqlite3mcCodecInit(codec) : SQLITE_NOMEM; } @@ -454,14 +481,9 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) if (nReserved != nReservedWriteCipher) { /* Use VACUUM to change the number of reserved bytes */ - char* err = NULL; sqlite3mcSetReadReserved(codec, nReserved); sqlite3mcSetWriteReserved(codec, nReservedWriteCipher); rc = sqlite3mcRunVacuumForRekey(&err, db, dbIndex, NULL, nReservedWriteCipher); - if (rc != SQLITE_OK && err != NULL) - { - sqlite3ErrorWithMsg(db, rc, err); - } goto leave_rekey; } } @@ -469,12 +491,17 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) { /* Pagesize cannot be changed for an encrypted database */ rc = SQLITE_ERROR; - sqlite3ErrorWithMsg(db, rc, "Rekeying failed. Pagesize cannot be changed for an encrypted database."); + err = "Rekeying failed. Pagesize cannot be changed for an encrypted database."; goto leave_rekey; } } else { + sqlite3_mutex_leave(db->mutex); + if (codecAllocated) + { + sqlite3mcCodecFree(codec); + } return rc; } } @@ -490,10 +517,6 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) sqlite3mcSetReadReserved(codec, nReserved); sqlite3mcSetWriteReserved(codec, 0); rc = sqlite3mcRunVacuumForRekey(&err, db, dbIndex, NULL, 0); - if (rc != SQLITE_OK && err != NULL) - { - sqlite3ErrorWithMsg(db, rc, err); - } goto leave_rekey; } } @@ -515,10 +538,6 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) sqlite3mcSetReadReserved(codec, nReserved); sqlite3mcSetWriteReserved(codec, nReservedWriteCipher); rc = sqlite3mcRunVacuumForRekey(&err, db, dbIndex, NULL, nReservedWriteCipher); - if (rc != SQLITE_OK && err != NULL) - { - sqlite3ErrorWithMsg(db, rc, err); - } goto leave_rekey; } } @@ -526,14 +545,14 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) { /* Pagesize cannot be changed for an encrypted database */ rc = SQLITE_ERROR; - sqlite3ErrorWithMsg(db, rc, "Rekeying failed. Pagesize cannot be changed for an encrypted database."); + err = "Rekeying failed. Pagesize cannot be changed for an encrypted database."; goto leave_rekey; } } else { /* Setup of write cipher failed */ - sqlite3ErrorWithMsg(db, rc, "Rekeying failed. Setup of write cipher failed."); + err = "Rekeying failed. Setup of write cipher failed."; goto leave_rekey; } } @@ -584,8 +603,15 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) /* Set read key equal to write key if necessary */ if (sqlite3mcHasWriteCipher(codec)) { + /* Set Read cipher equal to Write cipher */ sqlite3mcCopyCipher(codec, 0); sqlite3mcSetHasReadCipher(codec, 1); + + /* Enforce page size and number of reserved bytes per page */ + int pageSize = sqlite3mcGetPageSizeWriteCipher(codec); + int reserved = sqlite3mcGetReservedWriteCipher(codec); + mcAdjustBtree(pBt, pageSize, reserved, sqlite3mcGetLegacyWriteCipher(codec)); + sqlite3mcCodecSizeChange(codec, pageSize, reserved); } else { @@ -615,6 +641,10 @@ sqlite3_rekey_v2(sqlite3* db, const char* zDbName, const void* zKey, int nKey) /* Remove codec for unencrypted database */ sqlite3mcSetCodec(db, zDbName, dbFileName, NULL); } + if (rc != SQLITE_OK && err != NULL) + { + sqlite3ErrorWithMsg(db, rc, err); + } return rc; } diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/compress.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/compress.c index e6534e8a23..302fc7cfbb 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/compress.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/compress.c @@ -112,14 +112,14 @@ static void uncompressFunc( __declspec(dllexport) #endif int sqlite3_compress_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "compress", 1, + rc = sqlite3_create_function(db, "compress", 1, SQLITE_UTF8 | SQLITE_INNOCUOUS, 0, compressFunc, 0, 0); if( rc==SQLITE_OK ){ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/csv.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/csv.c index f980dfb028..7e54385167 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/csv.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/csv.c @@ -170,7 +170,7 @@ static int csv_getc(CsvReader *p){ return ((unsigned char*)p->zIn)[p->iIn++]; } -/* Increase the size of p->z and append character c to the end. +/* Increase the size of p->z and append character c to the end. ** Return 0 on success and non-zero if there is an OOM error */ static CSV_NOINLINE int csv_resize_and_append(CsvReader *p, char c){ char *zNew; @@ -289,9 +289,9 @@ static char *csv_read_one_field(CsvReader *p){ /* Forward references to the various virtual table methods implemented ** in this file. */ -static int csvtabCreate(sqlite3*, void*, int, const char*const*, +static int csvtabCreate(sqlite3*, void*, int, const char*const*, sqlite3_vtab**,char**); -static int csvtabConnect(sqlite3*, void*, int, const char*const*, +static int csvtabConnect(sqlite3*, void*, int, const char*const*, sqlite3_vtab**,char**); static int csvtabBestIndex(sqlite3_vtab*,sqlite3_index_info*); static int csvtabDisconnect(sqlite3_vtab*); @@ -476,7 +476,7 @@ static int csv_boolean_parameter( ** columns=N Assume the CSV file contains N columns. ** ** Only available if compiled with SQLITE_TEST: -** +** ** testflags=N Bitmask of test flags. Optional ** ** If schema= is omitted, then the columns are named "c0", "c1", "c2", @@ -503,7 +503,7 @@ static int csvtabConnect( CsvReader sRdr; /* A CSV file reader used to store an error ** message and/or to count the number of columns */ static const char *azParam[] = { - "filename", "data", "schema", + "filename", "data", "schema", }; char *azPValue[3]; /* Parameter values */ # define CSV_FILENAME (azPValue[0]) @@ -805,7 +805,7 @@ static int csvtabEof(sqlite3_vtab_cursor *cur){ ** the beginning. */ static int csvtabFilter( - sqlite3_vtab_cursor *pVtabCursor, + sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ @@ -861,7 +861,7 @@ static int csvtabBestIndex( unsigned char op; if( pIdxInfo->aConstraint[i].usable==0 ) continue; op = pIdxInfo->aConstraint[i].op; - if( op==SQLITE_INDEX_CONSTRAINT_EQ + if( op==SQLITE_INDEX_CONSTRAINT_EQ || op==SQLITE_INDEX_CONSTRAINT_LIKE || op==SQLITE_INDEX_CONSTRAINT_GLOB ){ @@ -948,14 +948,14 @@ static sqlite3_module CsvModuleFauxWrite = { #ifdef _WIN32 __declspec(dllexport) #endif -/* +/* ** This routine is called when the extension is loaded. The new ** CSV virtual table module is registered with the calling database ** connection. */ int sqlite3_csv_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ #ifndef SQLITE_OMIT_VIRTUALTABLE diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/extensionfunctions.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/extensionfunctions.c index 5dcaa10cdf..2e38d54f60 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/extensionfunctions.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/extensionfunctions.c @@ -54,7 +54,7 @@ Usage instructions for the sqlite3 program: security measure; see "Security Considerations" in http://www.sqlite.org/cvstrac/wiki?p=LoadableExtensions. If the sqlite3 program and library are built this - way, you cannot use these functions from the program, you + way, you cannot use these functions from the program, you must write your own program using the sqlite3 API, and call sqlite3_enable_load_extension as described above, or else rebuilt the sqlite3 program to allow loadable extensions. @@ -125,7 +125,7 @@ Original code 2006 June 05 by relicoder. #define HAVE_ISBLANK 1 #endif #define SQLITE_SOUNDEX 1 -#define HAVE_TRIM 1 /* LMH 2007-03-25 if sqlite has trim functions */ +#define HAVE_TRIM 1 /* LMH 2007-03-25 if sqlite has trim functions */ #ifdef COMPILE_SQLITE_EXTENSIONS_AS_LOADABLE_MODULE #include "sqlite3ext.h" @@ -139,7 +139,7 @@ SQLITE_EXTENSION_INIT1 #include #include #include -#include /* LMH 2007-03-25 */ +#include /* LMH 2007-03-25 */ #include #include @@ -319,7 +319,7 @@ static int sqlite3ReadUtf8(const unsigned char *z){ ** pZ is a UTF-8 encoded unicode string. If nByte is less than zero, ** return the number of unicode characters in pZ up to (but not including) ** the first 0x00 byte. If nByte is not less than zero, return the -** number of unicode characters in the first nByte of pZ (or up to +** number of unicode characters in the first nByte of pZ (or up to ** the first 0x00, whichever comes first). */ static int sqlite3Utf8CharLen(const char *z, int nByte){ @@ -354,7 +354,7 @@ static int sqlite3Utf8CharLen(const char *z, int nByte){ ** ** Could have been implemented using pointers to functions but this way it's inline ** and thus more efficient. Lower * ranking though... -** +** ** Parameters: ** name: function name to de defined (eg: sinFunc) ** function: function defined in math.h to wrap (eg: sin) @@ -400,7 +400,7 @@ GEN_MATH_WRAP_DOUBLE_1(atanFunc, atan) /* ** Many of systems don't have inverse hyperbolic trig functions so this will emulate -** them on those systems in terms of log and sqrt (formulas are too trivial to demand +** them on those systems in terms of log and sqrt (formulas are too trivial to demand ** written proof here) */ @@ -572,7 +572,7 @@ static void squareFunc(sqlite3_context *context, int argc, sqlite3_value **argv) ** (see sqrt just before this). Here the result is always double */ /* LMH 2007-03-25 Changed to use errno; no pre-checking for errors. Also removes - but that was present in the pre-checking that called sqlite3_result_error on + but that was present in the pre-checking that called sqlite3_result_error on a non-positive first argument, which is not always an error. */ static void powerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ double r1 = 0.0; @@ -580,9 +580,9 @@ static void powerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ double val; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ r1 = sqlite3_value_double(argv[0]); r2 = sqlite3_value_double(argv[1]); @@ -590,9 +590,9 @@ static void powerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ val = pow(r1,r2); if (errno == 0) { sqlite3_result_double(context, val); - } else { + } else { sqlite3_result_error(context, strerror(errno), errno); - } + } } } @@ -606,9 +606,9 @@ static void atn2Func(sqlite3_context *context, int argc, sqlite3_value **argv){ double r2 = 0.0; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ r1 = sqlite3_value_double(argv[0]); r2 = sqlite3_value_double(argv[1]); @@ -705,14 +705,14 @@ static void floorFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ #endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ /* -** Given a string (s) in the first argument and an integer (n) in the second returns the +** Given a string (s) in the first argument and an integer (n) in the second returns the ** string that constains s contatenated n times */ static void replicateFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ unsigned char *z; /* input string */ unsigned char *zo; /* result string */ i64 iCount; /* times to repeat */ - i64 nLen; /* length of the input string (no multibyte considerations) */ + i64 nLen; /* length of the input string (no multibyte considerations) */ i64 nTLen; /* length of the result string (no multibyte considerations) */ i64 i=0; @@ -747,7 +747,7 @@ static void replicateFunc(sqlite3_context *context, int argc, sqlite3_value **ar } } -/* +/* ** Some systems (win32 among others) don't have an isblank function, this will emulate it. ** This function is not UFT-8 safe since it only analyses a byte character. */ @@ -812,9 +812,9 @@ static void padlFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *zt; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ zi = (char *)sqlite3_value_text(argv[0]); ilen = sqlite3_value_int64(argv[1]); @@ -866,9 +866,9 @@ static void padrFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *zt; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ zi = (char *)sqlite3_value_text(argv[0]); ilen = sqlite3_value_int64(argv[1]); @@ -921,9 +921,9 @@ static void padcFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *zt; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ zi = (char *)sqlite3_value_text(argv[0]); ilen = sqlite3_value_int64(argv[1]); @@ -980,17 +980,17 @@ static void strfilterFunc(sqlite3_context *context, int argc, sqlite3_value **ar int c2 = 0; assert( argc==2 ); - + if( sqlite3_value_type(argv[0]) == SQLITE_NULL || sqlite3_value_type(argv[1]) == SQLITE_NULL ){ - sqlite3_result_null(context); + sqlite3_result_null(context); }else{ zi1 = (char *)sqlite3_value_text(argv[0]); zi2 = (char *)sqlite3_value_text(argv[1]); - /* - ** maybe I could allocate less, but that would imply 2 passes, rather waste + /* + ** maybe I could allocate less, but that would imply 2 passes, rather waste ** (possibly) some memory */ - zo = sqlite3_malloc((int) (strlen(zi1)+1)); + zo = sqlite3_malloc((int) (strlen(zi1)+1)); if (!zo){ sqlite3_result_error_nomem(context); return; @@ -1034,11 +1034,11 @@ static int _substr(const char* z1, const char* z2, int s, const char** p){ if( '\0'==*z1 ){ return -1; } - + while( (sqliteCharVal((unsigned char *)z2) != 0) && (c++) 0 ){ sqliteNextChar(zt); } @@ -1186,7 +1186,7 @@ static void rightFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ return; } strcpy((char*) rz, (char*) (zt)); - sqlite3_result_text(context, (char*)rz, -1, SQLITE_TRANSIENT); + sqlite3_result_text(context, (char*)rz, -1, SQLITE_TRANSIENT); sqlite3_free(rz); } @@ -1224,7 +1224,7 @@ static void ltrimFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ return; } z = sqlite3_value_text(argv[0]); - sqlite3_result_text(context, ltrim(z), -1, SQLITE_TRANSIENT); + sqlite3_result_text(context, ltrim(z), -1, SQLITE_TRANSIENT); } /* @@ -1465,7 +1465,7 @@ static void modeStep(sqlite3_context *context, int argc, sqlite3_value **argv){ if( type == SQLITE_NULL) return; - + p = sqlite3_aggregate_context(context, sizeof(*p)); if( 0==(p->m) ){ @@ -1504,33 +1504,33 @@ static void modeIterate(void* e, i64 c, void* pp){ i64 ei; double ed; ModeCtx *p = (ModeCtx*)pp; - + if( 0==p->is_double ){ ei = *(int*)(e); - if( p->mcnt==c ){ + if( p->mcnt==c ){ ++p->mn; }else if( p->mcntriM = ei; p->mcnt = c; - p->mn=1; + p->mn=1; } }else{ ed = *(double*)(e); - if( p->mcnt==c ){ + if( p->mcnt==c ){ ++p->mn; }else if(p->mcntrdM = ed; p->mcnt = c; - p->mn=1; + p->mn=1; } } } /* ** Auxiliary function that iterates all elements in a map and finds the median -** (the value such that the number of elements smaller is equal the the number of +** (the value such that the number of elements smaller is equal the the number of ** elements larger) */ static void medianIterate(void* e, i64 c, void* pp){ @@ -1601,9 +1601,9 @@ static void _medianFinalize(sqlite3_context *context){ if( 0==p->is_double ) if( 1==p->mn ) - sqlite3_result_int64(context, p->riM); + sqlite3_result_int64(context, p->riM); else - sqlite3_result_double(context, p->riM*1.0/p->mn); + sqlite3_result_double(context, p->riM*1.0/p->mn); else sqlite3_result_double(context, p->rdM/p->mn); } @@ -1723,12 +1723,12 @@ static void differenceFunc(sqlite3_context *context, int argc, sqlite3_value **a const u8 *zIn2; assert( argc==2 ); - + if( sqlite3_value_type(argv[0])==SQLITE_NULL || sqlite3_value_type(argv[1])==SQLITE_NULL ){ sqlite3_result_null(context); return; } - + zIn1 = (u8*)sqlite3_value_text(argv[0]); zIn2 = (u8*)sqlite3_value_text(argv[1]); @@ -1865,7 +1865,7 @@ int RegisterExtensionFunctions(sqlite3 *db){ aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0); #if 0 if( aFuncs[i].needCollSeq ){ - struct FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName, + struct FuncDef *pFunc = sqlite3FindFunction(db, aFuncs[i].zName, strlen(aFuncs[i].zName), aFuncs[i].nArg, aFuncs[i].eTextRep, 0); if( pFunc && aFuncs[i].needCollSeq ){ pFunc->needCollSeq = 1; @@ -1882,7 +1882,7 @@ int RegisterExtensionFunctions(sqlite3 *db){ } /* sqlite3CreateFunc */ /* LMH no error checking */ - sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, + sqlite3_create_function(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize); #if 0 if( aAggs[i].needCollSeq ){ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.c index a190f7616a..7ed8e16b80 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.c @@ -391,6 +391,7 @@ DECL_PBKDF2(sha512, sha512_extract, sha512_xor) +SQLITE_PRIVATE void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -402,6 +403,7 @@ void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, #endif } +SQLITE_PRIVATE void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -410,6 +412,7 @@ void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw, PBKDF2(sha256)(pw, npw, salt, nsalt, iterations, out, nout); } +SQLITE_PRIVATE void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -418,6 +421,7 @@ void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw, PBKDF2(sha512)(pw, npw, salt, nsalt, iterations, out, nout); } +SQLITE_PRIVATE void sqlcipher_hmac(int algorithm, unsigned char* key, int nkey, unsigned char* in, int in_sz, unsigned char* in2, int in2_sz, unsigned char* out) { switch (algorithm) diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.h index 75f7e2c742..d523314576 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fastpbkdf2.h @@ -15,6 +15,10 @@ #ifndef FASTPBKDF2_H #define FASTPBKDF2_H +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + #include #include "mystdint.h" @@ -31,6 +35,7 @@ extern "C" { * * This function cannot fail; it does not report errors. */ +SQLITE_PRIVATE void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -45,6 +50,7 @@ void fastpbkdf2_hmac_sha1(const uint8_t *pw, size_t npw, * * This function cannot fail; it does not report errors. */ +SQLITE_PRIVATE void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -59,6 +65,7 @@ void fastpbkdf2_hmac_sha256(const uint8_t *pw, size_t npw, * * This function cannot fail; it does not report errors. */ +SQLITE_PRIVATE void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw, const uint8_t *salt, size_t nsalt, uint32_t iterations, @@ -68,6 +75,7 @@ void fastpbkdf2_hmac_sha512(const uint8_t *pw, size_t npw, * * This function cannot fail; it does not report errors. */ +SQLITE_PRIVATE void sqlcipher_hmac(int algorithm, unsigned char* key, int nkey, unsigned char* in, int in_sz, diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fileio.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fileio.c index ca8090ed2e..4cc4b9f6e1 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fileio.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/fileio.c @@ -40,7 +40,7 @@ ** modification-time of the target file is set to this value before ** returning. ** -** If three or more arguments are passed to this function and an +** If five or more arguments are passed to this function and an ** error is encountered, an exception is raised. ** ** READFILE(FILE): @@ -69,8 +69,8 @@ ** directory, NULL. ** ** If a non-NULL value is specified for the optional $dir parameter and -** $path is a relative path, then $path is interpreted relative to $dir. -** And the paths returned in the "name" column of the table are also +** $path is a relative path, then $path is interpreted relative to $dir. +** And the paths returned in the "name" column of the table are also ** relative to directory $dir. ** ** Notes on building this extension for Windows: @@ -110,6 +110,13 @@ SQLITE_EXTENSION_INIT1 #include #include +/* When used as part of the CLI, the sqlite3_stdio.h module will have +** been included before this one. In that case use the sqlite3_stdio.h +** #defines. If not, create our own for fopen(). +*/ +#ifndef _SQLITE3_STDIO_H_ +# define sqlite3_fopen fopen +#endif /* ** Structure of the fsdir() table-valued function @@ -125,7 +132,7 @@ SQLITE_EXTENSION_INIT1 /* -** Set the result stored by context ctx to a blob containing the +** Set the result stored by context ctx to a blob containing the ** contents of file zName. Or, leave the result unchanged (NULL) ** if the file does not exist or is unreadable. ** @@ -142,7 +149,7 @@ static void readFileContents(sqlite3_context *ctx, const char *zName){ sqlite3 *db; int mxBlob; - in = fopen(zName, "rb"); + in = sqlite3_fopen(zName, "rb"); if( in==0 ){ /* File does not exist or is unreadable. Leave the result set to NULL. */ return; @@ -358,7 +365,7 @@ static int makeDirectory( } /* -** This function does the work for the writefile() UDF. Refer to +** This function does the work for the writefile() UDF. Refer to ** header comments at the top of this file for details. */ static int writeFile( @@ -397,7 +404,7 @@ static int writeFile( sqlite3_int64 nWrite = 0; const char *z; int rc = 0; - FILE *out = fopen(zFile, "wb"); + FILE *out = sqlite3_fopen(zFile, "wb"); if( out==0 ) return 1; z = (const char*)sqlite3_value_blob(pData); if( z ){ @@ -460,10 +467,10 @@ static int writeFile( return 1; } #else - /* Legacy unix. + /* Legacy unix. ** ** Do not use utimes() on a symbolic link - it sees through the link and - ** modifies the timestamps on the target. Or fails if the target does + ** modifies the timestamps on the target. Or fails if the target does ** not exist. */ if( 0==S_ISLNK(mode) ){ struct timeval times[2]; @@ -481,7 +488,7 @@ static int writeFile( } /* -** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function. +** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function. ** Refer to header comments at the top of this file for details. */ static void writefileFunc( @@ -495,7 +502,7 @@ static void writefileFunc( sqlite3_int64 mtime = -1; if( argc<2 || argc>4 ){ - sqlite3_result_error(context, + sqlite3_result_error(context, "wrong number of arguments to function writefile()", -1 ); return; @@ -565,7 +572,7 @@ static void lsModeFunc( #ifndef SQLITE_OMIT_VIRTUALTABLE -/* +/* ** Cursor type for recursively iterating through a directory structure. */ typedef struct fsdir_cursor fsdir_cursor; @@ -713,7 +720,7 @@ static int fsdirNext(sqlite3_vtab_cursor *cur){ } pCur->iLvl = iNew; pLvl = &pCur->aLvl[iNew]; - + pLvl->zDir = pCur->zPath; pCur->zPath = 0; pLvl->pDir = opendir(pLvl->zDir); @@ -844,7 +851,7 @@ static int fsdirEof(sqlite3_vtab_cursor *cur){ ** idxNum==2 Both PATH and DIR supplied */ static int fsdirFilter( - sqlite3_vtab_cursor *cur, + sqlite3_vtab_cursor *cur, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ @@ -933,7 +940,7 @@ static int fsdirBestIndex( } break; } - } + } } if( seenPath || seenDir ){ /* If input parameters are unusable, disallow this plan */ @@ -1005,14 +1012,14 @@ static int fsdirRegister(sqlite3 *db){ __declspec(dllexport) #endif int sqlite3_fileio_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ - rc = sqlite3_create_function(db, "readfile", 1, + rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8|SQLITE_DIRECTONLY, 0, readfileFunc, 0, 0); if( rc==SQLITE_OK ){ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/md5.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/md5.c index 2c7c6a1345..42e9b330a8 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/md5.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/md5.c @@ -60,19 +60,19 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx); * architectures that lack an AND-NOT instruction, just like in Colin Plumb's * implementation. */ -#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) -#define H(x, y, z) (((x) ^ (y)) ^ (z)) -#define H2(x, y, z) ((x) ^ ((y) ^ (z))) -#define I(x, y, z) ((y) ^ ((x) | ~(z))) +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) (((x) ^ (y)) ^ (z)) +#define H2(x, y, z) ((x) ^ ((y) ^ (z))) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) /* * The MD5 transformation for all four rounds. */ #define STEP(f, a, b, c, d, x, t, s) \ - (a) += f((b), (c), (d)) + (x) + (t); \ - (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ - (a) += (b); + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); /* * SET reads 4 input bytes in little-endian byte order and stores them @@ -84,18 +84,18 @@ static void MD5_Final(unsigned char *result, MD5_CTX *ctx); */ #if defined(__i386__) || defined(__x86_64__) || defined(__vax__) #define SET(n) \ - (*(MD5_u32plus *)&ptr[(n) * 4]) + (*(MD5_u32plus *)&ptr[(n) * 4]) #define GET(n) \ - SET(n) + SET(n) #else #define SET(n) \ - (ctx->block[(n)] = \ - (MD5_u32plus)ptr[(n) * 4] | \ - ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ - ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ - ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) + (ctx->block[(n)] = \ + (MD5_u32plus)ptr[(n) * 4] | \ + ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) #define GET(n) \ - (ctx->block[(n)]) + (ctx->block[(n)]) #endif /* diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/memory_secure.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/memory_secure.c index 171e2c645a..ee82bcafdb 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/memory_secure.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/memory_secure.c @@ -44,38 +44,6 @@ static volatile int mcSecureMemoryFlag = 0; /* Map of default memory allocation methods */ static volatile sqlite3_mem_methods mcDefaultMemoryMethods; -#if SQLITE3MC_ENABLE_RANDOM_FILL_MEMORY - -/* -** Fill a buffer with pseudo-random bytes. This is used to preset -** the content of a new memory allocation to unpredictable values and -** to clear the content of a freed allocation to unpredictable values. -*/ -static void mcRandomFill(char* pBuf, int nByte) -{ - unsigned int x, y, r; - x = SQLITE_PTR_TO_INT(pBuf); - y = nByte | 1; - while( nByte >= 4 ) - { - x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); - y = y*1103515245 + 12345; - r = x ^ y; - *(int*)pBuf = r; - pBuf += 4; - nByte -= 4; - } - while( nByte-- > 0 ) - { - x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); - y = y*1103515245 + 12345; - r = x ^ y; - *(pBuf++) = r & 0xff; - } -} - -#endif - /* ** Return the size of an allocation */ @@ -99,13 +67,8 @@ static void mcMemoryFree(void* pPrior) { if (mcSecureMemoryFlag) { -#if SQLITE3MC_USE_RANDOM_FILL_MEMORY - int nSize = mcMemorySize(pPrior); - mcRandomFill((char*) pPrior, nSize) -#else int nSize = mcMemorySize(pPrior); sqlite3mcSecureZeroMemory(pPrior, 0, nSize); -#endif } mcDefaultMemoryMethods.xFree(pPrior); } diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.c index 87bdedb188..b46bc7677e 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.c @@ -1379,15 +1379,15 @@ static int tdefl_flush_block(tdefl_compressor *d, int flush) #ifdef MINIZ_UNALIGNED_USE_MEMCPY static mz_uint16 TDEFL_READ_UNALIGNED_WORD(const mz_uint8* p) { - mz_uint16 ret; - memcpy(&ret, p, sizeof(mz_uint16)); - return ret; + mz_uint16 ret; + memcpy(&ret, p, sizeof(mz_uint16)); + return ret; } static mz_uint16 TDEFL_READ_UNALIGNED_WORD2(const mz_uint16* p) { - mz_uint16 ret; - memcpy(&ret, p, sizeof(mz_uint16)); - return ret; + mz_uint16 ret; + memcpy(&ret, p, sizeof(mz_uint16)); + return ret; } #else #define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p) @@ -1495,9 +1495,9 @@ static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahe #ifdef MINIZ_UNALIGNED_USE_MEMCPY static mz_uint32 TDEFL_READ_UNALIGNED_WORD32(const mz_uint8* p) { - mz_uint32 ret; - memcpy(&ret, p, sizeof(mz_uint32)); - return ret; + mz_uint32 ret; + memcpy(&ret, p, sizeof(mz_uint32)); + return ret; } #else #define TDEFL_READ_UNALIGNED_WORD32(p) *(const mz_uint32 *)(p) @@ -1572,7 +1572,7 @@ static mz_bool tdefl_compress_fast(tdefl_compressor *d) pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); #ifdef MINIZ_UNALIGNED_USE_MEMCPY - memcpy(&pLZ_code_buf[1], &cur_match_dist, sizeof(cur_match_dist)); + memcpy(&pLZ_code_buf[1], &cur_match_dist, sizeof(cur_match_dist)); #else *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; #endif @@ -2741,7 +2741,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex do { #ifdef MINIZ_UNALIGNED_USE_MEMCPY - memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32)*2); + memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32)*2); #else ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; @@ -2768,7 +2768,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex pOut_buf_cur[2] = pSrc[2]; pOut_buf_cur += 3; pSrc += 3; - counter -= 3; + counter -= 3; } if (counter > 0) { @@ -3706,47 +3706,47 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag if (extra_size_remaining) { - const mz_uint8 *pExtra_data; - void* buf = NULL; - - if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > n) - { - buf = MZ_MALLOC(ext_data_size); - if(buf==NULL) - return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); - - if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size, buf, ext_data_size) != ext_data_size) - { - MZ_FREE(buf); - return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); - } - - pExtra_data = (mz_uint8*)buf; - } - else - { - pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size; - } + const mz_uint8 *pExtra_data; + void* buf = NULL; + + if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > n) + { + buf = MZ_MALLOC(ext_data_size); + if(buf==NULL) + return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED); + + if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size, buf, ext_data_size) != ext_data_size) + { + MZ_FREE(buf); + return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED); + } + + pExtra_data = (mz_uint8*)buf; + } + else + { + pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size; + } do { mz_uint32 field_id; mz_uint32 field_data_size; - if (extra_size_remaining < (sizeof(mz_uint16) * 2)) - { - MZ_FREE(buf); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } + if (extra_size_remaining < (sizeof(mz_uint16) * 2)) + { + MZ_FREE(buf); + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + } field_id = MZ_READ_LE16(pExtra_data); field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16)); - if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining) - { - MZ_FREE(buf); - return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); - } + if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining) + { + MZ_FREE(buf); + return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED); + } if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID) { @@ -3760,7 +3760,7 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size; } while (extra_size_remaining); - MZ_FREE(buf); + MZ_FREE(buf); } } @@ -3965,7 +3965,7 @@ mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) { - MZ_FCLOSE(pFile); + MZ_FCLOSE(pFile); return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE); } @@ -6177,16 +6177,16 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n } #endif /* #ifndef MINIZ_NO_TIME */ - if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) - { - uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size); - uncomp_size = buf_size; - if (uncomp_size <= 3) - { - level = 0; - store_data_uncompressed = MZ_TRUE; - } - } + if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) + { + uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size); + uncomp_size = buf_size; + if (uncomp_size <= 3) + { + level = 0; + store_data_uncompressed = MZ_TRUE; + } + } archive_name_size = strlen(pArchive_name); if (archive_name_size > MZ_UINT16_MAX) @@ -6202,9 +6202,9 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n { /* Bail early if the archive would obviously become too large */ if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size - + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len + - pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len - + MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF) + + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len + + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len + + MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF) { pState->m_zip64 = MZ_TRUE; /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ @@ -6303,13 +6303,13 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n cur_archive_file_ofs += archive_name_size; } - if (user_extra_data_len > 0) - { - if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len) - return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); + if (user_extra_data_len > 0) + { + if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len) + return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED); - cur_archive_file_ofs += user_extra_data_len; - } + cur_archive_file_ofs += user_extra_data_len; + } if (store_data_uncompressed) { @@ -6461,8 +6461,8 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA { /* Bail early if the archive would obviously become too large */ if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE - + archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024 - + MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF) + + archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024 + + MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF) { pState->m_zip64 = MZ_TRUE; /*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */ @@ -6704,7 +6704,7 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA if (!mz_zip_writer_create_local_dir_header(pZip, local_dir_header, (mz_uint16)archive_name_size, (mz_uint16)(extra_size + user_extra_data_len), - (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size, + (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : uncomp_size, (max_size >= MZ_UINT32_MAX) ? MZ_UINT32_MAX : comp_size, uncomp_crc32, method, gen_flags, dos_time, dos_date)) return mz_zip_set_error(pZip, MZ_ZIP_INTERNAL_ERROR); @@ -6753,20 +6753,20 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA static size_t mz_file_read_func_stdio(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n) { - MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque; - mz_int64 cur_ofs = MZ_FTELL64(pSrc_file); + MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque; + mz_int64 cur_ofs = MZ_FTELL64(pSrc_file); - if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET)))) - return 0; + if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET)))) + return 0; - return MZ_FREAD(pBuf, 1, n, pSrc_file); + return MZ_FREAD(pBuf, 1, n, pSrc_file); } mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, - const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) + const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len) { - return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, pFile_time, pComment, comment_size, level_and_flags, - user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len); + return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, pFile_time, pComment, comment_size, level_and_flags, + user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len); } mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags) @@ -7088,11 +7088,11 @@ mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive * { /* src is zip64, dest must be zip64 */ - /* name uint32_t's */ - /* id 1 (optional in zip64?) */ - /* crc 1 */ - /* comp_size 2 */ - /* uncomp_size 2 */ + /* name uint32_t's */ + /* id 1 (optional in zip64?) */ + /* crc 1 */ + /* comp_size 2 */ + /* uncomp_size 2 */ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, (sizeof(mz_uint32) * 6)) != (sizeof(mz_uint32) * 6)) { pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf); diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.h index 6cc398c920..82be6580c3 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/miniz.h @@ -115,7 +115,7 @@ -/* Defines to completely disable specific portions of miniz.c: +/* Defines to completely disable specific portions of miniz.c: If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. */ /* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */ @@ -138,7 +138,7 @@ /* Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. */ /*#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES */ -/* Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. +/* Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. */ @@ -908,7 +908,7 @@ struct tinfl_decompressor_tag #ifdef __cplusplus } #endif - + #pragma once @@ -1226,13 +1226,13 @@ MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, c #if 0 /* TODO */ - typedef void *mz_zip_streaming_extract_state_ptr; - mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags); - uint64_t mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); - uint64_t mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); - mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, uint64_t new_ofs); - size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size); - mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); + typedef void *mz_zip_streaming_extract_state_ptr; + mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags); + uint64_t mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); + uint64_t mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); + mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, uint64_t new_ofs); + size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size); + mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState); #endif /* This function compares the archive's local headers, the optional local zip64 extended information block, and the optional descriptor following the compressed data vs. the data in the central directory. */ @@ -1294,8 +1294,8 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const cha /* Adds the contents of a file to an archive. This function also records the disk file's modified time into the archive. */ /* File data is supplied via a read callback function. User mz_zip_writer_add_(c)file to add a file directly.*/ MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size, - const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len, - const char *user_extra_data_central, mz_uint user_extra_data_central_len); + const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len, + const char *user_extra_data_central, mz_uint user_extra_data_central_len); #ifndef MINIZ_NO_STDIO diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/mystdint.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/mystdint.h index 3648a1fee3..a6beaf8c26 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/mystdint.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/mystdint.h @@ -19,7 +19,7 @@ typedef unsigned long long uint64_t; #define UINT8_MAX 255 #define UINT16_MAX 65535 #define UINT32_MAX 0xffffffffU /* 4294967295U */ -#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ +#define UINT64_MAX 0xffffffffffffffffULL /* 18446744073709551615ULL */ #else #include #endif diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/regexp.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/regexp.c index a50008ca35..1826649321 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/regexp.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/regexp.c @@ -169,7 +169,7 @@ static void re_add_state(ReStateSet *pSet, int newState){ /* Extract the next unicode character from *pzIn and return it. Advance ** *pzIn to the first byte past the end of the character returned. To -** be clear: this routine converts utf8 to unicode. This routine is +** be clear: this routine converts utf8 to unicode. This routine is ** optimized for the common case where the next character is a single byte. */ static unsigned re_next_char(ReInput *p){ @@ -240,7 +240,7 @@ static int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){ /* Look for the initial prefix match, if there is one. */ if( pRe->nInit ){ unsigned char x = pRe->zInit[0]; - while( in.i+pRe->nInit<=in.mx + while( in.i+pRe->nInit<=in.mx && (zIn[in.i]!=x || strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0) ){ @@ -710,7 +710,7 @@ static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ /* The following is a performance optimization. If the regex begins with ** ".*" (if the input regex lacks an initial "^") and afterwards there are ** one or more matching characters, enter those matching characters into - ** zInit[]. The re_match() routine can then search ahead in the input + ** zInit[]. The re_match() routine can then search ahead in the input ** string looking for the initial match without having to run the whole ** regex engine over the string. Do not worry about trying to match ** unicode characters beyond plane 0 - those are very rare and this is @@ -853,14 +853,14 @@ static void re_bytecode_func( __declspec(dllexport) #endif int sqlite3_regexp_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused */ - rc = sqlite3_create_function(db, "regexp", 2, + rc = sqlite3_create_function(db, "regexp", 2, SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, 0, re_sql_func, 0, 0); if( rc==SQLITE_OK ){ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rekeyvacuum.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rekeyvacuum.c index d50ed97e36..557f14678f 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rekeyvacuum.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rekeyvacuum.c @@ -27,7 +27,7 @@ ** Change 4: Call sqlite3mcBtreeSetPageSize instead of sqlite3BtreeSetPageSize for main database ** (sqlite3mcBtreeSetPageSize allows to reduce the number of reserved bytes) ** -** This code is generated by the script rekeyvacuum.sh from SQLite version 3.44.2 amalgamation. +** This code is generated by the script rekeyvacuum.sh from SQLite version 3.47.0 amalgamation. */ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey( char **pzErrMsg, /* Write error message here */ @@ -50,6 +50,9 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey( const char *zDbMain; /* Schema name of database to vacuum */ const char *zOut; /* Name of output file */ u32 pgflags = PAGER_SYNCHRONOUS_OFF; /* sync flags for output db */ + u64 iRandom; /* Random value used for zDbVacuum[] */ + char zDbVacuum[42]; /* Name of the ATTACH-ed database used for vacuum */ + if( !db->autoCommit ){ sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); @@ -90,27 +93,29 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey( pMain = db->aDb[iDb].pBt; isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); - /* Attach the temporary database as 'vacuum_db'. The synchronous pragma + /* Attach the temporary database as 'vacuum_XXXXXX'. The synchronous pragma ** can be set to 'off' for this file, as it is not recovered if a crash ** occurs anyway. The integrity of the database is maintained by a ** (possibly synchronous) transaction opened on the main database before ** sqlite3BtreeCopyFile() is called. ** ** An optimization would be to use a non-journaled pager. - ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but + ** (Later:) I tried setting "PRAGMA vacuum_XXXXXX.journal_mode=OFF" but ** that actually made the VACUUM run slower. Very little journalling ** actually occurs when doing a vacuum since the vacuum_db is initially ** empty. Only the journal header is written. Apparently it takes more ** time to parse and run the PRAGMA to turn journalling off than it does ** to write the journal header file. */ + sqlite3_randomness(sizeof(iRandom),&iRandom); + sqlite3_snprintf(sizeof(zDbVacuum), zDbVacuum, "vacuum_%016llx", iRandom); nDb = db->nDb; - rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS vacuum_db", zOut); + rc = execSqlF(db, pzErrMsg, "ATTACH %Q AS %s", zOut, zDbVacuum); db->openFlags = saved_openFlags; if( rc!=SQLITE_OK ) goto end_of_vacuum; assert( (db->nDb-1)==nDb ); pDb = &db->aDb[nDb]; - assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); + assert( strcmp(pDb->zDbSName,zDbVacuum)==0 ); pTemp = pDb->pBt; if( pOut ){ sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); @@ -195,11 +200,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey( ** the contents to the temporary database. */ rc = execSqlF(db, pzErrMsg, - "SELECT'INSERT INTO vacuum_db.'||quote(name)" + "SELECT'INSERT INTO %s.'||quote(name)" "||' SELECT*FROM\"%w\".'||quote(name)" - "FROM vacuum_db.sqlite_schema " + "FROM %s.sqlite_schema " "WHERE type='table'AND coalesce(rootpage,1)>0", - zDbMain + zDbVacuum, zDbMain, zDbVacuum ); assert( (db->mDbFlags & DBFLAG_Vacuum)!=0 ); db->mDbFlags &= ~DBFLAG_Vacuum; @@ -211,11 +216,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3mcRunVacuumForRekey( ** from the schema table. */ rc = execSqlF(db, pzErrMsg, - "INSERT INTO vacuum_db.sqlite_schema" + "INSERT INTO %s.sqlite_schema" " SELECT*FROM \"%w\".sqlite_schema" " WHERE type IN('view','trigger')" " OR(type='table'AND rootpage=0)", - zDbMain + zDbVacuum, zDbMain ); if( rc ) goto end_of_vacuum; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.c index fccca806d3..144e849088 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.c @@ -86,21 +86,21 @@ static UINT8 S[256]= { - 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, - 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, - 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, - 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, - 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, - 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, - 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, - 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, - 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, - 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, - 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, - 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, - 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, - 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, - 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22 }; @@ -171,7 +171,7 @@ static UINT8 T1[256][4]= {0x82,0x41,0x41,0xc3}, {0x29,0x99,0x99,0xb0}, {0x5a,0x2d,0x2d,0x77}, {0x1e,0x0f,0x0f,0x11}, {0x7b,0xb0,0xb0,0xcb}, {0xa8,0x54,0x54,0xfc}, {0x6d,0xbb,0xbb,0xd6}, {0x2c,0x16,0x16,0x3a} }; - + static UINT8 T2[256][4]= { {0xa5,0xc6,0x63,0x63}, {0x84,0xf8,0x7c,0x7c}, {0x99,0xee,0x77,0x77}, {0x8d,0xf6,0x7b,0x7b}, @@ -783,7 +783,7 @@ static UINT8 U1[256][4]= {0xa7,0x79,0xb4,0x92}, {0xa9,0x70,0xb9,0x99}, {0xbb,0x6b,0xae,0x84}, {0xb5,0x62,0xa3,0x8f}, {0x9f,0x5d,0x80,0xbe}, {0x91,0x54,0x8d,0xb5}, {0x83,0x4f,0x9a,0xa8}, {0x8d,0x46,0x97,0xa3} }; - + static UINT8 U2[256][4]= { {0x00,0x00,0x00,0x00}, {0x0b,0x0e,0x09,0x0d}, {0x16,0x1c,0x12,0x1a}, {0x1d,0x12,0x1b,0x17}, @@ -989,7 +989,7 @@ static UINT8 U4[256][4]= }; static UINT32 rcon[30]= -{ +{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, @@ -1003,11 +1003,13 @@ static UINT32 rcon[30]= ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ +SQLITE_PRIVATE void RijndaelCreate(Rijndael* rijndael) { rijndael->m_state = RIJNDAEL_State_Invalid; } +SQLITE_PRIVATE int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, UINT8* initVector) { UINT32 uKeyLenInBytes; @@ -1092,7 +1094,7 @@ int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, #endif } } -#ifndef TEST_AES_HW +#ifndef TEST_AES_HW else #endif #endif @@ -1104,7 +1106,7 @@ int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, if (rijndael->m_direction == RIJNDAEL_Direction_Decrypt) RijndaelKeyEncToDec(rijndael); } -#ifdef TEST_AES_HW +#ifdef TEST_AES_HW { int cmpkeyexp = memcmp((unsigned char*) rijndael->m_expandedKey, aesKeySched, (rijndael->m_uRounds+1)*16); int datalen = (rijndael->m_uRounds + 1) * 16; @@ -1134,10 +1136,10 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* numBlocks = inputLen/128; lenFrag = (inputLen % 128) / 8; - + switch (rijndael->m_mode) { - case RIJNDAEL_Direction_Mode_ECB: + case RIJNDAEL_Direction_Mode_ECB: for(i = numBlocks;i > 0;i--) { RijndaelEncrypt(rijndael, input, outBuffer); @@ -1149,7 +1151,7 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* #if HAS_AES_HARDWARE if (aesHardwareAvailable()) { -#ifndef TEST_AES_HW +#ifndef TEST_AES_HW aesEncryptCBC(input, outBuffer, rijndael->m_initVector, inputLen/8, (unsigned char*) (rijndael->m_expandedKey), rijndael->m_uRounds); #else TEST_AES_HW_DEBUG_LOG("aes enc: hw enabled\n"); @@ -1195,8 +1197,8 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* } break; case RIJNDAEL_Direction_Mode_CFB1: -#if STRICT_ALIGN - memcpy(iv,rijndael->m_initVector,16); +#if STRICT_ALIGN + memcpy(iv,rijndael->m_initVector,16); #else /* !STRICT_ALIGN */ *((UINT32*)iv[0]) = *((UINT32*)(rijndael->m_initVector )); *((UINT32*)iv[1]) = *((UINT32*)(rijndael->m_initVector + 4)); @@ -1240,7 +1242,7 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* break; } -#ifdef TEST_AES_HW +#ifdef TEST_AES_HW { int cmpdata = memcmp((unsigned char*) outOrig, outBuffer2, inputLen/8); TEST_AES_HW_DEBUG_LOG("aes enc: cmp=%d\n", cmpdata); @@ -1248,10 +1250,11 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* TEST_AES_HW_DEBUG_HEX("aes enc HW:", outBuffer2, 16); } #endif - + return 128 * numBlocks; } +SQLITE_PRIVATE int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer) { int i, numBlocks, padLen; @@ -1266,7 +1269,7 @@ int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 switch (rijndael->m_mode) { - case RIJNDAEL_Direction_Mode_ECB: + case RIJNDAEL_Direction_Mode_ECB: for(i = numBlocks; i > 0; i--) { RijndaelEncrypt(rijndael, input, outBuffer); @@ -1306,10 +1309,11 @@ int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 return -1; break; } - + return 16*(numBlocks + 1); } - + +SQLITE_PRIVATE int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* outBuffer) { int i, k, numBlocks, lenFrag; @@ -1329,7 +1333,7 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* switch (rijndael->m_mode) { - case RIJNDAEL_Direction_Mode_ECB: + case RIJNDAEL_Direction_Mode_ECB: for (i = numBlocks; i > 0; i--) { RijndaelDecrypt(rijndael, input, outBuffer); @@ -1384,8 +1388,8 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* } } } -#if STRICT_ALIGN - memcpy(iv,rijndael->m_initVector,16); +#if STRICT_ALIGN + memcpy(iv,rijndael->m_initVector,16); #else *((UINT32*)iv[0]) = *((UINT32*)(rijndael->m_initVector )); *((UINT32*)iv[1]) = *((UINT32*)(rijndael->m_initVector+ 4)); @@ -1414,8 +1418,8 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* } break; case RIJNDAEL_Direction_Mode_CFB1: -#if STRICT_ALIGN - memcpy(iv, rijndael->m_initVector, 16); +#if STRICT_ALIGN + memcpy(iv, rijndael->m_initVector, 16); #else *((UINT32*)iv[0]) = *((UINT32*)(rijndael->m_initVector)); *((UINT32*)iv[1]) = *((UINT32*)(rijndael->m_initVector+ 4)); @@ -1459,7 +1463,7 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* break; } -#ifdef TEST_AES_HW +#ifdef TEST_AES_HW { int cmpdata = memcmp((unsigned char*) outOrig, outBuffer2, inputLen/8); TEST_AES_HW_DEBUG_LOG("aes dec: cmp=%d\n", cmpdata); @@ -1467,10 +1471,11 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8* input, int inputLen, UINT8* TEST_AES_HW_DEBUG_HEX("aes dec HW:", outBuffer2, 16); } #endif - + return 128*numBlocks; } +SQLITE_PRIVATE int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer) { int i, numBlocks, padLen; @@ -1504,7 +1509,7 @@ int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 if (block[i] != padLen) return RIJNDAEL_CORRUPTED_DATA; } memcpy(outBuffer, block, 16 - padLen); - break; + break; case RIJNDAEL_Direction_Mode_CBC: memcpy(iv, rijndael->m_initVector, 16); /* all blocks but last */ @@ -1534,12 +1539,12 @@ int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 } memcpy(outBuffer, block, 16 - padLen); break; - + default: return -1; break; } - + return 16*numBlocks - padLen; } @@ -1549,6 +1554,7 @@ int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */ +SQLITE_PRIVATE void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]) { int j,rconpointer = 0; @@ -1585,7 +1591,7 @@ void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]) t = 0; } } - + while(r <= rijndael->m_uRounds) { tempKey[0][0] ^= S[tempKey[uKeyColumns-1][1]]; @@ -1626,9 +1632,10 @@ void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]) t = 0; } } - } + } } +SQLITE_PRIVATE void RijndaelKeyEncToDec(Rijndael* rijndael) { UINT32 r; @@ -1645,8 +1652,9 @@ void RijndaelKeyEncToDec(Rijndael* rijndael) w = rijndael->m_expandedKey[r][3]; *((UINT32*)w) = *((UINT32*)U1[w[0]]) ^ *((UINT32*)U2[w[1]]) ^ *((UINT32*)U3[w[2]]) ^ *((UINT32*)U4[w[3]]); } -} +} +SQLITE_PRIVATE void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) { UINT32 r; @@ -1658,19 +1666,19 @@ void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)temp[3]) = *((UINT32*)(a+12)) ^ *((UINT32*)rijndael->m_expandedKey[0][3]); *((UINT32*)(b )) = *((UINT32*)T1[temp[0][0]]) ^ *((UINT32*)T2[temp[1][1]]) - ^ *((UINT32*)T3[temp[2][2]]) + ^ *((UINT32*)T3[temp[2][2]]) ^ *((UINT32*)T4[temp[3][3]]); *((UINT32*)(b + 4)) = *((UINT32*)T1[temp[1][0]]) ^ *((UINT32*)T2[temp[2][1]]) - ^ *((UINT32*)T3[temp[3][2]]) + ^ *((UINT32*)T3[temp[3][2]]) ^ *((UINT32*)T4[temp[0][3]]); *((UINT32*)(b + 8)) = *((UINT32*)T1[temp[2][0]]) ^ *((UINT32*)T2[temp[3][1]]) - ^ *((UINT32*)T3[temp[0][2]]) + ^ *((UINT32*)T3[temp[0][2]]) ^ *((UINT32*)T4[temp[1][3]]); *((UINT32*)(b +12)) = *((UINT32*)T1[temp[3][0]]) ^ *((UINT32*)T2[temp[0][1]]) - ^ *((UINT32*)T3[temp[1][2]]) + ^ *((UINT32*)T3[temp[1][2]]) ^ *((UINT32*)T4[temp[2][3]]); for(r = 1; r < rijndael->m_uRounds-1; r++) { @@ -1681,19 +1689,19 @@ void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)(b )) = *((UINT32*)T1[temp[0][0]]) ^ *((UINT32*)T2[temp[1][1]]) - ^ *((UINT32*)T3[temp[2][2]]) + ^ *((UINT32*)T3[temp[2][2]]) ^ *((UINT32*)T4[temp[3][3]]); *((UINT32*)(b + 4)) = *((UINT32*)T1[temp[1][0]]) ^ *((UINT32*)T2[temp[2][1]]) - ^ *((UINT32*)T3[temp[3][2]]) + ^ *((UINT32*)T3[temp[3][2]]) ^ *((UINT32*)T4[temp[0][3]]); *((UINT32*)(b + 8)) = *((UINT32*)T1[temp[2][0]]) ^ *((UINT32*)T2[temp[3][1]]) - ^ *((UINT32*)T3[temp[0][2]]) + ^ *((UINT32*)T3[temp[0][2]]) ^ *((UINT32*)T4[temp[1][3]]); *((UINT32*)(b +12)) = *((UINT32*)T1[temp[3][0]]) ^ *((UINT32*)T2[temp[0][1]]) - ^ *((UINT32*)T3[temp[1][2]]) + ^ *((UINT32*)T3[temp[1][2]]) ^ *((UINT32*)T4[temp[2][3]]); } *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)rijndael->m_expandedKey[rijndael->m_uRounds-1][0]); @@ -1722,11 +1730,12 @@ void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)(b+12)) ^= *((UINT32*)rijndael->m_expandedKey[rijndael->m_uRounds][3]); } +SQLITE_PRIVATE void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) { int r; UINT8 temp[4][4]; - + *((UINT32*)temp[0]) = *((UINT32*)(a )) ^ *((UINT32*)rijndael->m_expandedKey[rijndael->m_uRounds][0]); *((UINT32*)temp[1]) = *((UINT32*)(a+ 4)) ^ *((UINT32*)rijndael->m_expandedKey[rijndael->m_uRounds][1]); *((UINT32*)temp[2]) = *((UINT32*)(a+ 8)) ^ *((UINT32*)rijndael->m_expandedKey[rijndael->m_uRounds][2]); @@ -1734,19 +1743,19 @@ void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)(b )) = *((UINT32*)T5[temp[0][0]]) ^ *((UINT32*)T6[temp[3][1]]) - ^ *((UINT32*)T7[temp[2][2]]) + ^ *((UINT32*)T7[temp[2][2]]) ^ *((UINT32*)T8[temp[1][3]]); *((UINT32*)(b+ 4)) = *((UINT32*)T5[temp[1][0]]) ^ *((UINT32*)T6[temp[0][1]]) - ^ *((UINT32*)T7[temp[3][2]]) + ^ *((UINT32*)T7[temp[3][2]]) ^ *((UINT32*)T8[temp[2][3]]); *((UINT32*)(b+ 8)) = *((UINT32*)T5[temp[2][0]]) ^ *((UINT32*)T6[temp[1][1]]) - ^ *((UINT32*)T7[temp[0][2]]) + ^ *((UINT32*)T7[temp[0][2]]) ^ *((UINT32*)T8[temp[3][3]]); *((UINT32*)(b+12)) = *((UINT32*)T5[temp[3][0]]) ^ *((UINT32*)T6[temp[2][1]]) - ^ *((UINT32*)T7[temp[1][2]]) + ^ *((UINT32*)T7[temp[1][2]]) ^ *((UINT32*)T8[temp[0][3]]); for(r = rijndael->m_uRounds-1; r > 1; r--) { @@ -1756,22 +1765,22 @@ void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)temp[3]) = *((UINT32*)(b+12)) ^ *((UINT32*)rijndael->m_expandedKey[r][3]); *((UINT32*)(b )) = *((UINT32*)T5[temp[0][0]]) ^ *((UINT32*)T6[temp[3][1]]) - ^ *((UINT32*)T7[temp[2][2]]) + ^ *((UINT32*)T7[temp[2][2]]) ^ *((UINT32*)T8[temp[1][3]]); *((UINT32*)(b+ 4)) = *((UINT32*)T5[temp[1][0]]) ^ *((UINT32*)T6[temp[0][1]]) - ^ *((UINT32*)T7[temp[3][2]]) + ^ *((UINT32*)T7[temp[3][2]]) ^ *((UINT32*)T8[temp[2][3]]); *((UINT32*)(b+ 8)) = *((UINT32*)T5[temp[2][0]]) ^ *((UINT32*)T6[temp[1][1]]) - ^ *((UINT32*)T7[temp[0][2]]) + ^ *((UINT32*)T7[temp[0][2]]) ^ *((UINT32*)T8[temp[3][3]]); *((UINT32*)(b+12)) = *((UINT32*)T5[temp[3][0]]) ^ *((UINT32*)T6[temp[2][1]]) - ^ *((UINT32*)T7[temp[1][2]]) + ^ *((UINT32*)T7[temp[1][2]]) ^ *((UINT32*)T8[temp[0][3]]); } - + *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)rijndael->m_expandedKey[1][0]); *((UINT32*)temp[1]) = *((UINT32*)(b+ 4)) ^ *((UINT32*)rijndael->m_expandedKey[1][1]); *((UINT32*)temp[2]) = *((UINT32*)(b+ 8)) ^ *((UINT32*)rijndael->m_expandedKey[1][2]); @@ -1798,6 +1807,7 @@ void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]) *((UINT32*)(b+12)) ^= *((UINT32*)rijndael->m_expandedKey[0][3]); } +SQLITE_PRIVATE void RijndaelInvalidate(Rijndael* rijndael) { rijndael->m_state = RIJNDAEL_State_Invalid; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.h index f383c0cbb5..837169b286 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/rijndael.h @@ -18,6 +18,10 @@ #ifndef _RIJNDAEL_H_ #define _RIJNDAEL_H_ +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + /* // File : rijndael.h // Creation date : Sun Nov 5 2000 03:21:05 CEST @@ -116,16 +120,16 @@ typedef unsigned short UINT16; */ typedef struct _Rijndael -{ - int m_state; - int m_mode; - int m_direction; - UINT8 m_initVector[MAX_IV_SIZE]; - UINT32 m_uRounds; - UINT8 m_expandedKey[_MAX_ROUNDS+1][4][4]; +{ + int m_state; + int m_mode; + int m_direction; + UINT8 m_initVector[MAX_IV_SIZE]; + UINT32 m_uRounds; + UINT8 m_expandedKey[_MAX_ROUNDS+1][4][4]; } Rijndael; -void RijndaelCreate(Rijndael* rijndael); +SQLITE_PRIVATE void RijndaelCreate(Rijndael* rijndael); /* ////////////////////////////////////////////////////////////////////////////////////////// @@ -147,7 +151,7 @@ void RijndaelCreate(Rijndael* rijndael); // keyLen : Rijndael::Key16Bytes , Rijndael::Key24Bytes or Rijndael::Key32Bytes // initVector: initialization vector, you will usually use 0 here */ -int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, UINT8* initVector); +SQLITE_PRIVATE int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, UINT8* initVector); /* // Encrypts the input array (can be binary data) @@ -158,7 +162,7 @@ int RijndaelInit(Rijndael* rijndael, int mode, int dir, UINT8* key, int keyLen, // outBuffer must be at least inputLen / 8 bytes long. // Returns the encrypted buffer length in BITS or an error code < 0 in case of error */ -int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer); +SQLITE_PRIVATE int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer); /* // Encrypts the input array (can be binary data) @@ -167,7 +171,7 @@ int RijndaelBlockEncrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 * // outBuffer must be at least (inputLen + 16) bytes long // Returns the encrypted buffer length in BYTES or an error code < 0 in case of error */ -int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer); +SQLITE_PRIVATE int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer); /* // Decrypts the input vector @@ -175,7 +179,7 @@ int RijndaelPadEncrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 // outBuffer must be at least inputLen / 8 bytes long // Returns the decrypted buffer length in BITS and an error code < 0 in case of error */ -int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer); +SQLITE_PRIVATE int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 *outBuffer); /* // Decrypts the input vector @@ -183,12 +187,12 @@ int RijndaelBlockDecrypt(Rijndael* rijndael, UINT8 *input, int inputLen, UINT8 * // outBuffer must be at least inputLen bytes long // Returns the decrypted buffer length in BYTES and an error code < 0 in case of error */ -int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer); - -void RijndaelInvalidate(Rijndael* rijndael); -void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]); -void RijndaelKeyEncToDec(Rijndael* rijndael); -void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]); -void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]); - +SQLITE_PRIVATE int RijndaelPadDecrypt(Rijndael* rijndael, UINT8 *input, int inputOctets, UINT8 *outBuffer); + +SQLITE_PRIVATE void RijndaelInvalidate(Rijndael* rijndael); +SQLITE_PRIVATE void RijndaelKeySched(Rijndael* rijndael, UINT8 key[_MAX_KEY_COLUMNS][4]); +SQLITE_PRIVATE void RijndaelKeyEncToDec(Rijndael* rijndael); +SQLITE_PRIVATE void RijndaelEncrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]); +SQLITE_PRIVATE void RijndaelDecrypt(Rijndael* rijndael, UINT8 a[16], UINT8 b[16]); + #endif /* _RIJNDAEL_H_ */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/series.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/series.c index 0dfed181f6..e0810fa6a1 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/series.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/series.c @@ -90,6 +90,26 @@ ** and a very large cost if either start or stop are unavailable. This ** encourages the query planner to order joins such that the bounds of the ** series are well-defined. +** +** Update on 2024-08-22: +** xBestIndex now also looks for equality and inequality constraints against +** the value column and uses those constraints as additional bounds against +** the sequence range. Thus, a query like this: +** +** SELECT value FROM generate_series($SA,$EA) +** WHERE value BETWEEN $SB AND $EB; +** +** Is logically the same as: +** +** SELECT value FROM generate_series(max($SA,$SB),min($EA,$EB)); +** +** Constraints on the value column can server as substitutes for constraints +** on the hidden start and stop columns. So, the following two queries +** are equivalent: +** +** SELECT value FROM generate_series($S,$E); +** SELECT value FROM generate_series WHERE value BETWEEN $S and $E; +** */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 @@ -131,8 +151,10 @@ static sqlite3_int64 genSeqMember( typedef unsigned char u8; typedef struct SequenceSpec { - sqlite3_int64 iBase; /* Starting value ("start") */ - sqlite3_int64 iTerm; /* Given terminal value ("stop") */ + sqlite3_int64 iOBase; /* Original starting value ("start") */ + sqlite3_int64 iOTerm; /* Original terminal value ("stop") */ + sqlite3_int64 iBase; /* Starting value to actually use */ + sqlite3_int64 iTerm; /* Terminal value to actually use */ sqlite3_int64 iStep; /* Increment ("step") */ sqlite3_uint64 uSeqIndexMax; /* maximum sequence index (aka "n") */ sqlite3_uint64 uSeqIndexNow; /* Current index during generation */ @@ -325,9 +347,9 @@ static int seriesColumn( series_cursor *pCur = (series_cursor*)cur; sqlite3_int64 x = 0; switch( i ){ - case SERIES_COLUMN_START: x = pCur->ss.iBase; break; - case SERIES_COLUMN_STOP: x = pCur->ss.iTerm; break; - case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break; + case SERIES_COLUMN_START: x = pCur->ss.iOBase; break; + case SERIES_COLUMN_STOP: x = pCur->ss.iOTerm; break; + case SERIES_COLUMN_STEP: x = pCur->ss.iStep; break; default: x = pCur->ss.iValueNow; break; } sqlite3_result_int64(ctx, x); @@ -335,7 +357,9 @@ static int seriesColumn( } #ifndef LARGEST_UINT64 +#define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) #define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32)) +#define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) #endif /* @@ -376,13 +400,18 @@ static int seriesEof(sqlite3_vtab_cursor *cur){ ** parameter. (idxStr is not used in this implementation.) idxNum ** is a bitmask showing which constraints are available: ** -** 0x01: start=VALUE -** 0x02: stop=VALUE -** 0x04: step=VALUE -** 0x08: descending order -** 0x10: ascending order -** 0x20: LIMIT VALUE -** 0x40: OFFSET VALUE +** 0x0001: start=VALUE +** 0x0002: stop=VALUE +** 0x0004: step=VALUE +** 0x0008: descending order +** 0x0010: ascending order +** 0x0020: LIMIT VALUE +** 0x0040: OFFSET VALUE +** 0x0080: value=VALUE +** 0x0100: value>=VALUE +** 0x0200: value>VALUE +** 0x1000: value<=VALUE +** 0x2000: valuess.iBase = sqlite3_value_int64(argv[i++]); @@ -416,16 +451,98 @@ static int seriesFilter( }else{ pCur->ss.iStep = 1; } + + /* If there are constraints on the value column but there are + ** no constraints on the start, stop, and step columns, then + ** initialize the default range to be the entire range of 64-bit signed + ** integers. This range will contracted by the value column constraints + ** further below. + */ + if( (idxNum & 0x05)==0 && (idxNum & 0x0380)!=0 ){ + pCur->ss.iBase = SMALLEST_INT64; + } + if( (idxNum & 0x06)==0 && (idxNum & 0x3080)!=0 ){ + pCur->ss.iTerm = LARGEST_INT64; + } + pCur->ss.iOBase = pCur->ss.iBase; + pCur->ss.iOTerm = pCur->ss.iTerm; + + /* Extract the LIMIT and OFFSET values, but do not apply them yet. + ** The range must first be constrained by the limits on value. + */ if( idxNum & 0x20 ){ - sqlite3_int64 iLimit = sqlite3_value_int64(argv[i++]); - sqlite3_int64 iTerm; + iLimit = sqlite3_value_int64(argv[i++]); if( idxNum & 0x40 ){ - sqlite3_int64 iOffset = sqlite3_value_int64(argv[i++]); - if( iOffset>0 ){ - pCur->ss.iBase += pCur->ss.iStep*iOffset; + iOffset = sqlite3_value_int64(argv[i++]); + } + } + + if( idxNum & 0x3380 ){ + /* Extract the maximum range of output values determined by + ** constraints on the "value" column. + */ + if( idxNum & 0x0080 ){ + iMin = iMax = sqlite3_value_int64(argv[i++]); + }else{ + if( idxNum & 0x0300 ){ + iMin = sqlite3_value_int64(argv[i++]); + if( idxNum & 0x0200 ){ + if( iMin==LARGEST_INT64 ){ + returnNoRows = 1; + }else{ + iMin++; + } + } + } + if( idxNum & 0x3000 ){ + iMax = sqlite3_value_int64(argv[i++]); + if( idxNum & 0x2000 ){ + if( iMax==SMALLEST_INT64 ){ + returnNoRows = 1; + }else{ + iMax--; + } + } + } + if( iMin>iMax ){ + returnNoRows = 1; + } + } + + /* Try to reduce the range of values to be generated based on + ** constraints on the "value" column. + */ + if( pCur->ss.iStep>0 ){ + sqlite3_int64 szStep = pCur->ss.iStep; + if( pCur->ss.iBasess.iBase; + pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep; + } + if( pCur->ss.iTerm>iMax ){ + sqlite3_uint64 d = pCur->ss.iTerm - iMax; + pCur->ss.iTerm -= ((d+szStep-1)/szStep)*szStep; + } + }else{ + sqlite3_int64 szStep = -pCur->ss.iStep; + assert( szStep>0 ); + if( pCur->ss.iBase>iMax ){ + sqlite3_uint64 d = pCur->ss.iBase - iMax; + pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep; + } + if( pCur->ss.iTermss.iTerm; + pCur->ss.iTerm += ((d+szStep-1)/szStep)*szStep; } } + } + + /* Apply LIMIT and OFFSET constraints, if any */ + if( idxNum & 0x20 ){ + if( iOffset>0 ){ + pCur->ss.iBase += pCur->ss.iStep*iOffset; + } if( iLimit>=0 ){ + sqlite3_int64 iTerm; iTerm = pCur->ss.iBase + (iLimit - 1)*pCur->ss.iStep; if( pCur->ss.iStep<0 ){ if( iTerm>pCur->ss.iTerm ) pCur->ss.iTerm = iTerm; @@ -434,16 +551,21 @@ static int seriesFilter( } } } + + for(i=0; iss.iBase = 1; - pCur->ss.iTerm = 0; - pCur->ss.iStep = 1; + returnNoRows = 1; break; } } + if( returnNoRows ){ + pCur->ss.iBase = 1; + pCur->ss.iTerm = 0; + pCur->ss.iStep = 1; + } if( idxNum & 0x08 ){ pCur->ss.isReversing = pCur->ss.iStep > 0; }else{ @@ -464,13 +586,35 @@ static int seriesFilter( ** ** The query plan is represented by bits in idxNum: ** -** 0x01 start = $value -- constraint exists -** 0x02 stop = $value -- constraint exists -** 0x04 step = $value -- constraint exists -** 0x08 output is in descending order -** 0x10 output is in ascending order -** 0x20 LIMIT $value -- constraint exists -** 0x40 OFFSET $value -- constraint exists +** 0x0001 start = $num +** 0x0002 stop = $num +** 0x0004 step = $num +** 0x0008 output is in descending order +** 0x0010 output is in ascending order +** 0x0020 LIMIT $num +** 0x0040 OFFSET $num +** 0x0080 value = $num +** 0x0100 value >= $num +** 0x0200 value > $num +** 0x1000 value <= $num +** 0x2000 value < $num +** +** Only one of 0x0100 or 0x0200 will be returned. Similarly, only +** one of 0x1000 or 0x2000 will be returned. If the 0x0080 is set, then +** none of the 0xff00 bits will be set. +** +** The order of parameters passed to xFilter is as follows: +** +** * The argument to start= if bit 0x0001 is in the idxNum mask +** * The argument to stop= if bit 0x0002 is in the idxNum mask +** * The argument to step= if bit 0x0004 is in the idxNum mask +** * The argument to LIMIT if bit 0x0020 is in the idxNum mask +** * The argument to OFFSET if bit 0x0040 is in the idxNum mask +** * The argument to value=, or value>= or value> if any of +** bits 0x0380 are in the idxNum mask +** * The argument to value<= or value< if either of bits 0x3000 +** are in the mask +** */ static int seriesBestIndex( sqlite3_vtab *pVTab, @@ -483,7 +627,9 @@ static int seriesBestIndex( #endif int unusableMask = 0; /* Mask of unusable constraints */ int nArg = 0; /* Number of arguments that seriesFilter() expects */ - int aIdx[5]; /* Constraints on start, stop, step, LIMIT, OFFSET */ + int aIdx[7]; /* Constraints on start, stop, step, LIMIT, OFFSET, + ** and value. aIdx[5] covers value=, value>=, and + ** value>, aIdx[6] covers value<= and value< */ const struct sqlite3_index_constraint *pConstraint; /* This implementation assumes that the start, stop, and step columns @@ -491,7 +637,7 @@ static int seriesBestIndex( assert( SERIES_COLUMN_STOP == SERIES_COLUMN_START+1 ); assert( SERIES_COLUMN_STEP == SERIES_COLUMN_START+2 ); - aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = -1; + aIdx[0] = aIdx[1] = aIdx[2] = aIdx[3] = aIdx[4] = aIdx[5] = aIdx[6] = -1; pConstraint = pIdxInfo->aConstraint; for(i=0; inConstraint; i++, pConstraint++){ int iCol; /* 0 for start, 1 for stop, 2 for step */ @@ -512,7 +658,52 @@ static int seriesBestIndex( } continue; } - if( pConstraint->iColumniColumniColumn==SERIES_COLUMN_VALUE ){ + switch( op ){ + case SQLITE_INDEX_CONSTRAINT_EQ: + case SQLITE_INDEX_CONSTRAINT_IS: { + idxNum |= 0x0080; + idxNum &= ~0x3300; + aIdx[5] = i; + aIdx[6] = -1; + bStartSeen = 1; + break; + } + case SQLITE_INDEX_CONSTRAINT_GE: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x0100; + idxNum &= ~0x0200; + aIdx[5] = i; + bStartSeen = 1; + break; + } + case SQLITE_INDEX_CONSTRAINT_GT: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x0200; + idxNum &= ~0x0100; + aIdx[5] = i; + bStartSeen = 1; + break; + } + case SQLITE_INDEX_CONSTRAINT_LE: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x1000; + idxNum &= ~0x2000; + aIdx[6] = i; + break; + } + case SQLITE_INDEX_CONSTRAINT_LT: { + if( idxNum & 0x0080 ) break; + idxNum |= 0x2000; + idxNum &= ~0x1000; + aIdx[6] = i; + break; + } + } + } + continue; + } iCol = pConstraint->iColumn - SERIES_COLUMN_START; assert( iCol>=0 && iCol<=2 ); iMask = 1 << iCol; @@ -534,7 +725,7 @@ static int seriesBestIndex( idxNum &= ~0x60; aIdx[4] = 0; } - for(i=0; i<5; i++){ + for(i=0; i<7; i++){ if( (j = aIdx[i])>=0 ){ pIdxInfo->aConstraintUsage[j].argvIndex = ++nArg; pIdxInfo->aConstraintUsage[j].omit = @@ -560,7 +751,7 @@ static int seriesBestIndex( return SQLITE_CONSTRAINT; } if( (idxNum & 0x03)==0x03 ){ - /* Both start= and stop= boundaries are available. This is the + /* Both start= and stop= boundaries are available. This is the ** the preferred case */ pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0)); pIdxInfo->estimatedRows = 1000; @@ -582,11 +773,14 @@ static int seriesBestIndex( pIdxInfo->estimatedRows = 2147483647; } pIdxInfo->idxNum = idxNum; +#ifdef SQLITE_INDEX_SCAN_HEX + pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_HEX; +#endif return SQLITE_OK; } /* -** This following structure defines all the methods for the +** This following structure defines all the methods for the ** generate_series virtual table. */ static sqlite3_module seriesModule = { @@ -623,8 +817,8 @@ static sqlite3_module seriesModule = { __declspec(dllexport) #endif int sqlite3_series_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.c index 6a562192d5..c49041cb7f 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.c @@ -13,10 +13,10 @@ Still 100% Public Domain Corrected a problem which generated improper hash values on 16 bit machines Routine SHA1Update changed from - void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int + void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len) to - void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned + void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned long len) The 'len' parameter was declared an int which works fine on 32 bit machines. @@ -141,6 +141,7 @@ A million repetitions of "a" z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); /* Hash a single 512-bit block. This is the core of the algorithm. */ +SQLITE_PRIVATE void sha1_transform(sha1_ctx *context, const uint8_t buffer[64]) { uint32_t a, b, c, d, e; @@ -205,6 +206,7 @@ void sha1_transform(sha1_ctx *context, const uint8_t buffer[64]) * * @param context SHA1-Context */ +SQLITE_PRIVATE void sha1_init(sha1_ctx *context) { /* SHA1 initialization constants */ @@ -224,6 +226,7 @@ void sha1_init(sha1_ctx *context) * @param p Buffer to run SHA1 on * @param len Number of bytes */ +SQLITE_PRIVATE void sha1_update(sha1_ctx *context, const void *p, size_t len) { const uint8_t *data = p; @@ -259,6 +262,7 @@ void sha1_update(sha1_ctx *context, const void *p, size_t len) * @param digest Generated message digest * @param context SHA1-Context */ +SQLITE_PRIVATE void sha1_final(sha1_ctx *context, uint8_t digest[SHA1_DIGEST_SIZE]) { uint32_t i; diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.h index bf2c56aae9..844b607bb1 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha1.h @@ -4,6 +4,10 @@ #ifndef SHA1_H_ #define SHA1_H_ (1) +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + /** SHA-1 Context */ typedef struct { uint32_t h[5]; @@ -17,12 +21,12 @@ typedef struct { /** SHA-1 Digest size in bytes */ #define SHA1_DIGEST_SIZE 20 -void sha1_init(sha1_ctx *context); +SQLITE_PRIVATE void sha1_init(sha1_ctx *context); -void sha1_update(sha1_ctx *context, const void *p, size_t len); +SQLITE_PRIVATE void sha1_update(sha1_ctx *context, const void *p, size_t len); -void sha1_final(sha1_ctx *context, uint8_t digest[SHA1_DIGEST_SIZE]); +SQLITE_PRIVATE void sha1_final(sha1_ctx *context, uint8_t digest[SHA1_DIGEST_SIZE]); -void sha1_transform(sha1_ctx *context, const uint8_t buffer[64]); +SQLITE_PRIVATE void sha1_transform(sha1_ctx *context, const uint8_t buffer[64]); #endif /* SHA1_H_ */ diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.c index 587cc39556..cf1300402f 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.c @@ -131,27 +131,27 @@ wv[h] = t1 + t2; \ } -uint32 sha224_h0[8] = +static uint32 sha224_h0[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; -uint32 sha256_h0[8] = +static uint32 sha256_h0[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; -uint64 sha384_h0[8] = +static uint64 sha384_h0[8] = {li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507), li_64(9159015a3070dd17), li_64(152fecd8f70e5939), li_64(67332667ffc00b31), li_64(8eb44a8768581511), li_64(db0c2e0d64f98fa7), li_64(47b5481dbefa4fa4)}; -uint64 sha512_h0[8] = +static uint64 sha512_h0[8] = {li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b), li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1), li_64(510e527fade682d1), li_64(9b05688c2b3e6c1f), li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179)}; -uint32 sha256_k[64] = +static uint32 sha256_k[64] = {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, @@ -169,7 +169,7 @@ uint32 sha256_k[64] = 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2}; -uint64 sha512_k[80] = +static uint64 sha512_k[80] = {li_64(428a2f98d728ae22), li_64(7137449123ef65cd), li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc), li_64(3956c25bf348b538), li_64(59f111f1b605d019), @@ -329,11 +329,13 @@ void sha256_transf(sha256_ctx *ctx, const unsigned char *message, } } +SQLITE_PRIVATE void sha256_transform(sha256_ctx *ctx, const unsigned char *message) { sha256_transf(ctx, message, 1); } +SQLITE_PRIVATE void sha256(const unsigned char *message, unsigned int len, unsigned char *digest) { sha256_ctx ctx; @@ -343,6 +345,7 @@ void sha256(const unsigned char *message, unsigned int len, unsigned char *diges sha256_final(&ctx, digest); } +SQLITE_PRIVATE void sha256_init(sha256_ctx *ctx) { #ifndef UNROLL_LOOPS @@ -361,6 +364,7 @@ void sha256_init(sha256_ctx *ctx) ctx->tot_len = 0; } +SQLITE_PRIVATE void sha256_update(sha256_ctx *ctx, const unsigned char *message, unsigned int len) { @@ -395,6 +399,7 @@ void sha256_update(sha256_ctx *ctx, const unsigned char *message, ctx->tot_len += (block_nb + 1) << 6; } +SQLITE_PRIVATE void sha256_final(sha256_ctx *ctx, unsigned char *digest) { unsigned int block_nb; @@ -531,11 +536,13 @@ void sha512_transf(sha512_ctx *ctx, const unsigned char *message, } } +SQLITE_PRIVATE void sha512_transform(sha512_ctx *ctx, const unsigned char *message) { sha512_transf(ctx, message, 1); } +SQLITE_PRIVATE void sha512(const unsigned char *message, unsigned int len, unsigned char *digest) { @@ -546,6 +553,7 @@ void sha512(const unsigned char *message, unsigned int len, sha512_final(&ctx, digest); } +SQLITE_PRIVATE void sha512_init(sha512_ctx *ctx) { #ifndef UNROLL_LOOPS @@ -564,6 +572,7 @@ void sha512_init(sha512_ctx *ctx) ctx->tot_len = 0; } +SQLITE_PRIVATE void sha512_update(sha512_ctx *ctx, const unsigned char *message, unsigned int len) { @@ -598,6 +607,7 @@ void sha512_update(sha512_ctx *ctx, const unsigned char *message, ctx->tot_len += (block_nb + 1) << 7; } +SQLITE_PRIVATE void sha512_final(sha512_ctx *ctx, unsigned char *digest) { unsigned int block_nb; @@ -638,6 +648,7 @@ void sha512_final(sha512_ctx *ctx, unsigned char *digest) /* SHA-384 functions */ +SQLITE_PRIVATE void sha384(const unsigned char *message, unsigned int len, unsigned char *digest) { @@ -648,6 +659,7 @@ void sha384(const unsigned char *message, unsigned int len, sha384_final(&ctx, digest); } +SQLITE_PRIVATE void sha384_init(sha384_ctx *ctx) { #ifndef UNROLL_LOOPS @@ -666,6 +678,7 @@ void sha384_init(sha384_ctx *ctx) ctx->tot_len = 0; } +SQLITE_PRIVATE void sha384_update(sha384_ctx *ctx, const unsigned char *message, unsigned int len) { @@ -700,6 +713,7 @@ void sha384_update(sha384_ctx *ctx, const unsigned char *message, ctx->tot_len += (block_nb + 1) << 7; } +SQLITE_PRIVATE void sha384_final(sha384_ctx *ctx, unsigned char *digest) { unsigned int block_nb; @@ -738,6 +752,7 @@ void sha384_final(sha384_ctx *ctx, unsigned char *digest) /* SHA-224 functions */ +SQLITE_PRIVATE void sha224(const unsigned char *message, unsigned int len, unsigned char *digest) { @@ -748,6 +763,7 @@ void sha224(const unsigned char *message, unsigned int len, sha224_final(&ctx, digest); } +SQLITE_PRIVATE void sha224_init(sha224_ctx *ctx) { #ifndef UNROLL_LOOPS @@ -766,6 +782,7 @@ void sha224_init(sha224_ctx *ctx) ctx->tot_len = 0; } +SQLITE_PRIVATE void sha224_update(sha224_ctx *ctx, const unsigned char *message, unsigned int len) { @@ -800,6 +817,7 @@ void sha224_update(sha224_ctx *ctx, const unsigned char *message, ctx->tot_len += (block_nb + 1) << 6; } +SQLITE_PRIVATE void sha224_final(sha224_ctx *ctx, unsigned char *digest) { unsigned int block_nb; @@ -963,4 +981,3 @@ int main() } #endif /* TEST_VECTORS */ - diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.h b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.h index 4e63b26b0b..07c12c76f4 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.h +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/sha2.h @@ -34,6 +34,10 @@ #ifndef SHA2_H #define SHA2_H +#ifndef SQLITE_PRIVATE +#define SQLITE_PRIVATE +#endif + #define SHA224_DIGEST_SIZE ( 224 / 8) #define SHA256_DIGEST_SIZE ( 256 / 8) #define SHA384_DIGEST_SIZE ( 384 / 8) @@ -55,7 +59,7 @@ typedef sqlite3_uint64 uint64; #define li_64(h) 0x##h##ui64 #else #define li_64(h) 0x##h##ull -#endif +#endif #if 0 /* Start of original int64 defines */ @@ -127,35 +131,27 @@ typedef struct { typedef sha512_ctx sha384_ctx; typedef sha256_ctx sha224_ctx; -void sha224_init(sha224_ctx *ctx); -void sha224_update(sha224_ctx *ctx, const unsigned char *message, - unsigned int len); -void sha224_final(sha224_ctx *ctx, unsigned char *digest); -void sha224(const unsigned char *message, unsigned int len, - unsigned char *digest); - -void sha256_init(sha256_ctx * ctx); -void sha256_update(sha256_ctx *ctx, const unsigned char *message, - unsigned int len); -void sha256_final(sha256_ctx *ctx, unsigned char *digest); -void sha256_transform(sha256_ctx *ctx, const unsigned char *message); -void sha256(const unsigned char *message, unsigned int len, - unsigned char *digest); - -void sha384_init(sha384_ctx *ctx); -void sha384_update(sha384_ctx *ctx, const unsigned char *message, - unsigned int len); -void sha384_final(sha384_ctx *ctx, unsigned char *digest); -void sha384(const unsigned char *message, unsigned int len, - unsigned char *digest); - -void sha512_init(sha512_ctx *ctx); -void sha512_update(sha512_ctx *ctx, const unsigned char *message, - unsigned int len); -void sha512_final(sha512_ctx *ctx, unsigned char *digest); -void sha512_transform(sha512_ctx *ctx, const unsigned char *message); -void sha512(const unsigned char *message, unsigned int len, - unsigned char *digest); +SQLITE_PRIVATE void sha224_init(sha224_ctx *ctx); +SQLITE_PRIVATE void sha224_update(sha224_ctx *ctx, const unsigned char *message, unsigned int len); +SQLITE_PRIVATE void sha224_final(sha224_ctx *ctx, unsigned char *digest); +SQLITE_PRIVATE void sha224(const unsigned char *message, unsigned int len, unsigned char *digest); + +SQLITE_PRIVATE void sha256_init(sha256_ctx * ctx); +SQLITE_PRIVATE void sha256_update(sha256_ctx *ctx, const unsigned char *message, unsigned int len); +SQLITE_PRIVATE void sha256_final(sha256_ctx *ctx, unsigned char *digest); +SQLITE_PRIVATE void sha256_transform(sha256_ctx *ctx, const unsigned char *message); +SQLITE_PRIVATE void sha256(const unsigned char *message, unsigned int len, unsigned char *digest); + +SQLITE_PRIVATE void sha384_init(sha384_ctx *ctx); +SQLITE_PRIVATE void sha384_update(sha384_ctx *ctx, const unsigned char *message, unsigned int len); +SQLITE_PRIVATE void sha384_final(sha384_ctx *ctx, unsigned char *digest); +SQLITE_PRIVATE void sha384(const unsigned char *message, unsigned int len, unsigned char *digest); + +SQLITE_PRIVATE void sha512_init(sha512_ctx *ctx); +SQLITE_PRIVATE void sha512_update(sha512_ctx *ctx, const unsigned char *message, unsigned int len); +SQLITE_PRIVATE void sha512_final(sha512_ctx *ctx, unsigned char *digest); +SQLITE_PRIVATE void sha512_transform(sha512_ctx *ctx, const unsigned char *message); +SQLITE_PRIVATE void sha512(const unsigned char *message, unsigned int len, unsigned char *digest); #ifdef __cplusplus } diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shathree.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shathree.c index ba3ea581f8..b03d107d4b 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shathree.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shathree.c @@ -15,10 +15,20 @@ ** Two SQL functions are implemented: ** ** sha3(X,SIZE) -** sha3_query(Y,SIZE) +** sha3_agg(Y,SIZE) +** sha3_query(Z,SIZE) ** ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if -** X is NULL. +** X is NULL. If inputs X is text, the UTF-8 rendering of that text is +** used to compute the hash. If X is a BLOB, then the binary data of the +** blob is used to compute the hash. If X is an integer or real number, +** then that number if converted into UTF-8 text and the hash is computed +** over the text. +** +** The sha3_agg(Y) function computes the SHA3 hash of all Y inputs. Since +** order is important for the hash, it is recommended that the Y expression +** by followed by an ORDER BY clause to guarantee that the inputs occur +** in the desired order. ** ** The sha3_query(Y) function evaluates all queries in the SQL statements of Y ** and returns a hash of their results. @@ -26,6 +36,68 @@ ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm ** is used. If SIZE is included it must be one of the integers 224, 256, ** 384, or 512, to determine SHA3 hash variant that is computed. +** +** Because the sha3_agg() and sha3_query() functions compute a hash over +** multiple values, the values are encode to use include type information. +** +** In sha3_agg(), the sequence of bytes that gets hashed for each input +** Y depends on the datatype of Y: +** +** typeof(Y)='null' A single "N" is hashed. (One byte) +** +** typeof(Y)='integer' The data hash is the character "I" followed +** by an 8-byte big-endian binary of the +** 64-bit signed integer. (Nine bytes total.) +** +** typeof(Y)='real' The character "F" followed by an 8-byte +** big-ending binary of the double. (Nine +** bytes total.) +** +** typeof(Y)='text' The hash is over prefix "Tnnn:" followed +** by the UTF8 encoding of the text. The "nnn" +** in the prefix is the minimum-length decimal +** representation of the octet_length of the text. +** Notice the ":" at the end of the prefix, which +** is needed to separate the prefix from the +** content in cases where the content starts +** with a digit. +** +** typeof(Y)='blob' The hash is taken over prefix "Bnnn:" followed +** by the binary content of the blob. The "nnn" +** in the prefix is the mimimum-length decimal +** representation of the byte-length of the blob. +** +** According to the rules above, all of the following SELECT statements +** should return TRUE: +** +** SELECT sha3(1) = sha3('1'); +** +** SELECT sha3('hello') = sha3(x'68656c6c6f'); +** +** WITH a(x) AS (VALUES('xyzzy')) +** SELECT sha3_agg(x) = sha3('T5:xyzzy') FROM a; +** +** WITH a(x) AS (VALUES(x'010203')) +** SELECT sha3_agg(x) = sha3(x'42333a010203') FROM a; +** +** WITH a(x) AS (VALUES(0x123456)) +** SELECT sha3_agg(x) = sha3(x'490000000000123456') FROM a; +** +** WITH a(x) AS (VALUES(100.015625)) +** SELECT sha3_agg(x) = sha3(x'464059010000000000') FROM a; +** +** WITH a(x) AS (VALUES(NULL)) +** SELECT sha3_agg(x) = sha3('N') FROM a; +** +** +** In sha3_query(), individual column values are encoded as with +** sha3_agg(), but with the addition that a single "R" character is +** inserted at the start of each row. +** +** Note that sha3_agg() hashes rows for which Y is NULL. Add a FILTER +** clause if NULL rows should be excluded: +** +** SELECT sha3_agg(x ORDER BY rowid) FILTER(WHERE x NOT NULL) FROM t1; */ #include "sqlite3ext.h" SQLITE_EXTENSION_INIT1 @@ -75,6 +147,7 @@ struct SHA3Context { unsigned nRate; /* Bytes of input accepted per Keccak iteration */ unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ + unsigned iSize; /* 224, 256, 358, or 512 */ }; /* @@ -404,6 +477,7 @@ static void KeccakF1600Step(SHA3Context *p){ */ static void SHA3Init(SHA3Context *p, int iSize){ memset(p, 0, sizeof(*p)); + p->iSize = iSize; if( iSize>=128 && iSize<=512 ){ p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; }else{ @@ -495,7 +569,7 @@ static unsigned char *SHA3Final(SHA3Context *p){ ** Implementation of the sha3(X,SIZE) function. ** ** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default -** size is 256. If X is a BLOB, it is hashed as is. +** size is 256. If X is a BLOB, it is hashed as is. ** For all other non-NULL types of input, X is converted into a UTF-8 string ** and the string is hashed without the trailing 0x00 terminator. The hash ** of a NULL value is NULL. @@ -547,6 +621,60 @@ static void sha3_step_vformat( SHA3Update(p, (unsigned char*)zBuf, n); } +/* +** Update a SHA3Context using a single sqlite3_value. +*/ +static void sha3UpdateFromValue(SHA3Context *p, sqlite3_value *pVal){ + switch( sqlite3_value_type(pVal) ){ + case SQLITE_NULL: { + SHA3Update(p, (const unsigned char*)"N",1); + break; + } + case SQLITE_INTEGER: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + sqlite3_int64 v = sqlite3_value_int64(pVal); + memcpy(&u, &v, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'I'; + SHA3Update(p, x, 9); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + double r = sqlite3_value_double(pVal); + memcpy(&u, &r, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'F'; + SHA3Update(p,x,9); + break; + } + case SQLITE_TEXT: { + int n2 = sqlite3_value_bytes(pVal); + const unsigned char *z2 = sqlite3_value_text(pVal); + sha3_step_vformat(p,"T%d:",n2); + SHA3Update(p, z2, n2); + break; + } + case SQLITE_BLOB: { + int n2 = sqlite3_value_bytes(pVal); + const unsigned char *z2 = sqlite3_value_blob(pVal); + sha3_step_vformat(p,"B%d:",n2); + SHA3Update(p, z2, n2); + break; + } + } +} + /* ** Implementation of the sha3_query(SQL,SIZE) function. ** @@ -636,54 +764,7 @@ static void sha3QueryFunc( while( SQLITE_ROW==sqlite3_step(pStmt) ){ SHA3Update(&cx,(const unsigned char*)"R",1); for(i=0; i=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'I'; - SHA3Update(&cx, x, 9); - break; - } - case SQLITE_FLOAT: { - sqlite3_uint64 u; - int j; - unsigned char x[9]; - double r = sqlite3_column_double(pStmt,i); - memcpy(&u, &r, 8); - for(j=8; j>=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'F'; - SHA3Update(&cx,x,9); - break; - } - case SQLITE_TEXT: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_text(pStmt, i); - sha3_step_vformat(&cx,"T%d:",n2); - SHA3Update(&cx, z2, n2); - break; - } - case SQLITE_BLOB: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_blob(pStmt, i); - sha3_step_vformat(&cx,"B%d:",n2); - SHA3Update(&cx, z2, n2); - break; - } - } + sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i)); } } sqlite3_finalize(pStmt); @@ -691,6 +772,44 @@ static void sha3QueryFunc( sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); } +/* +** xStep function for sha3_agg(). +*/ +static void sha3AggStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + SHA3Context *p; + p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p)); + if( p==0 ) return; + if( p->nRate==0 ){ + int sz = 256; + if( argc==2 ){ + sz = sqlite3_value_int(argv[1]); + if( sz!=224 && sz!=384 && sz!=512 ){ + sz = 256; + } + } + SHA3Init(p, sz); + } + sha3UpdateFromValue(p, argv[0]); +} + + +/* +** xFinal function for sha3_agg(). +*/ +static void sha3AggFinal(sqlite3_context *context){ + SHA3Context *p; + p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p)); + if( p==0 ) return; + if( p->iSize ){ + sqlite3_result_blob(context, SHA3Final(p), p->iSize/8, SQLITE_TRANSIENT); + } +} + + #ifdef _WIN32 __declspec(dllexport) @@ -711,6 +830,16 @@ int sqlite3_shathree_init( SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, 0, sha3Func, 0, 0); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_agg", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, 0, sha3AggStep, sha3AggFinal); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_agg", 2, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, 0, sha3AggStep, sha3AggFinal); + } if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8 | SQLITE_DIRECTONLY, diff --git a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shell.c b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shell.c index dea16bdbd4..0d9c0a243e 100644 --- a/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shell.c +++ b/libsql-ffi/bundled/SQLite3MultipleCiphers/src/shell.c @@ -218,8 +218,6 @@ typedef unsigned char u8; # ifndef strdup # define strdup _strdup # endif -# undef popen -# define popen _popen # undef pclose # define pclose _pclose # endif @@ -263,19 +261,9 @@ extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR); extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); #endif -/* Use console I/O package as a direct INCLUDE. */ -#define SQLITE_INTERNAL_LINKAGE static - -#ifdef SQLITE_SHELL_FIDDLE -/* Deselect most features from the console I/O package for Fiddle. */ -# define SQLITE_CIO_NO_REDIRECT -# define SQLITE_CIO_NO_CLASSIFY -# define SQLITE_CIO_NO_TRANSLATE -# define SQLITE_CIO_NO_SETMODE -#endif -/************************* Begin ../ext/consio/console_io.h ******************/ +/************************* Begin ../ext/misc/sqlite3_stdio.h ******************/ /* -** 2023 November 1 +** 2024-09-24 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -284,1081 +272,432 @@ extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText); ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** -******************************************************************************** -** This file exposes various interfaces used for console and other I/O -** by the SQLite project command-line tools. These interfaces are used -** at either source conglomeration time, compilation time, or run time. -** This source provides for either inclusion into conglomerated, -** "single-source" forms or separate compilation then linking. +************************************************************************* +** +** This header file contains definitions of interfaces that provide +** cross-platform I/O for UTF-8 content. ** -** Platform dependencies are "hidden" here by various stratagems so -** that, provided certain conditions are met, the programs using this -** source or object code compiled from it need no explicit conditional -** compilation in their source for their console and stream I/O. +** On most platforms, the interfaces definitions in this file are +** just #defines. For example sqlite3_fopen() is a macro that resolves +** to the standard fopen() in the C-library. ** -** The symbols and functionality exposed here are not a public API. -** This code may change in tandem with other project code as needed. +** But Windows does not have a standard C-library, at least not one that +** can handle UTF-8. So for windows build, the interfaces resolve to new +** C-language routines contained in the separate sqlite3_stdio.c source file. ** -** When this .h file and its companion .c are directly incorporated into -** a source conglomeration (such as shell.c), the preprocessor symbol -** CIO_WIN_WC_XLATE is defined as 0 or 1, reflecting whether console I/O -** translation for Windows is effected for the build. +** So on all non-Windows platforms, simply #include this header file and +** use the interfaces defined herein. Then to run your application on Windows, +** also link in the accompanying sqlite3_stdio.c source file when compiling +** to get compatible interfaces. */ +#ifndef _SQLITE3_STDIO_H_ +#define _SQLITE3_STDIO_H_ 1 +#ifdef _WIN32 +/**** Definitions For Windows ****/ +#include +#include -#ifndef SQLITE_INTERNAL_LINKAGE -# define SQLITE_INTERNAL_LINKAGE extern /* external to translation unit */ -# include -#else -# define SHELL_NO_SYSINC /* Better yet, modify mkshellc.tcl for this. */ -#endif +FILE *sqlite3_fopen(const char *zFilename, const char *zMode); +FILE *sqlite3_popen(const char *zCommand, const char *type); +char *sqlite3_fgets(char *s, int size, FILE *stream); +int sqlite3_fputs(const char *s, FILE *stream); +int sqlite3_fprintf(FILE *stream, const char *format, ...); +void sqlite3_fsetmode(FILE *stream, int mode); -#ifndef SQLITE3_H -/* # include "sqlite3.h" */ -#endif -#ifndef SQLITE_CIO_NO_CLASSIFY +#else +/**** Definitions For All Other Platforms ****/ +#include +#define sqlite3_fopen fopen +#define sqlite3_popen popen +#define sqlite3_fgets fgets +#define sqlite3_fputs fputs +#define sqlite3_fprintf fprintf +#define sqlite3_fsetmode(F,X) /*no-op*/ -/* Define enum for use with following function. */ -typedef enum StreamsAreConsole { - SAC_NoConsole = 0, - SAC_InConsole = 1, SAC_OutConsole = 2, SAC_ErrConsole = 4, - SAC_AnyConsole = 0x7 -} StreamsAreConsole; +#endif +#endif /* _SQLITE3_STDIO_H_ */ +/************************* End ../ext/misc/sqlite3_stdio.h ********************/ +/************************* Begin ../ext/misc/sqlite3_stdio.c ******************/ /* -** Classify the three standard I/O streams according to whether -** they are connected to a console attached to the process. +** 2024-09-24 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: ** -** Returns the bit-wise OR of SAC_{In,Out,Err}Console values, -** or SAC_NoConsole if none of the streams reaches a console. +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. ** -** This function should be called before any I/O is done with -** the given streams. As a side-effect, the given inputs are -** recorded so that later I/O operations on them may be done -** differently than the C library FILE* I/O would be done, -** iff the stream is used for the I/O functions that follow, -** and to support the ones that use an implicit stream. +************************************************************************* ** -** On some platforms, stream or console mode alteration (aka -** "Setup") may be made which is undone by consoleRestore(). +** Implementation of standard I/O interfaces for UTF-8 that are missing +** on Windows. */ -SQLITE_INTERNAL_LINKAGE StreamsAreConsole -consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr ); -/* A usual call for convenience: */ -#define SQLITE_STD_CONSOLE_INIT() consoleClassifySetup(stdin,stdout,stderr) +#ifdef _WIN32 /* This file is a no-op on all platforms except Windows */ +#ifndef _SQLITE3_STDIO_H_ +/* #include "sqlite3_stdio.h" */ +#endif +#undef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +/* #include "sqlite3.h" */ +#include +#include +#include +#include /* -** After an initial call to consoleClassifySetup(...), renew -** the same setup it effected. (A call not after is an error.) -** This will restore state altered by consoleRestore(); -** -** Applications which run an inferior (child) process which -** inherits the same I/O streams may call this function after -** such a process exits to guard against console mode changes. -*/ -SQLITE_INTERNAL_LINKAGE void consoleRenewSetup(void); +** If the SQLITE_U8TEXT_ONLY option is defined, then use O_U8TEXT +** when appropriate on all output. (Sometimes use O_BINARY when +** rendering ASCII text in cases where NL-to-CRLF expansion would +** not be correct.) +** +** If the SQLITE_U8TEXT_STDIO option is defined, then use O_U8TEXT +** when appropriate when writing to stdout or stderr. Use O_BINARY +** or O_TEXT (depending on things like the .mode and the .crlf setting +** in the CLI, or other context clues in other applications) for all +** other output channels. +** +** The default behavior, if neither of the above is defined is to +** use O_U8TEXT when writing to the Windows console (or anything +** else for which _isatty() returns true) and to use O_BINARY or O_TEXT +** for all other output channels. +*/ +#if defined(SQLITE_U8TEXT_ONLY) +# define UseWtextForOutput(fd) 1 +# define UseWtextForInput(fd) 1 +# define IsConsole(fd) _isatty(_fileno(fd)) +#elif defined(SQLITE_U8TEXT_STDIO) +# define UseWtextForOutput(fd) ((fd)==stdout || (fd)==stderr) +# define UseWtextForInput(fd) ((fd)==stdin) +# define IsConsole(fd) _isatty(_fileno(fd)) +#else +# define UseWtextForOutput(fd) _isatty(_fileno(fd)) +# define UseWtextForInput(fd) _isatty(_fileno(fd)) +# define IsConsole(fd) 1 +#endif /* -** Undo any side-effects left by consoleClassifySetup(...). -** -** This should be called after consoleClassifySetup() and -** before the process terminates normally. It is suitable -** for use with the atexit() C library procedure. After -** this call, no console I/O should be done until one of -** console{Classify or Renew}Setup(...) is called again. -** -** Applications which run an inferior (child) process that -** inherits the same I/O streams might call this procedure -** before so that said process will have a console setup -** however users have configured it or come to expect. +** Global variables determine if simulated O_BINARY mode is to be +** used for stdout or other, respectively. Simulated O_BINARY mode +** means the mode is usually O_BINARY, but switches to O_U8TEXT for +** unicode characters U+0080 or greater (any character that has a +** multi-byte representation in UTF-8). This is the only way we +** have found to render Unicode characters on a Windows console while +** at the same time avoiding undesirable \n to \r\n translation. */ -SQLITE_INTERNAL_LINKAGE void SQLITE_CDECL consoleRestore( void ); +static int simBinaryStdout = 0; +static int simBinaryOther = 0; -#else /* defined(SQLITE_CIO_NO_CLASSIFY) */ -# define consoleClassifySetup(i,o,e) -# define consoleRenewSetup() -# define consoleRestore() -#endif /* defined(SQLITE_CIO_NO_CLASSIFY) */ -#ifndef SQLITE_CIO_NO_REDIRECT /* -** Set stream to be used for the functions below which write -** to "the designated X stream", where X is Output or Error. -** Returns the previous value. -** -** Alternatively, pass the special value, invalidFileStream, -** to get the designated stream value without setting it. -** -** Before the designated streams are set, they default to -** those passed to consoleClassifySetup(...), and before -** that is called they default to stdout and stderr. -** -** It is error to close a stream so designated, then, without -** designating another, use the corresponding {o,e}Emit(...). +** Determine if simulated binary mode should be used for output to fd */ -SQLITE_INTERNAL_LINKAGE FILE *invalidFileStream; -SQLITE_INTERNAL_LINKAGE FILE *setOutputStream(FILE *pf); -# ifdef CONSIO_SET_ERROR_STREAM -SQLITE_INTERNAL_LINKAGE FILE *setErrorStream(FILE *pf); -# endif -#else -# define setOutputStream(pf) -# define setErrorStream(pf) -#endif /* !defined(SQLITE_CIO_NO_REDIRECT) */ +static int UseBinaryWText(FILE *fd){ + if( fd==stdout || fd==stderr ){ + return simBinaryStdout; + }else{ + return simBinaryOther; + } +} -#ifndef SQLITE_CIO_NO_TRANSLATE -/* -** Emit output like fprintf(). If the output is going to the -** console and translation from UTF-8 is necessary, perform -** the needed translation. Otherwise, write formatted output -** to the provided stream almost as-is, possibly with newline -** translation as specified by set{Binary,Text}Mode(). -*/ -SQLITE_INTERNAL_LINKAGE int fPrintfUtf8(FILE *pfO, const char *zFormat, ...); -/* Like fPrintfUtf8 except stream is always the designated output. */ -SQLITE_INTERNAL_LINKAGE int oPrintfUtf8(const char *zFormat, ...); -/* Like fPrintfUtf8 except stream is always the designated error. */ -SQLITE_INTERNAL_LINKAGE int ePrintfUtf8(const char *zFormat, ...); /* -** Emit output like fputs(). If the output is going to the -** console and translation from UTF-8 is necessary, perform -** the needed translation. Otherwise, write given text to the -** provided stream almost as-is, possibly with newline -** translation as specified by set{Binary,Text}Mode(). +** Work-alike for the fopen() routine from the standard C library. */ -SQLITE_INTERNAL_LINKAGE int fPutsUtf8(const char *z, FILE *pfO); -/* Like fPutsUtf8 except stream is always the designated output. */ -SQLITE_INTERNAL_LINKAGE int oPutsUtf8(const char *z); -/* Like fPutsUtf8 except stream is always the designated error. */ -SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z); +FILE *sqlite3_fopen(const char *zFilename, const char *zMode){ + FILE *fp = 0; + wchar_t *b1, *b2; + int sz1, sz2; + + sz1 = (int)strlen(zFilename); + sz2 = (int)strlen(zMode); + b1 = malloc( (sz1+1)*sizeof(b1[0]) ); + b2 = malloc( (sz2+1)*sizeof(b1[0]) ); + if( b1 && b2 ){ + sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1); + b1[sz1] = 0; + sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); + b2[sz2] = 0; + fp = _wfopen(b1, b2); + } + free(b1); + free(b2); + simBinaryOther = 0; + return fp; +} -/* -** Emit output like fPutsUtf8(), except that the length of the -** accepted char or character sequence is limited by nAccept. -** -** Returns the number of accepted char values. -*/ -#ifdef CONSIO_SPUTB -SQLITE_INTERNAL_LINKAGE int -fPutbUtf8(FILE *pfOut, const char *cBuf, int nAccept); -#endif -/* Like fPutbUtf8 except stream is always the designated output. */ -SQLITE_INTERNAL_LINKAGE int -oPutbUtf8(const char *cBuf, int nAccept); -/* Like fPutbUtf8 except stream is always the designated error. */ -#ifdef CONSIO_EPUTB -SQLITE_INTERNAL_LINKAGE int -ePutbUtf8(const char *cBuf, int nAccept); -#endif /* -** Collect input like fgets(...) with special provisions for input -** from the console on platforms that require same. Defers to the -** C library fgets() when input is not from the console. Newline -** translation may be done as set by set{Binary,Text}Mode(). As a -** convenience, pfIn==NULL is treated as stdin. +** Work-alike for the popen() routine from the standard C library. */ -SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn); -/* Like fGetsUtf8 except stream is always the designated input. */ -/* SQLITE_INTERNAL_LINKAGE char* iGetsUtf8(char *cBuf, int ncMax); */ +FILE *sqlite3_popen(const char *zCommand, const char *zMode){ + FILE *fp = 0; + wchar_t *b1, *b2; + int sz1, sz2; -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ + sz1 = (int)strlen(zCommand); + sz2 = (int)strlen(zMode); + b1 = malloc( (sz1+1)*sizeof(b1[0]) ); + b2 = malloc( (sz2+1)*sizeof(b1[0]) ); + if( b1 && b2 ){ + sz1 = MultiByteToWideChar(CP_UTF8, 0, zCommand, sz1, b1, sz1); + b1[sz1] = 0; + sz2 = MultiByteToWideChar(CP_UTF8, 0, zMode, sz2, b2, sz2); + b2[sz2] = 0; + fp = _wpopen(b1, b2); + } + free(b1); + free(b2); + return fp; +} -#ifndef SQLITE_CIO_NO_SETMODE /* -** Set given stream for binary mode, where newline translation is -** not done, or for text mode where, for some platforms, newlines -** are translated to the platform's conventional char sequence. -** If bFlush true, flush the stream. -** -** An additional side-effect is that if the stream is one passed -** to consoleClassifySetup() as an output, it is flushed first. -** -** Note that binary/text mode has no effect on console I/O -** translation. On all platforms, newline to the console starts -** a new line and CR,LF chars from the console become a newline. +** Work-alike for fgets() from the standard C library. */ -SQLITE_INTERNAL_LINKAGE void setBinaryMode(FILE *, short bFlush); -SQLITE_INTERNAL_LINKAGE void setTextMode(FILE *, short bFlush); -#endif - -#ifdef SQLITE_CIO_PROMPTED_IN -typedef struct Prompts { - int numPrompts; - const char **azPrompts; -} Prompts; +char *sqlite3_fgets(char *buf, int sz, FILE *in){ + if( UseWtextForInput(in) ){ + /* When reading from the command-prompt in Windows, it is necessary + ** to use _O_WTEXT input mode to read UTF-16 characters, then translate + ** that into UTF-8. Otherwise, non-ASCII characters all get translated + ** into '?'. + */ + wchar_t *b1 = malloc( sz*sizeof(wchar_t) ); + if( b1==0 ) return 0; + _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT); + if( fgetws(b1, sz/4, in)==0 ){ + sqlite3_free(b1); + return 0; + } + WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0); + sqlite3_free(b1); + return buf; + }else{ + /* Reading from a file or other input source, just read bytes without + ** any translation. */ + return fgets(buf, sz, in); + } +} /* -** Macros for use of a line editor. -** -** The following macros define operations involving use of a -** line-editing library or simple console interaction. -** A "T" argument is a text (char *) buffer or filename. -** A "N" argument is an integer. -** -** SHELL_ADD_HISTORY(T) // Record text as line(s) of history. -** SHELL_READ_HISTORY(T) // Read history from file named by T. -** SHELL_WRITE_HISTORY(T) // Write history to file named by T. -** SHELL_STIFLE_HISTORY(N) // Limit history to N entries. -** -** A console program which does interactive console input is -** expected to call: -** SHELL_READ_HISTORY(T) before collecting such input; -** SHELL_ADD_HISTORY(T) as record-worthy input is taken; -** SHELL_STIFLE_HISTORY(N) after console input ceases; then -** SHELL_WRITE_HISTORY(T) before the program exits. +** Send ASCII text as O_BINARY. But for Unicode characters U+0080 and +** greater, switch to O_U8TEXT. */ +static void piecemealOutput(wchar_t *b1, int sz, FILE *out){ + int i; + wchar_t c; + while( sz>0 ){ + for(i=0; i=0x80; i++){} + if( i>0 ){ + c = b1[i]; + b1[i] = 0; + fflush(out); + _setmode(_fileno(out), _O_U8TEXT); + fputws(b1, out); + fflush(out); + b1 += i; + b1[0] = c; + sz -= i; + }else{ + fflush(out); + _setmode(_fileno(out), _O_TEXT); + _setmode(_fileno(out), _O_BINARY); + fwrite(&b1[0], 1, 1, out); + for(i=1; i=0 => char count, nAccept<0 => character - */ -SQLITE_INTERNAL_LINKAGE const char* -zSkipValidUtf8(const char *z, int nAccept, long ccm); - -#endif + va_start(ap, zFormat); + z = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + sqlite3_fputs(z, out); + rc = (int)strlen(z); + sqlite3_free(z); + }else{ + /* Writing to a file or other destination, just write bytes without + ** any translation. */ + va_list ap; + va_start(ap, zFormat); + rc = vfprintf(out, zFormat, ap); + va_end(ap); + } + return rc; +} -/************************* End ../ext/consio/console_io.h ********************/ -/************************* Begin ../ext/consio/console_io.c ******************/ /* -** 2023 November 4 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -******************************************************************************** -** This file implements various interfaces used for console and stream I/O -** by the SQLite project command-line tools, as explained in console_io.h . -** Functions prefixed by "SQLITE_INTERNAL_LINKAGE" behave as described there. +** Set the mode for an output stream. mode argument is typically _O_BINARY or +** _O_TEXT. */ +void sqlite3_fsetmode(FILE *fp, int mode){ + if( !UseWtextForOutput(fp) ){ + fflush(fp); + _setmode(_fileno(fp), mode); + }else if( fp==stdout || fp==stderr ){ + simBinaryStdout = (mode==_O_BINARY); + }else{ + simBinaryOther = (mode==_O_BINARY); + } +} -#ifndef SQLITE_CDECL -# define SQLITE_CDECL -#endif - -#ifndef SHELL_NO_SYSINC -# include -# include -# include -# include -# include -# include "console_io.h" -/* # include "sqlite3.h" */ -#endif +#endif /* defined(_WIN32) */ -#ifndef SQLITE_CIO_NO_TRANSLATE -# if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT -# ifndef SHELL_NO_SYSINC -# include -# include -# undef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# include -# endif -# define CIO_WIN_WC_XLATE 1 /* Use WCHAR Windows APIs for console I/O */ -# else -# ifndef SHELL_NO_SYSINC -# include -# endif -# define CIO_WIN_WC_XLATE 0 /* Use plain C library stream I/O at console */ -# endif -#else -# define CIO_WIN_WC_XLATE 0 /* Not exposing translation routines at all */ -#endif +/************************* End ../ext/misc/sqlite3_stdio.c ********************/ -#if CIO_WIN_WC_XLATE -/* Character used to represent a known-incomplete UTF-8 char group (�) */ -static WCHAR cBadGroup = 0xfffd; -#endif +/* Use console I/O package as a direct INCLUDE. */ +#define SQLITE_INTERNAL_LINKAGE static -#if CIO_WIN_WC_XLATE -static HANDLE handleOfFile(FILE *pf){ - int fileDesc = _fileno(pf); - union { intptr_t osfh; HANDLE fh; } fid = { - (fileDesc>=0)? _get_osfhandle(fileDesc) : (intptr_t)INVALID_HANDLE_VALUE - }; - return fid.fh; -} +#ifdef SQLITE_SHELL_FIDDLE +/* Deselect most features from the console I/O package for Fiddle. */ +# define SQLITE_CIO_NO_REDIRECT +# define SQLITE_CIO_NO_CLASSIFY +# define SQLITE_CIO_NO_TRANSLATE +# define SQLITE_CIO_NO_SETMODE +# define SQLITE_CIO_NO_FLUSH #endif -#ifndef SQLITE_CIO_NO_TRANSLATE -typedef struct PerStreamTags { -# if CIO_WIN_WC_XLATE - HANDLE hx; - DWORD consMode; - char acIncomplete[4]; -# else - short reachesConsole; -# endif - FILE *pf; -} PerStreamTags; - -/* Define NULL-like value for things which can validly be 0. */ -# define SHELL_INVALID_FILE_PTR ((FILE *)~0) -# if CIO_WIN_WC_XLATE -# define SHELL_INVALID_CONS_MODE 0xFFFF0000 -# endif +#define eputz(z) sqlite3_fputs(z,stderr) +#define sputz(fp,z) sqlite3_fputs(z,fp) -# if CIO_WIN_WC_XLATE -# define PST_INITIALIZER { INVALID_HANDLE_VALUE, SHELL_INVALID_CONS_MODE, \ - {0,0,0,0}, SHELL_INVALID_FILE_PTR } -# else -# define PST_INITIALIZER { 0, SHELL_INVALID_FILE_PTR } -# endif +/* True if the timer is enabled */ +static int enableTimer = 0; -/* Quickly say whether a known output is going to the console. */ -# if CIO_WIN_WC_XLATE -static short pstReachesConsole(PerStreamTags *ppst){ - return (ppst->hx != INVALID_HANDLE_VALUE); +/* A version of strcmp() that works with NULL values */ +static int cli_strcmp(const char *a, const char *b){ + if( a==0 ) a = ""; + if( b==0 ) b = ""; + return strcmp(a,b); } -# else -# define pstReachesConsole(ppst) 0 -# endif - -# if CIO_WIN_WC_XLATE -static void restoreConsoleArb(PerStreamTags *ppst){ - if( pstReachesConsole(ppst) ) SetConsoleMode(ppst->hx, ppst->consMode); +static int cli_strncmp(const char *a, const char *b, size_t n){ + if( a==0 ) a = ""; + if( b==0 ) b = ""; + return strncmp(a,b,n); } -# else -# define restoreConsoleArb(ppst) -# endif -/* Say whether FILE* appears to be a console, collect associated info. */ -static short streamOfConsole(FILE *pf, /* out */ PerStreamTags *ppst){ -# if CIO_WIN_WC_XLATE - short rv = 0; - DWORD dwCM = SHELL_INVALID_CONS_MODE; - HANDLE fh = handleOfFile(pf); - ppst->pf = pf; - if( INVALID_HANDLE_VALUE != fh ){ - rv = (GetFileType(fh) == FILE_TYPE_CHAR && GetConsoleMode(fh,&dwCM)); - } - ppst->hx = (rv)? fh : INVALID_HANDLE_VALUE; - ppst->consMode = dwCM; - return rv; -# else - ppst->pf = pf; - ppst->reachesConsole = ( (short)isatty(fileno(pf)) ); - return ppst->reachesConsole; -# endif +/* Return the current wall-clock time */ +static sqlite3_int64 timeOfDay(void){ + static sqlite3_vfs *clockVfs = 0; + sqlite3_int64 t; + if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); + if( clockVfs==0 ) return 0; /* Never actually happens */ + if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ + clockVfs->xCurrentTimeInt64(clockVfs, &t); + }else{ + double r; + clockVfs->xCurrentTime(clockVfs, &r); + t = (sqlite3_int64)(r*86400000.0); + } + return t; } -# if CIO_WIN_WC_XLATE -/* Define console modes for use with the Windows Console API. */ -# define SHELL_CONI_MODE \ - (ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | 0x80 \ - | ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS | ENABLE_PROCESSED_INPUT) -# define SHELL_CONO_MODE (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT \ - | ENABLE_VIRTUAL_TERMINAL_PROCESSING) -# endif - -typedef struct ConsoleInfo { - PerStreamTags pstSetup[3]; - PerStreamTags pstDesignated[3]; - StreamsAreConsole sacSetup; -} ConsoleInfo; - -static short isValidStreamInfo(PerStreamTags *ppst){ - return (ppst->pf != SHELL_INVALID_FILE_PTR); -} +#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) +#include +#include -static ConsoleInfo consoleInfo = { - { /* pstSetup */ PST_INITIALIZER, PST_INITIALIZER, PST_INITIALIZER }, - { /* pstDesignated[] */ PST_INITIALIZER, PST_INITIALIZER, PST_INITIALIZER }, - SAC_NoConsole /* sacSetup */ +/* VxWorks does not support getrusage() as far as we can determine */ +#if defined(_WRS_KERNEL) || defined(__RTP__) +struct rusage { + struct timeval ru_utime; /* user CPU time used */ + struct timeval ru_stime; /* system CPU time used */ }; +#define getrusage(A,B) memset(B,0,sizeof(*B)) +#endif -SQLITE_INTERNAL_LINKAGE FILE* invalidFileStream = (FILE *)~0; -# if CIO_WIN_WC_XLATE -static void maybeSetupAsConsole(PerStreamTags *ppst, short odir){ - if( pstReachesConsole(ppst) ){ - DWORD cm = odir? SHELL_CONO_MODE : SHELL_CONI_MODE; - SetConsoleMode(ppst->hx, cm); - } -} -# else -# define maybeSetupAsConsole(ppst,odir) -# endif +/* Saved resource information for the beginning of an operation */ +static struct rusage sBegin; /* CPU time at start */ +static sqlite3_int64 iBegin; /* Wall-clock time at start */ -SQLITE_INTERNAL_LINKAGE void consoleRenewSetup(void){ -# if CIO_WIN_WC_XLATE - int ix = 0; - while( ix < 6 ){ - PerStreamTags *ppst = (ix<3)? - &consoleInfo.pstSetup[ix] : &consoleInfo.pstDesignated[ix-3]; - maybeSetupAsConsole(ppst, (ix % 3)>0); - ++ix; +/* +** Begin timing an operation +*/ +static void beginTimer(void){ + if( enableTimer ){ + getrusage(RUSAGE_SELF, &sBegin); + iBegin = timeOfDay(); } -# endif } -SQLITE_INTERNAL_LINKAGE StreamsAreConsole -consoleClassifySetup( FILE *pfIn, FILE *pfOut, FILE *pfErr ){ - StreamsAreConsole rv = SAC_NoConsole; - FILE* apf[3] = { pfIn, pfOut, pfErr }; - int ix; - for( ix = 2; ix >= 0; --ix ){ - PerStreamTags *ppst = &consoleInfo.pstSetup[ix]; - if( streamOfConsole(apf[ix], ppst) ){ - rv |= (SAC_InConsole< 0 ) fflush(apf[ix]); - } - consoleInfo.sacSetup = rv; - consoleRenewSetup(); - return rv; +/* Return the difference of two time_structs in seconds */ +static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ + return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + + (double)(pEnd->tv_sec - pStart->tv_sec); } -SQLITE_INTERNAL_LINKAGE void SQLITE_CDECL consoleRestore( void ){ -# if CIO_WIN_WC_XLATE - static ConsoleInfo *pci = &consoleInfo; - if( pci->sacSetup ){ - int ix; - for( ix=0; ix<3; ++ix ){ - if( pci->sacSetup & (SAC_InConsole<pstSetup[ix]; - SetConsoleMode(ppst->hx, ppst->consMode); - } - } +/* +** Print the timing results. +*/ +static void endTimer(FILE *out){ + if( enableTimer ){ + sqlite3_int64 iEnd = timeOfDay(); + struct rusage sEnd; + getrusage(RUSAGE_SELF, &sEnd); + sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", + (iEnd - iBegin)*0.001, + timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), + timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); } -# endif } -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ -#ifdef SQLITE_CIO_INPUT_REDIR -/* Say whether given FILE* is among those known, via either -** consoleClassifySetup() or set{Output,Error}Stream, as -** readable, and return an associated PerStreamTags pointer -** if so. Otherwise, return 0. -*/ -static PerStreamTags * isKnownReadable(FILE *pf){ - static PerStreamTags *apst[] = { - &consoleInfo.pstDesignated[0], &consoleInfo.pstSetup[0], 0 - }; - int ix = 0; - do { - if( apst[ix]->pf == pf ) break; - } while( apst[++ix] != 0 ); - return apst[ix]; -} -#endif +#define BEGIN_TIMER beginTimer() +#define END_TIMER(X) endTimer(X) +#define HAS_TIMER 1 -#ifndef SQLITE_CIO_NO_TRANSLATE -/* Say whether given FILE* is among those known, via either -** consoleClassifySetup() or set{Output,Error}Stream, as -** writable, and return an associated PerStreamTags pointer -** if so. Otherwise, return 0. -*/ -static PerStreamTags * isKnownWritable(FILE *pf){ - static PerStreamTags *apst[] = { - &consoleInfo.pstDesignated[1], &consoleInfo.pstDesignated[2], - &consoleInfo.pstSetup[1], &consoleInfo.pstSetup[2], 0 - }; - int ix = 0; - do { - if( apst[ix]->pf == pf ) break; - } while( apst[++ix] != 0 ); - return apst[ix]; -} - -static FILE *designateEmitStream(FILE *pf, unsigned chix){ - FILE *rv = consoleInfo.pstDesignated[chix].pf; - if( pf == invalidFileStream ) return rv; - else{ - /* Setting a possibly new output stream. */ - PerStreamTags *ppst = isKnownWritable(pf); - if( ppst != 0 ){ - PerStreamTags pst = *ppst; - consoleInfo.pstDesignated[chix] = pst; - }else streamOfConsole(pf, &consoleInfo.pstDesignated[chix]); - } - return rv; -} - -SQLITE_INTERNAL_LINKAGE FILE *setOutputStream(FILE *pf){ - return designateEmitStream(pf, 1); -} -# ifdef CONSIO_SET_ERROR_STREAM -SQLITE_INTERNAL_LINKAGE FILE *setErrorStream(FILE *pf){ - return designateEmitStream(pf, 2); -} -# endif -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ - -#ifndef SQLITE_CIO_NO_SETMODE -# if CIO_WIN_WC_XLATE -static void setModeFlushQ(FILE *pf, short bFlush, int mode){ - if( bFlush ) fflush(pf); - _setmode(_fileno(pf), mode); -} -# else -# define setModeFlushQ(f, b, m) if(b) fflush(f) -# endif - -SQLITE_INTERNAL_LINKAGE void setBinaryMode(FILE *pf, short bFlush){ - setModeFlushQ(pf, bFlush, _O_BINARY); -} -SQLITE_INTERNAL_LINKAGE void setTextMode(FILE *pf, short bFlush){ - setModeFlushQ(pf, bFlush, _O_TEXT); -} -# undef setModeFlushQ - -#else /* defined(SQLITE_CIO_NO_SETMODE) */ -# define setBinaryMode(f, bFlush) do{ if((bFlush)) fflush(f); }while(0) -# define setTextMode(f, bFlush) do{ if((bFlush)) fflush(f); }while(0) -#endif /* defined(SQLITE_CIO_NO_SETMODE) */ - -#ifndef SQLITE_CIO_NO_TRANSLATE -# if CIO_WIN_WC_XLATE -/* Write buffer cBuf as output to stream known to reach console, -** limited to ncTake char's. Return ncTake on success, else 0. */ -static int conZstrEmit(PerStreamTags *ppst, const char *z, int ncTake){ - int rv = 0; - if( z!=NULL ){ - int nwc = MultiByteToWideChar(CP_UTF8,0, z,ncTake, 0,0); - if( nwc > 0 ){ - WCHAR *zw = sqlite3_malloc64(nwc*sizeof(WCHAR)); - if( zw!=NULL ){ - nwc = MultiByteToWideChar(CP_UTF8,0, z,ncTake, zw,nwc); - if( nwc > 0 ){ - /* Translation from UTF-8 to UTF-16, then WCHARs out. */ - if( WriteConsoleW(ppst->hx, zw,nwc, 0, NULL) ){ - rv = ncTake; - } - } - sqlite3_free(zw); - } - } - } - return rv; -} - -/* For {f,o,e}PrintfUtf8() when stream is known to reach console. */ -static int conioVmPrintf(PerStreamTags *ppst, const char *zFormat, va_list ap){ - char *z = sqlite3_vmprintf(zFormat, ap); - if( z ){ - int rv = conZstrEmit(ppst, z, (int)strlen(z)); - sqlite3_free(z); - return rv; - }else return 0; -} -# endif /* CIO_WIN_WC_XLATE */ - -# ifdef CONSIO_GET_EMIT_STREAM -static PerStreamTags * getDesignatedEmitStream(FILE *pf, unsigned chix, - PerStreamTags *ppst){ - PerStreamTags *rv = isKnownWritable(pf); - short isValid = (rv!=0)? isValidStreamInfo(rv) : 0; - if( rv != 0 && isValid ) return rv; - streamOfConsole(pf, ppst); - return ppst; -} -# endif - -/* Get stream info, either for designated output or error stream when -** chix equals 1 or 2, or for an arbitrary stream when chix == 0. -** In either case, ppst references a caller-owned PerStreamTags -** struct which may be filled in if none of the known writable -** streams is being held by consoleInfo. The ppf parameter is a -** byref output when chix!=0 and a byref input when chix==0. - */ -static PerStreamTags * -getEmitStreamInfo(unsigned chix, PerStreamTags *ppst, - /* in/out */ FILE **ppf){ - PerStreamTags *ppstTry; - FILE *pfEmit; - if( chix > 0 ){ - ppstTry = &consoleInfo.pstDesignated[chix]; - if( !isValidStreamInfo(ppstTry) ){ - ppstTry = &consoleInfo.pstSetup[chix]; - pfEmit = ppst->pf; - }else pfEmit = ppstTry->pf; - if( !isValidStreamInfo(ppstTry) ){ - pfEmit = (chix > 1)? stderr : stdout; - ppstTry = ppst; - streamOfConsole(pfEmit, ppstTry); - } - *ppf = pfEmit; - }else{ - ppstTry = isKnownWritable(*ppf); - if( ppstTry != 0 ) return ppstTry; - streamOfConsole(*ppf, ppst); - return ppst; - } - return ppstTry; -} - -SQLITE_INTERNAL_LINKAGE int oPrintfUtf8(const char *zFormat, ...){ - va_list ap; - int rv; - FILE *pfOut; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); -# else - getEmitStreamInfo(1, &pst, &pfOut); -# endif - assert(zFormat!=0); - va_start(ap, zFormat); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - rv = conioVmPrintf(ppst, zFormat, ap); - }else{ -# endif - rv = vfprintf(pfOut, zFormat, ap); -# if CIO_WIN_WC_XLATE - } -# endif - va_end(ap); - return rv; -} - -SQLITE_INTERNAL_LINKAGE int ePrintfUtf8(const char *zFormat, ...){ - va_list ap; - int rv; - FILE *pfErr; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); -# else - getEmitStreamInfo(2, &pst, &pfErr); -# endif - assert(zFormat!=0); - va_start(ap, zFormat); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - rv = conioVmPrintf(ppst, zFormat, ap); - }else{ -# endif - rv = vfprintf(pfErr, zFormat, ap); -# if CIO_WIN_WC_XLATE - } -# endif - va_end(ap); - return rv; -} - -SQLITE_INTERNAL_LINKAGE int fPrintfUtf8(FILE *pfO, const char *zFormat, ...){ - va_list ap; - int rv; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); -# else - getEmitStreamInfo(0, &pst, &pfO); -# endif - assert(zFormat!=0); - va_start(ap, zFormat); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - maybeSetupAsConsole(ppst, 1); - rv = conioVmPrintf(ppst, zFormat, ap); - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); - }else{ -# endif - rv = vfprintf(pfO, zFormat, ap); -# if CIO_WIN_WC_XLATE - } -# endif - va_end(ap); - return rv; -} - -SQLITE_INTERNAL_LINKAGE int fPutsUtf8(const char *z, FILE *pfO){ - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); -# else - getEmitStreamInfo(0, &pst, &pfO); -# endif - assert(z!=0); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - int rv; - maybeSetupAsConsole(ppst, 1); - rv = conZstrEmit(ppst, z, (int)strlen(z)); - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); - return rv; - }else { -# endif - return (fputs(z, pfO)<0)? 0 : (int)strlen(z); -# if CIO_WIN_WC_XLATE - } -# endif -} - -SQLITE_INTERNAL_LINKAGE int ePutsUtf8(const char *z){ - FILE *pfErr; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); -# else - getEmitStreamInfo(2, &pst, &pfErr); -# endif - assert(z!=0); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z)); - else { -# endif - return (fputs(z, pfErr)<0)? 0 : (int)strlen(z); -# if CIO_WIN_WC_XLATE - } -# endif -} - -SQLITE_INTERNAL_LINKAGE int oPutsUtf8(const char *z){ - FILE *pfOut; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); -# else - getEmitStreamInfo(1, &pst, &pfOut); -# endif - assert(z!=0); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ) return conZstrEmit(ppst, z, (int)strlen(z)); - else { -# endif - return (fputs(z, pfOut)<0)? 0 : (int)strlen(z); -# if CIO_WIN_WC_XLATE - } -# endif -} - -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ - -#if !(defined(SQLITE_CIO_NO_UTF8SCAN) && defined(SQLITE_CIO_NO_TRANSLATE)) -/* Skip over as much z[] input char sequence as is valid UTF-8, -** limited per nAccept char's or whole characters and containing -** no char cn such that ((1<=0 => char count, nAccept<0 => character - */ -SQLITE_INTERNAL_LINKAGE const char* -zSkipValidUtf8(const char *z, int nAccept, long ccm){ - int ng = (nAccept<0)? -nAccept : 0; - const char *pcLimit = (nAccept>=0)? z+nAccept : 0; - assert(z!=0); - while( (pcLimit)? (z= pcLimit ) return z; - else{ - char ct = *zt++; - if( ct==0 || (zt-z)>4 || (ct & 0xC0)!=0x80 ){ - /* Trailing bytes are too few, too many, or invalid. */ - return z; - } - } - } while( ((c <<= 1) & 0x40) == 0x40 ); /* Eat lead byte's count. */ - z = zt; - } - } - return z; -} -#endif /*!(defined(SQLITE_CIO_NO_UTF8SCAN)&&defined(SQLITE_CIO_NO_TRANSLATE))*/ - -#ifndef SQLITE_CIO_NO_TRANSLATE - -#ifdef CONSIO_SPUTB -SQLITE_INTERNAL_LINKAGE int -fPutbUtf8(FILE *pfO, const char *cBuf, int nAccept){ - assert(pfO!=0); -# if CIO_WIN_WC_XLATE - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ - PerStreamTags *ppst = getEmitStreamInfo(0, &pst, &pfO); - if( pstReachesConsole(ppst) ){ - int rv; - maybeSetupAsConsole(ppst, 1); - rv = conZstrEmit(ppst, cBuf, nAccept); - if( 0 == isKnownWritable(ppst->pf) ) restoreConsoleArb(ppst); - return rv; - }else { -# endif - return (int)fwrite(cBuf, 1, nAccept, pfO); -# if CIO_WIN_WC_XLATE - } -# endif -} -#endif /* defined(CONSIO_SPUTB) */ - -SQLITE_INTERNAL_LINKAGE int -oPutbUtf8(const char *cBuf, int nAccept){ - FILE *pfOut; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ -# if CIO_WIN_WC_XLATE - PerStreamTags *ppst = getEmitStreamInfo(1, &pst, &pfOut); -# else - getEmitStreamInfo(1, &pst, &pfOut); -# endif -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - return conZstrEmit(ppst, cBuf, nAccept); - }else { -# endif - return (int)fwrite(cBuf, 1, nAccept, pfOut); -# if CIO_WIN_WC_XLATE - } -# endif -} - -# ifdef CONSIO_EPUTB -SQLITE_INTERNAL_LINKAGE int -ePutbUtf8(const char *cBuf, int nAccept){ - FILE *pfErr; - PerStreamTags pst = PST_INITIALIZER; /* for unknown streams */ - PerStreamTags *ppst = getEmitStreamInfo(2, &pst, &pfErr); -# if CIO_WIN_WC_XLATE - if( pstReachesConsole(ppst) ){ - return conZstrEmit(ppst, cBuf, nAccept); - }else { -# endif - return (int)fwrite(cBuf, 1, nAccept, pfErr); -# if CIO_WIN_WC_XLATE - } -# endif -} -# endif /* defined(CONSIO_EPUTB) */ - -SQLITE_INTERNAL_LINKAGE char* fGetsUtf8(char *cBuf, int ncMax, FILE *pfIn){ - if( pfIn==0 ) pfIn = stdin; -# if CIO_WIN_WC_XLATE - if( pfIn == consoleInfo.pstSetup[0].pf - && (consoleInfo.sacSetup & SAC_InConsole)!=0 ){ -# if CIO_WIN_WC_XLATE==1 -# define SHELL_GULP 150 /* Count of WCHARS to be gulped at a time */ - WCHAR wcBuf[SHELL_GULP+1]; - int lend = 0, noc = 0; - if( ncMax > 0 ) cBuf[0] = 0; - while( noc < ncMax-8-1 && !lend ){ - /* There is room for at least 2 more characters and a 0-terminator. */ - int na = (ncMax > SHELL_GULP*4+1 + noc)? SHELL_GULP : (ncMax-1 - noc)/4; -# undef SHELL_GULP - DWORD nbr = 0; - BOOL bRC = ReadConsoleW(consoleInfo.pstSetup[0].hx, wcBuf, na, &nbr, 0); - if( bRC && nbr>0 && (wcBuf[nbr-1]&0xF800)==0xD800 ){ - /* Last WHAR read is first of a UTF-16 surrogate pair. Grab its mate. */ - DWORD nbrx; - bRC &= ReadConsoleW(consoleInfo.pstSetup[0].hx, wcBuf+nbr, 1, &nbrx, 0); - if( bRC ) nbr += nbrx; - } - if( !bRC || (noc==0 && nbr==0) ) return 0; - if( nbr > 0 ){ - int nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,0,0,0,0); - if( nmb != 0 && noc+nmb <= ncMax ){ - int iseg = noc; - nmb = WideCharToMultiByte(CP_UTF8, 0, wcBuf,nbr,cBuf+noc,nmb,0,0); - noc += nmb; - /* Fixup line-ends as coded by Windows for CR (or "Enter".) - ** This is done without regard for any setMode{Text,Binary}() - ** call that might have been done on the interactive input. - */ - if( noc > 0 ){ - if( cBuf[noc-1]=='\n' ){ - lend = 1; - if( noc > 1 && cBuf[noc-2]=='\r' ) cBuf[--noc-1] = '\n'; - } - } - /* Check for ^Z (anywhere in line) too, to act as EOF. */ - while( iseg < noc ){ - if( cBuf[iseg]=='\x1a' ){ - noc = iseg; /* Chop ^Z and anything following. */ - lend = 1; /* Counts as end of line too. */ - break; - } - ++iseg; - } - }else break; /* Drop apparent garbage in. (Could assert.) */ - }else break; - } - /* If got nothing, (after ^Z chop), must be at end-of-file. */ - if( noc > 0 ){ - cBuf[noc] = 0; - return cBuf; - }else return 0; -# endif - }else{ -# endif - return fgets(cBuf, ncMax, pfIn); -# if CIO_WIN_WC_XLATE - } -# endif -} -#endif /* !defined(SQLITE_CIO_NO_TRANSLATE) */ - -#undef SHELL_INVALID_FILE_PTR - -/************************* End ../ext/consio/console_io.c ********************/ - -#ifndef SQLITE_SHELL_FIDDLE -/* From here onward, fgets() is redirected to the console_io library. */ -# define fgets(b,n,f) fGetsUtf8(b,n,f) -/* - * Define macros for emitting output text in various ways: - * sputz(s, z) => emit 0-terminated string z to given stream s - * sputf(s, f, ...) => emit varargs per format f to given stream s - * oputz(z) => emit 0-terminated string z to default stream - * oputf(f, ...) => emit varargs per format f to default stream - * eputz(z) => emit 0-terminated string z to error stream - * eputf(f, ...) => emit varargs per format f to error stream - * oputb(b, n) => emit char buffer b[0..n-1] to default stream - * - * Note that the default stream is whatever has been last set via: - * setOutputStream(FILE *pf) - * This is normally the stream that CLI normal output goes to. - * For the stand-alone CLI, it is stdout with no .output redirect. - */ -# define sputz(s,z) fPutsUtf8(z,s) -# define sputf fPrintfUtf8 -# define oputz(z) oPutsUtf8(z) -# define oputf oPrintfUtf8 -# define eputz(z) ePutsUtf8(z) -# define eputf ePrintfUtf8 -# define oputb(buf,na) oPutbUtf8(buf,na) -#else -/* For Fiddle, all console handling and emit redirection is omitted. */ -# define sputz(fp,z) fputs(z,fp) -# define sputf(fp,fmt, ...) fprintf(fp,fmt,__VA_ARGS__) -# define oputz(z) fputs(z,stdout) -# define oputf(fmt, ...) printf(fmt,__VA_ARGS__) -# define eputz(z) fputs(z,stderr) -# define eputf(fmt, ...) fprintf(stderr,fmt,__VA_ARGS__) -# define oputb(buf,na) fwrite(buf,1,na,stdout) -#endif - -/* True if the timer is enabled */ -static int enableTimer = 0; - -/* A version of strcmp() that works with NULL values */ -static int cli_strcmp(const char *a, const char *b){ - if( a==0 ) a = ""; - if( b==0 ) b = ""; - return strcmp(a,b); -} -static int cli_strncmp(const char *a, const char *b, size_t n){ - if( a==0 ) a = ""; - if( b==0 ) b = ""; - return strncmp(a,b,n); -} - -/* Return the current wall-clock time */ -static sqlite3_int64 timeOfDay(void){ - static sqlite3_vfs *clockVfs = 0; - sqlite3_int64 t; - if( clockVfs==0 ) clockVfs = sqlite3_vfs_find(0); - if( clockVfs==0 ) return 0; /* Never actually happens */ - if( clockVfs->iVersion>=2 && clockVfs->xCurrentTimeInt64!=0 ){ - clockVfs->xCurrentTimeInt64(clockVfs, &t); - }else{ - double r; - clockVfs->xCurrentTime(clockVfs, &r); - t = (sqlite3_int64)(r*86400000.0); - } - return t; -} - -#if !defined(_WIN32) && !defined(WIN32) && !defined(__minux) -#include -#include - -/* VxWorks does not support getrusage() as far as we can determine */ -#if defined(_WRS_KERNEL) || defined(__RTP__) -struct rusage { - struct timeval ru_utime; /* user CPU time used */ - struct timeval ru_stime; /* system CPU time used */ -}; -#define getrusage(A,B) memset(B,0,sizeof(*B)) -#endif - -/* Saved resource information for the beginning of an operation */ -static struct rusage sBegin; /* CPU time at start */ -static sqlite3_int64 iBegin; /* Wall-clock time at start */ - -/* -** Begin timing an operation -*/ -static void beginTimer(void){ - if( enableTimer ){ - getrusage(RUSAGE_SELF, &sBegin); - iBegin = timeOfDay(); - } -} - -/* Return the difference of two time_structs in seconds */ -static double timeDiff(struct timeval *pStart, struct timeval *pEnd){ - return (pEnd->tv_usec - pStart->tv_usec)*0.000001 + - (double)(pEnd->tv_sec - pStart->tv_sec); -} - -/* -** Print the timing results. -*/ -static void endTimer(void){ - if( enableTimer ){ - sqlite3_int64 iEnd = timeOfDay(); - struct rusage sEnd; - getrusage(RUSAGE_SELF, &sEnd); - oputf("Run Time: real %.3f user %f sys %f\n", - (iEnd - iBegin)*0.001, - timeDiff(&sBegin.ru_utime, &sEnd.ru_utime), - timeDiff(&sBegin.ru_stime, &sEnd.ru_stime)); - } -} - -#define BEGIN_TIMER beginTimer() -#define END_TIMER endTimer() -#define HAS_TIMER 1 - -#elif (defined(_WIN32) || defined(WIN32)) +#elif (defined(_WIN32) || defined(WIN32)) /* Saved resource information for the beginning of an operation */ static HANDLE hProcess; @@ -1421,12 +760,12 @@ static double timeDiff(FILETIME *pStart, FILETIME *pEnd){ /* ** Print the timing results. */ -static void endTimer(void){ +static void endTimer(FILE *out){ if( enableTimer && getProcessTimesAddr){ FILETIME ftCreation, ftExit, ftKernelEnd, ftUserEnd; sqlite3_int64 ftWallEnd = timeOfDay(); getProcessTimesAddr(hProcess,&ftCreation,&ftExit,&ftKernelEnd,&ftUserEnd); - oputf("Run Time: real %.3f user %f sys %f\n", + sqlite3_fprintf(out, "Run Time: real %.3f user %f sys %f\n", (ftWallEnd - ftWallBegin)*0.001, timeDiff(&ftUserBegin, &ftUserEnd), timeDiff(&ftKernelBegin, &ftKernelEnd)); @@ -1434,12 +773,12 @@ static void endTimer(void){ } #define BEGIN_TIMER beginTimer() -#define END_TIMER endTimer() +#define END_TIMER(X) endTimer(X) #define HAS_TIMER hasTimer() #else #define BEGIN_TIMER -#define END_TIMER +#define END_TIMER(X) /*no-op*/ #define HAS_TIMER 0 #endif @@ -1512,6 +851,14 @@ static char *shell_strncpy(char *dest, const char *src, size_t n){ return dest; } +/* +** strcpy() workalike to squelch an unwarranted link-time warning +** from OpenBSD. +*/ +static void shell_strcpy(char *dest, const char *src){ + while( (*(dest++) = *(src++))!=0 ){} +} + /* ** Optionally disable dynamic continuation prompt. ** Unless disabled, the continuation prompt shows open SQL lexemes if any, @@ -1577,7 +924,7 @@ static char *dynamicContinuePrompt(void){ size_t ncp = strlen(continuePrompt); size_t ndp = strlen(dynPrompt.zScannerAwaits); if( ndp > ncp-3 ) return continuePrompt; - strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits); + shell_strcpy(dynPrompt.dynamicPrompt, dynPrompt.zScannerAwaits); while( ndp<3 ) dynPrompt.dynamicPrompt[ndp++] = ' '; shell_strncpy(dynPrompt.dynamicPrompt+3, continuePrompt+3, PROMPT_LEN_MAX-4); @@ -1632,37 +979,212 @@ static void SQLITE_CDECL iotracePrintf(const char *zFormat, ...){ va_start(ap, zFormat); z = sqlite3_vmprintf(zFormat, ap); va_end(ap); - sputf(iotrace, "%s", z); + sqlite3_fprintf(iotrace, "%s", z); sqlite3_free(z); } #endif +/* Lookup table to estimate the number of columns consumed by a Unicode +** character. +*/ +static const struct { + unsigned char w; /* Width of the character in columns */ + int iFirst; /* First character in a span having this width */ +} aUWidth[] = { + /* {1, 0x00000}, */ + {0, 0x00300}, {1, 0x00370}, {0, 0x00483}, {1, 0x00487}, {0, 0x00488}, + {1, 0x0048a}, {0, 0x00591}, {1, 0x005be}, {0, 0x005bf}, {1, 0x005c0}, + {0, 0x005c1}, {1, 0x005c3}, {0, 0x005c4}, {1, 0x005c6}, {0, 0x005c7}, + {1, 0x005c8}, {0, 0x00600}, {1, 0x00604}, {0, 0x00610}, {1, 0x00616}, + {0, 0x0064b}, {1, 0x0065f}, {0, 0x00670}, {1, 0x00671}, {0, 0x006d6}, + {1, 0x006e5}, {0, 0x006e7}, {1, 0x006e9}, {0, 0x006ea}, {1, 0x006ee}, + {0, 0x0070f}, {1, 0x00710}, {0, 0x00711}, {1, 0x00712}, {0, 0x00730}, + {1, 0x0074b}, {0, 0x007a6}, {1, 0x007b1}, {0, 0x007eb}, {1, 0x007f4}, + {0, 0x00901}, {1, 0x00903}, {0, 0x0093c}, {1, 0x0093d}, {0, 0x00941}, + {1, 0x00949}, {0, 0x0094d}, {1, 0x0094e}, {0, 0x00951}, {1, 0x00955}, + {0, 0x00962}, {1, 0x00964}, {0, 0x00981}, {1, 0x00982}, {0, 0x009bc}, + {1, 0x009bd}, {0, 0x009c1}, {1, 0x009c5}, {0, 0x009cd}, {1, 0x009ce}, + {0, 0x009e2}, {1, 0x009e4}, {0, 0x00a01}, {1, 0x00a03}, {0, 0x00a3c}, + {1, 0x00a3d}, {0, 0x00a41}, {1, 0x00a43}, {0, 0x00a47}, {1, 0x00a49}, + {0, 0x00a4b}, {1, 0x00a4e}, {0, 0x00a70}, {1, 0x00a72}, {0, 0x00a81}, + {1, 0x00a83}, {0, 0x00abc}, {1, 0x00abd}, {0, 0x00ac1}, {1, 0x00ac6}, + {0, 0x00ac7}, {1, 0x00ac9}, {0, 0x00acd}, {1, 0x00ace}, {0, 0x00ae2}, + {1, 0x00ae4}, {0, 0x00b01}, {1, 0x00b02}, {0, 0x00b3c}, {1, 0x00b3d}, + {0, 0x00b3f}, {1, 0x00b40}, {0, 0x00b41}, {1, 0x00b44}, {0, 0x00b4d}, + {1, 0x00b4e}, {0, 0x00b56}, {1, 0x00b57}, {0, 0x00b82}, {1, 0x00b83}, + {0, 0x00bc0}, {1, 0x00bc1}, {0, 0x00bcd}, {1, 0x00bce}, {0, 0x00c3e}, + {1, 0x00c41}, {0, 0x00c46}, {1, 0x00c49}, {0, 0x00c4a}, {1, 0x00c4e}, + {0, 0x00c55}, {1, 0x00c57}, {0, 0x00cbc}, {1, 0x00cbd}, {0, 0x00cbf}, + {1, 0x00cc0}, {0, 0x00cc6}, {1, 0x00cc7}, {0, 0x00ccc}, {1, 0x00cce}, + {0, 0x00ce2}, {1, 0x00ce4}, {0, 0x00d41}, {1, 0x00d44}, {0, 0x00d4d}, + {1, 0x00d4e}, {0, 0x00dca}, {1, 0x00dcb}, {0, 0x00dd2}, {1, 0x00dd5}, + {0, 0x00dd6}, {1, 0x00dd7}, {0, 0x00e31}, {1, 0x00e32}, {0, 0x00e34}, + {1, 0x00e3b}, {0, 0x00e47}, {1, 0x00e4f}, {0, 0x00eb1}, {1, 0x00eb2}, + {0, 0x00eb4}, {1, 0x00eba}, {0, 0x00ebb}, {1, 0x00ebd}, {0, 0x00ec8}, + {1, 0x00ece}, {0, 0x00f18}, {1, 0x00f1a}, {0, 0x00f35}, {1, 0x00f36}, + {0, 0x00f37}, {1, 0x00f38}, {0, 0x00f39}, {1, 0x00f3a}, {0, 0x00f71}, + {1, 0x00f7f}, {0, 0x00f80}, {1, 0x00f85}, {0, 0x00f86}, {1, 0x00f88}, + {0, 0x00f90}, {1, 0x00f98}, {0, 0x00f99}, {1, 0x00fbd}, {0, 0x00fc6}, + {1, 0x00fc7}, {0, 0x0102d}, {1, 0x01031}, {0, 0x01032}, {1, 0x01033}, + {0, 0x01036}, {1, 0x01038}, {0, 0x01039}, {1, 0x0103a}, {0, 0x01058}, + {1, 0x0105a}, {2, 0x01100}, {0, 0x01160}, {1, 0x01200}, {0, 0x0135f}, + {1, 0x01360}, {0, 0x01712}, {1, 0x01715}, {0, 0x01732}, {1, 0x01735}, + {0, 0x01752}, {1, 0x01754}, {0, 0x01772}, {1, 0x01774}, {0, 0x017b4}, + {1, 0x017b6}, {0, 0x017b7}, {1, 0x017be}, {0, 0x017c6}, {1, 0x017c7}, + {0, 0x017c9}, {1, 0x017d4}, {0, 0x017dd}, {1, 0x017de}, {0, 0x0180b}, + {1, 0x0180e}, {0, 0x018a9}, {1, 0x018aa}, {0, 0x01920}, {1, 0x01923}, + {0, 0x01927}, {1, 0x01929}, {0, 0x01932}, {1, 0x01933}, {0, 0x01939}, + {1, 0x0193c}, {0, 0x01a17}, {1, 0x01a19}, {0, 0x01b00}, {1, 0x01b04}, + {0, 0x01b34}, {1, 0x01b35}, {0, 0x01b36}, {1, 0x01b3b}, {0, 0x01b3c}, + {1, 0x01b3d}, {0, 0x01b42}, {1, 0x01b43}, {0, 0x01b6b}, {1, 0x01b74}, + {0, 0x01dc0}, {1, 0x01dcb}, {0, 0x01dfe}, {1, 0x01e00}, {0, 0x0200b}, + {1, 0x02010}, {0, 0x0202a}, {1, 0x0202f}, {0, 0x02060}, {1, 0x02064}, + {0, 0x0206a}, {1, 0x02070}, {0, 0x020d0}, {1, 0x020f0}, {2, 0x02329}, + {1, 0x0232b}, {2, 0x02e80}, {0, 0x0302a}, {2, 0x03030}, {1, 0x0303f}, + {2, 0x03040}, {0, 0x03099}, {2, 0x0309b}, {1, 0x0a4d0}, {0, 0x0a806}, + {1, 0x0a807}, {0, 0x0a80b}, {1, 0x0a80c}, {0, 0x0a825}, {1, 0x0a827}, + {2, 0x0ac00}, {1, 0x0d7a4}, {2, 0x0f900}, {1, 0x0fb00}, {0, 0x0fb1e}, + {1, 0x0fb1f}, {0, 0x0fe00}, {2, 0x0fe10}, {1, 0x0fe1a}, {0, 0x0fe20}, + {1, 0x0fe24}, {2, 0x0fe30}, {1, 0x0fe70}, {0, 0x0feff}, {2, 0x0ff00}, + {1, 0x0ff61}, {2, 0x0ffe0}, {1, 0x0ffe7}, {0, 0x0fff9}, {1, 0x0fffc}, + {0, 0x10a01}, {1, 0x10a04}, {0, 0x10a05}, {1, 0x10a07}, {0, 0x10a0c}, + {1, 0x10a10}, {0, 0x10a38}, {1, 0x10a3b}, {0, 0x10a3f}, {1, 0x10a40}, + {0, 0x1d167}, {1, 0x1d16a}, {0, 0x1d173}, {1, 0x1d183}, {0, 0x1d185}, + {1, 0x1d18c}, {0, 0x1d1aa}, {1, 0x1d1ae}, {0, 0x1d242}, {1, 0x1d245}, + {2, 0x20000}, {1, 0x2fffe}, {2, 0x30000}, {1, 0x3fffe}, {0, 0xe0001}, + {1, 0xe0002}, {0, 0xe0020}, {1, 0xe0080}, {0, 0xe0100}, {1, 0xe01f0} +}; + /* -** Output string zUtf to Out stream as w characters. If w is negative, -** then right-justify the text. W is the width in UTF-8 characters, not -** in bytes. This is different from the %*.*s specification in printf -** since with %*.*s the width is measured in bytes, not characters. +** Return an estimate of the width, in columns, for the single Unicode +** character c. For normal characters, the answer is always 1. But the +** estimate might be 0 or 2 for zero-width and double-width characters. +** +** Different display devices display unicode using different widths. So +** it is impossible to know that true display width with 100% accuracy. +** Inaccuracies in the width estimates might cause columns to be misaligned. +** Unfortunately, there is nothing we can do about that. */ -static void utf8_width_print(int w, const char *zUtf){ - int i; - int n; - int aw = w<0 ? -w : w; - if( zUtf==0 ) zUtf = ""; - for(i=n=0; zUtf[i]; i++){ - if( (zUtf[i]&0xc0)!=0x80 ){ - n++; - if( n==aw ){ - do{ i++; }while( (zUtf[i]&0xc0)==0x80 ); +int cli_wcwidth(int c){ + int iFirst, iLast; + + /* Fast path for common characters */ + if( c<=0x300 ) return 1; + + /* The general case */ + iFirst = 0; + iLast = sizeof(aUWidth)/sizeof(aUWidth[0]) - 1; + while( iFirst c ){ + iLast = iMid - 1; + }else{ + return aUWidth[iMid].w; + } + } + if( aUWidth[iLast].iFirst > c ) return aUWidth[iFirst].w; + return aUWidth[iLast].w; +} + +/* +** Compute the value and length of a multi-byte UTF-8 character that +** begins at z[0]. Return the length. Write the Unicode value into *pU. +** +** This routine only works for *multi-byte* UTF-8 characters. +*/ +static int decodeUtf8(const unsigned char *z, int *pU){ + if( (z[0] & 0xe0)==0xc0 && (z[1] & 0xc0)==0x80 ){ + *pU = ((z[0] & 0x1f)<<6) | (z[1] & 0x3f); + return 2; + } + if( (z[0] & 0xf0)==0xe0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 ){ + *pU = ((z[0] & 0x0f)<<12) | ((z[1] & 0x3f)<<6) | (z[2] & 0x3f); + return 3; + } + if( (z[0] & 0xf8)==0xf0 && (z[1] & 0xc0)==0x80 && (z[2] & 0xc0)==0x80 + && (z[3] & 0xc0)==0x80 + ){ + *pU = ((z[0] & 0x0f)<<18) | ((z[1] & 0x3f)<<12) | ((z[2] & 0x3f))<<6 + | (z[4] & 0x3f); + return 4; + } + *pU = 0; + return 1; +} + + +#if 0 /* NOT USED */ +/* +** Return the width, in display columns, of a UTF-8 string. +** +** Each normal character counts as 1. Zero-width characters count +** as zero, and double-width characters count as 2. +*/ +int cli_wcswidth(const char *z){ + const unsigned char *a = (const unsigned char*)z; + int n = 0; + int i = 0; + unsigned char c; + while( (c = a[i])!=0 ){ + if( c>=0xc0 ){ + int u; + int len = decodeUtf8(&a[i], &u); + i += len; + n += cli_wcwidth(u); + }else if( c>=' ' ){ + n++; + i++; + }else{ + i++; + } + } + return n; +} +#endif + +/* +** Output string zUtf to stdout as w characters. If w is negative, +** then right-justify the text. W is the width in UTF-8 characters, not +** in bytes. This is different from the %*.*s specification in printf +** since with %*.*s the width is measured in bytes, not characters. +** +** Take into account zero-width and double-width Unicode characters. +** In other words, a zero-width character does not count toward the +** the w limit. A double-width character counts as two. +*/ +static void utf8_width_print(FILE *out, int w, const char *zUtf){ + const unsigned char *a = (const unsigned char*)zUtf; + unsigned char c; + int i = 0; + int n = 0; + int aw = w<0 ? -w : w; + if( zUtf==0 ) zUtf = ""; + while( (c = a[i])!=0 ){ + if( (c&0xc0)==0xc0 ){ + int u; + int len = decodeUtf8(a+i, &u); + int x = cli_wcwidth(u); + if( x+n>aw ){ break; } + i += len; + n += x; + }else if( n>=aw ){ + break; + }else{ + n++; + i++; } } if( n>=aw ){ - oputf("%.*s", i, zUtf); + sqlite3_fprintf(out, "%.*s", i, zUtf); }else if( w<0 ){ - oputf("%*s%s", aw-n, "", zUtf); + sqlite3_fprintf(out, "%*s%s", aw-n, "", zUtf); }else{ - oputf("%s%*s", zUtf, aw-n, ""); + sqlite3_fprintf(out, "%s%*s", zUtf, aw-n, ""); } } @@ -1723,14 +1245,14 @@ static int strlenChar(const char *z){ */ static FILE * openChrSource(const char *zFile){ #if defined(_WIN32) || defined(WIN32) - struct _stat x = {0}; + struct __stat64 x = {0}; # define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0) /* On Windows, open first, then check the stream nature. This order ** is necessary because _stat() and sibs, when checking a named pipe, ** effectively break the pipe as its supplier sees it. */ - FILE *rv = fopen(zFile, "rb"); + FILE *rv = sqlite3_fopen(zFile, "rb"); if( rv==0 ) return 0; - if( _fstat(_fileno(rv), &x) != 0 + if( _fstat64(_fileno(rv), &x) != 0 || !STAT_CHR_SRC(x.st_mode)){ fclose(rv); rv = 0; @@ -1742,7 +1264,7 @@ static FILE * openChrSource(const char *zFile){ # define STAT_CHR_SRC(mode) (S_ISREG(mode)||S_ISFIFO(mode)||S_ISCHR(mode)) if( rc!=0 ) return 0; if( STAT_CHR_SRC(x.st_mode) ){ - return fopen(zFile, "rb"); + return sqlite3_fopen(zFile, "rb"); }else{ return 0; } @@ -1769,7 +1291,7 @@ static char *local_getline(char *zLine, FILE *in){ zLine = realloc(zLine, nLine); shell_check_oom(zLine); } - if( fgets(&zLine[n], nLine - n, in)==0 ){ + if( sqlite3_fgets(&zLine[n], nLine - n, in)==0 ){ if( n==0 ){ free(zLine); return 0; @@ -2562,7 +2084,7 @@ static FILE *memtraceOut; /* Methods that trace memory allocations */ static void *memtraceMalloc(int n){ if( memtraceOut ){ - fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n", + fprintf(memtraceOut, "MEMTRACE: allocate %d bytes\n", memtraceBase.xRoundup(n)); } return memtraceBase.xMalloc(n); @@ -2838,10 +2360,20 @@ int sqlite3PcacheTraceDeactivate(void){ ** Two SQL functions are implemented: ** ** sha3(X,SIZE) -** sha3_query(Y,SIZE) +** sha3_agg(Y,SIZE) +** sha3_query(Z,SIZE) ** ** The sha3(X) function computes the SHA3 hash of the input X, or NULL if -** X is NULL. +** X is NULL. If inputs X is text, the UTF-8 rendering of that text is +** used to compute the hash. If X is a BLOB, then the binary data of the +** blob is used to compute the hash. If X is an integer or real number, +** then that number if converted into UTF-8 text and the hash is computed +** over the text. +** +** The sha3_agg(Y) function computes the SHA3 hash of all Y inputs. Since +** order is important for the hash, it is recommended that the Y expression +** by followed by an ORDER BY clause to guarantee that the inputs occur +** in the desired order. ** ** The sha3_query(Y) function evaluates all queries in the SQL statements of Y ** and returns a hash of their results. @@ -2849,6 +2381,68 @@ int sqlite3PcacheTraceDeactivate(void){ ** The SIZE argument is optional. If omitted, the SHA3-256 hash algorithm ** is used. If SIZE is included it must be one of the integers 224, 256, ** 384, or 512, to determine SHA3 hash variant that is computed. +** +** Because the sha3_agg() and sha3_query() functions compute a hash over +** multiple values, the values are encode to use include type information. +** +** In sha3_agg(), the sequence of bytes that gets hashed for each input +** Y depends on the datatype of Y: +** +** typeof(Y)='null' A single "N" is hashed. (One byte) +** +** typeof(Y)='integer' The data hash is the character "I" followed +** by an 8-byte big-endian binary of the +** 64-bit signed integer. (Nine bytes total.) +** +** typeof(Y)='real' The character "F" followed by an 8-byte +** big-ending binary of the double. (Nine +** bytes total.) +** +** typeof(Y)='text' The hash is over prefix "Tnnn:" followed +** by the UTF8 encoding of the text. The "nnn" +** in the prefix is the minimum-length decimal +** representation of the octet_length of the text. +** Notice the ":" at the end of the prefix, which +** is needed to separate the prefix from the +** content in cases where the content starts +** with a digit. +** +** typeof(Y)='blob' The hash is taken over prefix "Bnnn:" followed +** by the binary content of the blob. The "nnn" +** in the prefix is the mimimum-length decimal +** representation of the byte-length of the blob. +** +** According to the rules above, all of the following SELECT statements +** should return TRUE: +** +** SELECT sha3(1) = sha3('1'); +** +** SELECT sha3('hello') = sha3(x'68656c6c6f'); +** +** WITH a(x) AS (VALUES('xyzzy')) +** SELECT sha3_agg(x) = sha3('T5:xyzzy') FROM a; +** +** WITH a(x) AS (VALUES(x'010203')) +** SELECT sha3_agg(x) = sha3(x'42333a010203') FROM a; +** +** WITH a(x) AS (VALUES(0x123456)) +** SELECT sha3_agg(x) = sha3(x'490000000000123456') FROM a; +** +** WITH a(x) AS (VALUES(100.015625)) +** SELECT sha3_agg(x) = sha3(x'464059010000000000') FROM a; +** +** WITH a(x) AS (VALUES(NULL)) +** SELECT sha3_agg(x) = sha3('N') FROM a; +** +** +** In sha3_query(), individual column values are encoded as with +** sha3_agg(), but with the addition that a single "R" character is +** inserted at the start of each row. +** +** Note that sha3_agg() hashes rows for which Y is NULL. Add a FILTER +** clause if NULL rows should be excluded: +** +** SELECT sha3_agg(x ORDER BY rowid) FILTER(WHERE x NOT NULL) FROM t1; */ /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 @@ -2898,6 +2492,7 @@ struct SHA3Context { unsigned nRate; /* Bytes of input accepted per Keccak iteration */ unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ + unsigned iSize; /* 224, 256, 358, or 512 */ }; /* @@ -3227,6 +2822,7 @@ static void KeccakF1600Step(SHA3Context *p){ */ static void SHA3Init(SHA3Context *p, int iSize){ memset(p, 0, sizeof(*p)); + p->iSize = iSize; if( iSize>=128 && iSize<=512 ){ p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; }else{ @@ -3318,7 +2914,7 @@ static unsigned char *SHA3Final(SHA3Context *p){ ** Implementation of the sha3(X,SIZE) function. ** ** Return a BLOB which is the SIZE-bit SHA3 hash of X. The default -** size is 256. If X is a BLOB, it is hashed as is. +** size is 256. If X is a BLOB, it is hashed as is. ** For all other non-NULL types of input, X is converted into a UTF-8 string ** and the string is hashed without the trailing 0x00 terminator. The hash ** of a NULL value is NULL. @@ -3370,6 +2966,60 @@ static void sha3_step_vformat( SHA3Update(p, (unsigned char*)zBuf, n); } +/* +** Update a SHA3Context using a single sqlite3_value. +*/ +static void sha3UpdateFromValue(SHA3Context *p, sqlite3_value *pVal){ + switch( sqlite3_value_type(pVal) ){ + case SQLITE_NULL: { + SHA3Update(p, (const unsigned char*)"N",1); + break; + } + case SQLITE_INTEGER: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + sqlite3_int64 v = sqlite3_value_int64(pVal); + memcpy(&u, &v, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'I'; + SHA3Update(p, x, 9); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + double r = sqlite3_value_double(pVal); + memcpy(&u, &r, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'F'; + SHA3Update(p,x,9); + break; + } + case SQLITE_TEXT: { + int n2 = sqlite3_value_bytes(pVal); + const unsigned char *z2 = sqlite3_value_text(pVal); + sha3_step_vformat(p,"T%d:",n2); + SHA3Update(p, z2, n2); + break; + } + case SQLITE_BLOB: { + int n2 = sqlite3_value_bytes(pVal); + const unsigned char *z2 = sqlite3_value_blob(pVal); + sha3_step_vformat(p,"B%d:",n2); + SHA3Update(p, z2, n2); + break; + } + } +} + /* ** Implementation of the sha3_query(SQL,SIZE) function. ** @@ -3459,54 +3109,7 @@ static void sha3QueryFunc( while( SQLITE_ROW==sqlite3_step(pStmt) ){ SHA3Update(&cx,(const unsigned char*)"R",1); for(i=0; i=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'I'; - SHA3Update(&cx, x, 9); - break; - } - case SQLITE_FLOAT: { - sqlite3_uint64 u; - int j; - unsigned char x[9]; - double r = sqlite3_column_double(pStmt,i); - memcpy(&u, &r, 8); - for(j=8; j>=1; j--){ - x[j] = u & 0xff; - u >>= 8; - } - x[0] = 'F'; - SHA3Update(&cx,x,9); - break; - } - case SQLITE_TEXT: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_text(pStmt, i); - sha3_step_vformat(&cx,"T%d:",n2); - SHA3Update(&cx, z2, n2); - break; - } - case SQLITE_BLOB: { - int n2 = sqlite3_column_bytes(pStmt, i); - const unsigned char *z2 = sqlite3_column_blob(pStmt, i); - sha3_step_vformat(&cx,"B%d:",n2); - SHA3Update(&cx, z2, n2); - break; - } - } + sha3UpdateFromValue(&cx, sqlite3_column_value(pStmt,i)); } } sqlite3_finalize(pStmt); @@ -3514,6 +3117,44 @@ static void sha3QueryFunc( sqlite3_result_blob(context, SHA3Final(&cx), iSize/8, SQLITE_TRANSIENT); } +/* +** xStep function for sha3_agg(). +*/ +static void sha3AggStep( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + SHA3Context *p; + p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p)); + if( p==0 ) return; + if( p->nRate==0 ){ + int sz = 256; + if( argc==2 ){ + sz = sqlite3_value_int(argv[1]); + if( sz!=224 && sz!=384 && sz!=512 ){ + sz = 256; + } + } + SHA3Init(p, sz); + } + sha3UpdateFromValue(p, argv[0]); +} + + +/* +** xFinal function for sha3_agg(). +*/ +static void sha3AggFinal(sqlite3_context *context){ + SHA3Context *p; + p = (SHA3Context*)sqlite3_aggregate_context(context, sizeof(*p)); + if( p==0 ) return; + if( p->iSize ){ + sqlite3_result_blob(context, SHA3Final(p), p->iSize/8, SQLITE_TRANSIENT); + } +} + + #ifdef _WIN32 @@ -3534,6 +3175,16 @@ int sqlite3_shathree_init( SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, 0, sha3Func, 0, 0); } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_agg", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, 0, sha3AggStep, sha3AggFinal); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha3_agg", 2, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, 0, sha3AggStep, sha3AggFinal); + } if( rc==SQLITE_OK ){ rc = sqlite3_create_function(db, "sha3_query", 1, SQLITE_UTF8 | SQLITE_DIRECTONLY, @@ -3548,9 +3199,9 @@ int sqlite3_shathree_init( } /************************* End ../ext/misc/shathree.c ********************/ -/************************* Begin ../ext/misc/uint.c ******************/ +/************************* Begin ../ext/misc/sha1.c ******************/ /* -** 2020-04-14 +** 2017-01-27 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -3561,92 +3212,504 @@ int sqlite3_shathree_init( ** ****************************************************************************** ** -** This SQLite extension implements the UINT collating sequence. -** -** UINT works like BINARY for text, except that embedded strings -** of digits compare in numeric order. +** This SQLite extension implements functions that compute SHA1 hashes. +** Two SQL functions are implemented: ** -** * Leading zeros are handled properly, in the sense that -** they do not mess of the maginitude comparison of embedded -** strings of digits. "x00123y" is equal to "x123y". +** sha1(X) +** sha1_query(Y) ** -** * Only unsigned integers are recognized. Plus and minus -** signs are ignored. Decimal points and exponential notation -** are ignored. +** The sha1(X) function computes the SHA1 hash of the input X, or NULL if +** X is NULL. ** -** * Embedded integers can be of arbitrary length. Comparison -** is *not* limited integers that can be expressed as a -** 64-bit machine integer. +** The sha1_query(Y) function evalutes all queries in the SQL statements of Y +** and returns a hash of their results. */ /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #include #include -#include +#include -/* -** Compare text in lexicographic order, except strings of digits -** compare in numeric order. +/****************************************************************************** +** The Hash Engine */ -static int uintCollFunc( - void *notUsed, - int nKey1, const void *pKey1, - int nKey2, const void *pKey2 +/* Context for the SHA1 hash */ +typedef struct SHA1Context SHA1Context; +struct SHA1Context { + unsigned int state[5]; + unsigned int count[2]; + unsigned char buffer[64]; +}; + +#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) +#define rol(x,k) SHA_ROT(x,k,32-(k)) +#define ror(x,k) SHA_ROT(x,32-(k),k) + +#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ + |(rol(block[i],8)&0x00FF00FF)) +#define blk0be(i) block[i] +#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ + ^block[(i+2)&15]^block[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + * + * Rl0() for little-endian and Rb0() for big-endian. Endianness is + * determined at run-time. + */ +#define Rl0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define Rb0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R1(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R2(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2); +#define R3(v,w,x,y,z,i) \ + z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2); +#define R4(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +static void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]){ + unsigned int qq[5]; /* a, b, c, d, e; */ + static int one = 1; + unsigned int block[16]; + memcpy(block, buffer, 64); + memcpy(qq,state,5*sizeof(unsigned int)); + +#define a qq[0] +#define b qq[1] +#define c qq[2] +#define d qq[3] +#define e qq[4] + + /* Copy p->state[] to working vars */ + /* + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + */ + + /* 4 rounds of 20 operations each. Loop unrolled. */ + if( 1 == *(unsigned char*)&one ){ + Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3); + Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7); + Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11); + Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15); + }else{ + Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3); + Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7); + Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11); + Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15); + } + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + +#undef a +#undef b +#undef c +#undef d +#undef e +} + + +/* Initialize a SHA1 context */ +static void hash_init(SHA1Context *p){ + /* SHA1 initialization constants */ + p->state[0] = 0x67452301; + p->state[1] = 0xEFCDAB89; + p->state[2] = 0x98BADCFE; + p->state[3] = 0x10325476; + p->state[4] = 0xC3D2E1F0; + p->count[0] = p->count[1] = 0; +} + +/* Add new content to the SHA1 hash */ +static void hash_step( + SHA1Context *p, /* Add content to this context */ + const unsigned char *data, /* Data to be added */ + unsigned int len /* Number of bytes in data */ ){ - const unsigned char *zA = (const unsigned char*)pKey1; - const unsigned char *zB = (const unsigned char*)pKey2; - int i=0, j=0, x; - (void)notUsed; - while( icount[0]; + if( (p->count[0] += len << 3) < j ){ + p->count[1] += (len>>29)+1; + } + j = (j >> 3) & 63; + if( (j + len) > 63 ){ + (void)memcpy(&p->buffer[j], data, (i = 64-j)); + SHA1Transform(p->state, p->buffer); + for(; i + 63 < len; i += 64){ + SHA1Transform(p->state, &data[i]); } + j = 0; + }else{ + i = 0; } - return (nKey1 - i) - (nKey2 - j); + (void)memcpy(&p->buffer[j], &data[i], len - i); } -#ifdef _WIN32 - -#endif -int sqlite3_uint_init( - sqlite3 *db, - char **pzErrMsg, - const sqlite3_api_routines *pApi +/* Compute a string using sqlite3_vsnprintf() and hash it */ +static void hash_step_vformat( + SHA1Context *p, /* Add content to this context */ + const char *zFormat, + ... ){ - SQLITE_EXTENSION_INIT2(pApi); - (void)pzErrMsg; /* Unused parameter */ - return sqlite3_create_collation(db, "uint", SQLITE_UTF8, 0, uintCollFunc); + va_list ap; + int n; + char zBuf[50]; + va_start(ap, zFormat); + sqlite3_vsnprintf(sizeof(zBuf),zBuf,zFormat,ap); + va_end(ap); + n = (int)strlen(zBuf); + hash_step(p, (unsigned char*)zBuf, n); } -/************************* End ../ext/misc/uint.c ********************/ -/************************* Begin ../ext/misc/decimal.c ******************/ -/* -** 2020-06-22 -** + +/* Add padding and compute the message digest. Render the +** message digest as lower-case hexadecimal and put it into +** zOut[]. zOut[] must be at least 41 bytes long. */ +static void hash_finish( + SHA1Context *p, /* The SHA1 context to finish and render */ + char *zOut, /* Store hex or binary hash here */ + int bAsBinary /* 1 for binary hash, 0 for hex hash */ +){ + unsigned int i; + unsigned char finalcount[8]; + unsigned char digest[20]; + static const char zEncode[] = "0123456789abcdef"; + + for (i = 0; i < 8; i++){ + finalcount[i] = (unsigned char)((p->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + hash_step(p, (const unsigned char *)"\200", 1); + while ((p->count[0] & 504) != 448){ + hash_step(p, (const unsigned char *)"\0", 1); + } + hash_step(p, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++){ + digest[i] = (unsigned char)((p->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + if( bAsBinary ){ + memcpy(zOut, digest, 20); + }else{ + for(i=0; i<20; i++){ + zOut[i*2] = zEncode[(digest[i]>>4)&0xf]; + zOut[i*2+1] = zEncode[digest[i] & 0xf]; + } + zOut[i*2]= 0; + } +} +/* End of the hashing logic +*****************************************************************************/ + +/* +** Implementation of the sha1(X) function. +** +** Return a lower-case hexadecimal rendering of the SHA1 hash of the +** argument X. If X is a BLOB, it is hashed as is. For all other +** types of input, X is converted into a UTF-8 string and the string +** is hash without the trailing 0x00 terminator. The hash of a NULL +** value is NULL. +*/ +static void sha1Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + SHA1Context cx; + int eType = sqlite3_value_type(argv[0]); + int nByte = sqlite3_value_bytes(argv[0]); + char zOut[44]; + + assert( argc==1 ); + if( eType==SQLITE_NULL ) return; + hash_init(&cx); + if( eType==SQLITE_BLOB ){ + hash_step(&cx, sqlite3_value_blob(argv[0]), nByte); + }else{ + hash_step(&cx, sqlite3_value_text(argv[0]), nByte); + } + if( sqlite3_user_data(context)!=0 ){ + hash_finish(&cx, zOut, 1); + sqlite3_result_blob(context, zOut, 20, SQLITE_TRANSIENT); + }else{ + hash_finish(&cx, zOut, 0); + sqlite3_result_blob(context, zOut, 40, SQLITE_TRANSIENT); + } +} + +/* +** Implementation of the sha1_query(SQL) function. +** +** This function compiles and runs the SQL statement(s) given in the +** argument. The results are hashed using SHA1 and that hash is returned. +** +** The original SQL text is included as part of the hash. +** +** The hash is not just a concatenation of the outputs. Each query +** is delimited and each row and value within the query is delimited, +** with all values being marked with their datatypes. +*/ +static void sha1QueryFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + sqlite3_stmt *pStmt = 0; + int nCol; /* Number of columns in the result set */ + int i; /* Loop counter */ + int rc; + int n; + const char *z; + SHA1Context cx; + char zOut[44]; + + assert( argc==1 ); + if( zSql==0 ) return; + hash_init(&cx); + while( zSql[0] ){ + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zSql); + if( rc ){ + char *zMsg = sqlite3_mprintf("error SQL statement [%s]: %s", + zSql, sqlite3_errmsg(db)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + if( !sqlite3_stmt_readonly(pStmt) ){ + char *zMsg = sqlite3_mprintf("non-query: [%s]", sqlite3_sql(pStmt)); + sqlite3_finalize(pStmt); + sqlite3_result_error(context, zMsg, -1); + sqlite3_free(zMsg); + return; + } + nCol = sqlite3_column_count(pStmt); + z = sqlite3_sql(pStmt); + n = (int)strlen(z); + hash_step_vformat(&cx,"S%d:",n); + hash_step(&cx,(unsigned char*)z,n); + + /* Compute a hash over the result of the query */ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + hash_step(&cx,(const unsigned char*)"R",1); + for(i=0; i=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'I'; + hash_step(&cx, x, 9); + break; + } + case SQLITE_FLOAT: { + sqlite3_uint64 u; + int j; + unsigned char x[9]; + double r = sqlite3_column_double(pStmt,i); + memcpy(&u, &r, 8); + for(j=8; j>=1; j--){ + x[j] = u & 0xff; + u >>= 8; + } + x[0] = 'F'; + hash_step(&cx,x,9); + break; + } + case SQLITE_TEXT: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_text(pStmt, i); + hash_step_vformat(&cx,"T%d:",n2); + hash_step(&cx, z2, n2); + break; + } + case SQLITE_BLOB: { + int n2 = sqlite3_column_bytes(pStmt, i); + const unsigned char *z2 = sqlite3_column_blob(pStmt, i); + hash_step_vformat(&cx,"B%d:",n2); + hash_step(&cx, z2, n2); + break; + } + } + } + } + sqlite3_finalize(pStmt); + } + hash_finish(&cx, zOut, 0); + sqlite3_result_text(context, zOut, 40, SQLITE_TRANSIENT); +} + + +#ifdef _WIN32 + +#endif +int sqlite3_sha_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + static int one = 1; + SQLITE_EXTENSION_INIT2(pApi); + (void)pzErrMsg; /* Unused parameter */ + rc = sqlite3_create_function(db, "sha1", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + 0, sha1Func, 0, 0); + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha1b", 1, + SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC, + (void*)&one, sha1Func, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "sha1_query", 1, + SQLITE_UTF8|SQLITE_DIRECTONLY, 0, + sha1QueryFunc, 0, 0); + } + return rc; +} + +/************************* End ../ext/misc/sha1.c ********************/ +/************************* Begin ../ext/misc/uint.c ******************/ +/* +** 2020-04-14 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This SQLite extension implements the UINT collating sequence. +** +** UINT works like BINARY for text, except that embedded strings +** of digits compare in numeric order. +** +** * Leading zeros are handled properly, in the sense that +** they do not mess of the maginitude comparison of embedded +** strings of digits. "x00123y" is equal to "x123y". +** +** * Only unsigned integers are recognized. Plus and minus +** signs are ignored. Decimal points and exponential notation +** are ignored. +** +** * Embedded integers can be of arbitrary length. Comparison +** is *not* limited integers that can be expressed as a +** 64-bit machine integer. +*/ +/* #include "sqlite3ext.h" */ +SQLITE_EXTENSION_INIT1 +#include +#include +#include + +/* +** Compare text in lexicographic order, except strings of digits +** compare in numeric order. +*/ +static int uintCollFunc( + void *notUsed, + int nKey1, const void *pKey1, + int nKey2, const void *pKey2 +){ + const unsigned char *zA = (const unsigned char*)pKey1; + const unsigned char *zB = (const unsigned char*)pKey2; + int i=0, j=0, x; + (void)notUsed; + while( inFrac = 0; } } - if( iExp>0 ){ + if( iExp>0 ){ p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 ); if( p->a==0 ) goto new_from_text_failed; memset(p->a+p->nDigit, 0, iExp); @@ -4164,7 +4227,7 @@ static void decimalMul(Decimal *pA, Decimal *pB){ int minFrac; if( pA==0 || pA->oom || pA->isNull - || pB==0 || pB->oom || pB->isNull + || pB==0 || pB->oom || pB->isNull ){ goto mul_end; } @@ -4450,7 +4513,7 @@ static void decimalMulFunc( Decimal *pB = decimal_new(context, argv[1], 1); UNUSED_PARAMETER(argc); if( pA==0 || pA->oom || pA->isNull - || pB==0 || pB->oom || pB->isNull + || pB==0 || pB->oom || pB->isNull ){ goto mul_end; } @@ -4487,8 +4550,8 @@ static void decimalPow2Func( #endif int sqlite3_decimal_init( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; @@ -4530,11 +4593,9 @@ int sqlite3_decimal_init( } /************************* End ../ext/misc/decimal.c ********************/ -#undef sqlite3_base_init -#define sqlite3_base_init sqlite3_base64_init -/************************* Begin ../ext/misc/base64.c ******************/ +/************************* Begin ../ext/misc/percentile.c ******************/ /* -** 2022-11-18 +** 2013-05-28 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: @@ -4543,13 +4604,521 @@ int sqlite3_decimal_init( ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** -************************************************************************* +****************************************************************************** ** -** This is a SQLite extension for converting in either direction -** between a (binary) blob and base64 text. Base64 can transit a -** sane USASCII channel unmolested. It also plays nicely in CSV or -** written as TCL brace-enclosed literals or SQL string literals, -** and can be used unmodified in XML-like documents. +** This file contains code to implement the percentile(Y,P) SQL function +** and similar as described below: +** +** (1) The percentile(Y,P) function is an aggregate function taking +** exactly two arguments. +** +** (2) If the P argument to percentile(Y,P) is not the same for every +** row in the aggregate then an error is thrown. The word "same" +** in the previous sentence means that the value differ by less +** than 0.001. +** +** (3) If the P argument to percentile(Y,P) evaluates to anything other +** than a number in the range of 0.0 to 100.0 inclusive then an +** error is thrown. +** +** (4) If any Y argument to percentile(Y,P) evaluates to a value that +** is not NULL and is not numeric then an error is thrown. +** +** (5) If any Y argument to percentile(Y,P) evaluates to plus or minus +** infinity then an error is thrown. (SQLite always interprets NaN +** values as NULL.) +** +** (6) Both Y and P in percentile(Y,P) can be arbitrary expressions, +** including CASE WHEN expressions. +** +** (7) The percentile(Y,P) aggregate is able to handle inputs of at least +** one million (1,000,000) rows. +** +** (8) If there are no non-NULL values for Y, then percentile(Y,P) +** returns NULL. +** +** (9) If there is exactly one non-NULL value for Y, the percentile(Y,P) +** returns the one Y value. +** +** (10) If there N non-NULL values of Y where N is two or more and +** the Y values are ordered from least to greatest and a graph is +** drawn from 0 to N-1 such that the height of the graph at J is +** the J-th Y value and such that straight lines are drawn between +** adjacent Y values, then the percentile(Y,P) function returns +** the height of the graph at P*(N-1)/100. +** +** (11) The percentile(Y,P) function always returns either a floating +** point number or NULL. +** +** (12) The percentile(Y,P) is implemented as a single C99 source-code +** file that compiles into a shared-library or DLL that can be loaded +** into SQLite using the sqlite3_load_extension() interface. +** +** (13) A separate median(Y) function is the equivalent percentile(Y,50). +** +** (14) A separate percentile_cont(Y,P) function is equivalent to +** percentile(Y,P/100.0). In other words, the fraction value in +** the second argument is in the range of 0 to 1 instead of 0 to 100. +** +** (15) A separate percentile_disc(Y,P) function is like +** percentile_cont(Y,P) except that instead of returning the weighted +** average of the nearest two input values, it returns the next lower +** value. So the percentile_disc(Y,P) will always return a value +** that was one of the inputs. +** +** (16) All of median(), percentile(Y,P), percentile_cont(Y,P) and +** percentile_disc(Y,P) can be used as window functions. +** +** Differences from standard SQL: +** +** * The percentile_cont(X,P) function is equivalent to the following in +** standard SQL: +** +** (percentile_cont(P) WITHIN GROUP (ORDER BY X)) +** +** The SQLite syntax is much more compact. The standard SQL syntax +** is also supported if SQLite is compiled with the +** -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES option. +** +** * No median(X) function exists in the SQL standard. App developers +** are expected to write "percentile_cont(0.5)WITHIN GROUP(ORDER BY X)". +** +** * No percentile(Y,P) function exists in the SQL standard. Instead of +** percential(Y,P), developers must write this: +** "percentile_cont(P/100.0) WITHIN GROUP (ORDER BY Y)". Note that +** the fraction parameter to percentile() goes from 0 to 100 whereas +** the fraction parameter in SQL standard percentile_cont() goes from +** 0 to 1. +** +** Implementation notes as of 2024-08-31: +** +** * The regular aggregate-function versions of these routines work +** by accumulating all values in an array of doubles, then sorting +** that array using quicksort before computing the answer. Thus +** the runtime is O(NlogN) where N is the number of rows of input. +** +** * For the window-function versions of these routines, the array of +** inputs is sorted as soon as the first value is computed. Thereafter, +** the array is kept in sorted order using an insert-sort. This +** results in O(N*K) performance where K is the size of the window. +** One can imagine alternative implementations that give O(N*logN*logK) +** performance, but they require more complex logic and data structures. +** The developers have elected to keep the asymptotically slower +** algorithm for now, for simplicity, under the theory that window +** functions are seldom used and when they are, the window size K is +** often small. The developers might revisit that decision later, +** should the need arise. +*/ +#if defined(SQLITE3_H) + /* no-op */ +#elif defined(SQLITE_STATIC_PERCENTILE) +/* # include "sqlite3.h" */ +#else +/* # include "sqlite3ext.h" */ + SQLITE_EXTENSION_INIT1 +#endif +#include +#include +#include + +/* The following object is the group context for a single percentile() +** aggregate. Remember all input Y values until the very end. +** Those values are accumulated in the Percentile.a[] array. +*/ +typedef struct Percentile Percentile; +struct Percentile { + unsigned nAlloc; /* Number of slots allocated for a[] */ + unsigned nUsed; /* Number of slots actually used in a[] */ + char bSorted; /* True if a[] is already in sorted order */ + char bKeepSorted; /* True if advantageous to keep a[] sorted */ + char bPctValid; /* True if rPct is valid */ + double rPct; /* Fraction. 0.0 to 1.0 */ + double *a; /* Array of Y values */ +}; + +/* Details of each function in the percentile family */ +typedef struct PercentileFunc PercentileFunc; +struct PercentileFunc { + const char *zName; /* Function name */ + char nArg; /* Number of arguments */ + char mxFrac; /* Maximum value of the "fraction" input */ + char bDiscrete; /* True for percentile_disc() */ +}; +static const PercentileFunc aPercentFunc[] = { + { "median", 1, 1, 0 }, + { "percentile", 2, 100, 0 }, + { "percentile_cont", 2, 1, 0 }, + { "percentile_disc", 2, 1, 1 }, +}; + +/* +** Return TRUE if the input floating-point number is an infinity. +*/ +static int percentIsInfinity(double r){ + sqlite3_uint64 u; + assert( sizeof(u)==sizeof(r) ); + memcpy(&u, &r, sizeof(u)); + return ((u>>52)&0x7ff)==0x7ff; +} + +/* +** Return TRUE if two doubles differ by 0.001 or less. +*/ +static int percentSameValue(double a, double b){ + a -= b; + return a>=-0.001 && a<=0.001; +} + +/* +** Search p (which must have p->bSorted) looking for an entry with +** value y. Return the index of that entry. +** +** If bExact is true, return -1 if the entry is not found. +** +** If bExact is false, return the index at which a new entry with +** value y should be insert in order to keep the values in sorted +** order. The smallest return value in this case will be 0, and +** the largest return value will be p->nUsed. +*/ +static int percentBinarySearch(Percentile *p, double y, int bExact){ + int iFirst = 0; /* First element of search range */ + int iLast = p->nUsed - 1; /* Last element of search range */ + while( iLast>=iFirst ){ + int iMid = (iFirst+iLast)/2; + double x = p->a[iMid]; + if( xy ){ + iLast = iMid - 1; + }else{ + return iMid; + } + } + if( bExact ) return -1; + return iFirst; +} + +/* +** Generate an error for a percentile function. +** +** The error format string must have exactly one occurrance of "%%s()" +** (with two '%' characters). That substring will be replaced by the name +** of the function. +*/ +static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){ + PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); + char *zMsg1; + char *zMsg2; + va_list ap; + + va_start(ap, zFormat); + zMsg1 = sqlite3_vmprintf(zFormat, ap); + va_end(ap); + zMsg2 = zMsg1 ? sqlite3_mprintf(zMsg1, pFunc->zName) : 0; + sqlite3_result_error(pCtx, zMsg2, -1); + sqlite3_free(zMsg1); + sqlite3_free(zMsg2); +} + +/* +** The "step" function for percentile(Y,P) is called once for each +** input row. +*/ +static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){ + Percentile *p; + double rPct; + int eType; + double y; + assert( argc==2 || argc==1 ); + + if( argc==1 ){ + /* Requirement 13: median(Y) is the same as percentile(Y,50). */ + rPct = 0.5; + }else{ + /* Requirement 3: P must be a number between 0 and 100 */ + PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); + eType = sqlite3_value_numeric_type(argv[1]); + rPct = sqlite3_value_double(argv[1])/(double)pFunc->mxFrac; + if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT) + || rPct<0.0 || rPct>1.0 + ){ + percentError(pCtx, "the fraction argument to %%s()" + " is not between 0.0 and %.1f", + (double)pFunc->mxFrac); + return; + } + } + + /* Allocate the session context. */ + p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + if( p==0 ) return; + + /* Remember the P value. Throw an error if the P value is different + ** from any prior row, per Requirement (2). */ + if( !p->bPctValid ){ + p->rPct = rPct; + p->bPctValid = 1; + }else if( !percentSameValue(p->rPct,rPct) ){ + percentError(pCtx, "the fraction argument to %%s()" + " is not the same for all input rows"); + return; + } + + /* Ignore rows for which Y is NULL */ + eType = sqlite3_value_type(argv[0]); + if( eType==SQLITE_NULL ) return; + + /* If not NULL, then Y must be numeric. Otherwise throw an error. + ** Requirement 4 */ + if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){ + percentError(pCtx, "input to %%s() is not numeric"); + return; + } + + /* Throw an error if the Y value is infinity or NaN */ + y = sqlite3_value_double(argv[0]); + if( percentIsInfinity(y) ){ + percentError(pCtx, "Inf input to %%s()"); + return; + } + + /* Allocate and store the Y */ + if( p->nUsed>=p->nAlloc ){ + unsigned n = p->nAlloc*2 + 250; + double *a = sqlite3_realloc64(p->a, sizeof(double)*n); + if( a==0 ){ + sqlite3_free(p->a); + memset(p, 0, sizeof(*p)); + sqlite3_result_error_nomem(pCtx); + return; + } + p->nAlloc = n; + p->a = a; + } + if( p->nUsed==0 ){ + p->a[p->nUsed++] = y; + p->bSorted = 1; + }else if( !p->bSorted || y>=p->a[p->nUsed-1] ){ + p->a[p->nUsed++] = y; + }else if( p->bKeepSorted ){ + int i; + i = percentBinarySearch(p, y, 0); + if( i<(int)p->nUsed ){ + memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0])); + } + p->a[i] = y; + p->nUsed++; + }else{ + p->a[p->nUsed++] = y; + p->bSorted = 0; + } +} + +/* +** Interchange two doubles. +*/ +#define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;} + +/* +** Sort an array of doubles. +** +** Algorithm: quicksort +** +** This is implemented separately rather than using the qsort() routine +** from the standard library because: +** +** (1) To avoid a dependency on qsort() +** (2) To avoid the function call to the comparison routine for each +** comparison. +*/ +static void percentSort(double *a, unsigned int n){ + int iLt; /* Entries before a[iLt] are less than rPivot */ + int iGt; /* Entries at or after a[iGt] are greater than rPivot */ + int i; /* Loop counter */ + double rPivot; /* The pivot value */ + + assert( n>=2 ); + if( a[0]>a[n-1] ){ + SWAP_DOUBLE(a[0],a[n-1]) + } + if( n==2 ) return; + iGt = n-1; + i = n/2; + if( a[0]>a[i] ){ + SWAP_DOUBLE(a[0],a[i]) + }else if( a[i]>a[iGt] ){ + SWAP_DOUBLE(a[i],a[iGt]) + } + if( n==3 ) return; + rPivot = a[i]; + iLt = i = 1; + do{ + if( a[i]iLt ) SWAP_DOUBLE(a[i],a[iLt]) + iLt++; + i++; + }else if( a[i]>rPivot ){ + do{ + iGt--; + }while( iGt>i && a[iGt]>rPivot ); + SWAP_DOUBLE(a[i],a[iGt]) + }else{ + i++; + } + }while( i=2 ) percentSort(a, iLt); + if( n-iGt>=2 ) percentSort(a+iGt, n-iGt); + +/* Uncomment for testing */ +#if 0 + for(i=0; ibSorted==0 ){ + assert( p->nUsed>1 ); + percentSort(p->a, p->nUsed); + p->bSorted = 1; + } + p->bKeepSorted = 1; + + /* Find and remove the row */ + i = percentBinarySearch(p, y, 1); + if( i>=0 ){ + p->nUsed--; + if( i<(int)p->nUsed ){ + memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0])); + } + } +} + +/* +** Compute the final output of percentile(). Clean up all allocated +** memory if and only if bIsFinal is true. +*/ +static void percentCompute(sqlite3_context *pCtx, int bIsFinal){ + Percentile *p; + PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx); + unsigned i1, i2; + double v1, v2; + double ix, vx; + p = (Percentile*)sqlite3_aggregate_context(pCtx, 0); + if( p==0 ) return; + if( p->a==0 ) return; + if( p->nUsed ){ + if( p->bSorted==0 ){ + assert( p->nUsed>1 ); + percentSort(p->a, p->nUsed); + p->bSorted = 1; + } + ix = p->rPct*(p->nUsed-1); + i1 = (unsigned)ix; + if( pFunc->bDiscrete ){ + vx = p->a[i1]; + }else{ + i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1; + v1 = p->a[i1]; + v2 = p->a[i2]; + vx = v1 + (v2-v1)*(ix-i1); + } + sqlite3_result_double(pCtx, vx); + } + if( bIsFinal ){ + sqlite3_free(p->a); + memset(p, 0, sizeof(*p)); + }else{ + p->bKeepSorted = 1; + } +} +static void percentFinal(sqlite3_context *pCtx){ + percentCompute(pCtx, 1); +} +static void percentValue(sqlite3_context *pCtx){ + percentCompute(pCtx, 0); +} + +#if defined(_WIN32) && !defined(SQLITE3_H) && !defined(SQLITE_STATIC_PERCENTILE) + +#endif +int sqlite3_percentile_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + unsigned int i; +#if defined(SQLITE3_H) || defined(SQLITE_STATIC_PERCENTILE) + (void)pApi; /* Unused parameter */ +#else + SQLITE_EXTENSION_INIT2(pApi); +#endif + (void)pzErrMsg; /* Unused parameter */ + for(i=0; i