Chilkat v11.6.0 / v11.6.1
New platforms · AI tooling · MCP · dozens of fixes
- Rust (new) — Chilkat for Rust is now available as the
chilkatcrate on crates.io:cargo add chilkat, and the prebuilt Chilkat library for Windows, Linux, Alpine Linux, or macOS is downloaded automatically at build time. Details - ActiveX — members added in v11.6.0 were not callable from the ActiveX; they are now. Details
- Java — the per-JDK downloads are replaced by one download per OS/architecture that works with every JDK from Java 8 up. Details
- Lazarus / Free Pascal — fixes to the
.paswrapper units: four units that would not compile, and five that raisedEntry point not foundat startup. Details - Perl — Perl 5.42 and 5.44 are added, and the 32-bit x86 and armv7l Linux/Alpine builds are retired. Details
- PHP — the PHP extension is rebuilt on an improved code generator with no API changes; installing it is now one command (a Composer package,
chilkat/chilkat, or an install script); and the 32-bit Alpine Linux builds (x86 and armv7l) are retired. Details - Python (CkPython) — the
chilkatmodule is rebuilt on an improved code generator with no API changes and now targets the CPython stable ABI, so one download per platform (and one pip wheel) works with every Python from 3.7 onward; Windows ARM64 is added; Python 3.6 and earlier, and the 32-bit x86 and armv7l Alpine builds, are retired. Details - Ruby — the Ruby extension is rebuilt on an improved code generator with no API changes, and Ruby 3.2 is retired. Details
- Tcl — Tcl 9.0 is now available for Windows, the two 64-bit Tcl 8.6 downloads have become one, and strings are UTF-8 by default. Details
This release adds several major new capabilities — Chilkat for B4X, cross-platform Delphi DLL and Lazarus / Free Pascal editions, Model Context Protocol (MCP) support, AI structured output and web search, and Argon2 password hashing — along with a broad set of fixes and improvements across the crypto, email, HTTP/REST, and text-processing classes.
✨ Release Highlights
| Area | What’s new |
|---|---|
| 🧩 New platforms | Chilkat for B4X (B4A + B4J), cross-platform Delphi DLL (Linux, macOS, iOS, Android, Win-ARM), and Lazarus / Free Pascal |
| 🤖 AI | MCP client + Ai.UseMcp, JSON-Schema structured output, provider-hosted web search |
| 🔐 Crypto | Argon2 (id/i/d) password hashing & key derivation in Crypt2 |
| 🛡️ Reliability | Strict JSON/XML loading, StringBuilder.IsWellFormed, secrets-aware unlock & JSON load |
| 🧰 Fixes | JWE, JWS, MIME, PrivateKey/PublicKey, Socket, IMAP, REST, HtmlToText, PCRE2 |
📑 Contents
- Chilkat for B4X (B4A and B4J)
- Chilkat for Lazarus / Free Pascal
- Chilkat Delphi DLL — Cross-Platform
- Model Context Protocol (MCP)
- Ai — Structured Output
- Ai — Web Search
- Crypt2 — Argon2
- Secrets-Aware Methods
- Strict Loading (Xml / JsonObject)
- StringBuilder.IsWellFormed
- HtmlToText — Table Rendering
- Smaller additions
- HTTP / REST
- HtmlToText — Correctness Fixes
- Crypto — JWE, JWS, Keys
- MIME
- Sockets
- Email — IMAP & MailMan
- JSON, PCRE2, Objective-C
- Chilkat v11.6.1 — Rust: the new
chilkatcrate - Chilkat v11.6.1 — ActiveX fix
- Chilkat v11.6.1 — Java: one download per OS/architecture
- Chilkat v11.6.1 — Lazarus / Free Pascal fixes
- Chilkat v11.6.1 — Perl: UTF-8 by default, and new Perl versions
- Chilkat v11.6.1 — PHP: a rebuilt extension, one-command installation, and a slimmer platform matrix
- Chilkat v11.6.1 — Python (CkPython): a rebuilt extension, one download for every Python 3.7+, Windows ARM64
- Chilkat v11.6.1 — Ruby: a rebuilt extension, Ruby 3.2 retired
- Chilkat v11.6.1 — Tcl: Tcl 9.0 on Windows, UTF-8 by default
✨ New Features & Additions
📱 Chilkat for B4X (B4A and B4J)
Chilkat is now available for B4X: B4A (Android) and B4J (Windows, Linux, macOS).
- One download, two libraries —
ChilkatB4A.jarandChilkatB4J.jar(each with its.xml), installed by copying into the IDE’s additional-libraries folder. - Familiar, prefixed classes — every Chilkat class appears as a Chilkat-prefixed B4X type (
ChilkatHttp,ChilkatCrypt2,ChilkatZip, …) with full IDE autocomplete. The API is identical in B4A and B4J, so code moves between them unchanged. - Self-contained jars — native libraries for all supported CPUs are inside: packaged into the APK automatically on Android (armeabi-v7a, arm64-v8a, x86, x86_64; 16 KB-page aligned), and loaded automatically on the desktop (Windows x64, Linux x86_64/arm64/arm, macOS Intel and Apple Silicon).
- Progress events — long-running calls raise the standard
AbortCheck,PercentDone, andProgressInfoevents as ordinary B4X event Subs. - Requirements — Android 7.0+ (
minSdkVersion 24) on B4A; Java 8+ on B4J.
📘 Links Download · Reference Documentation
🧡 Chilkat for Lazarus / Free Pascal
Chilkat is now available for Lazarus / Free Pascal (FPC) — a fully generated Object Pascal API in which each Chilkat class is wrapped by its own self-contained Pascal unit (Chilkat.Http.pas, Chilkat.Zip.pas, …), each providing a Pascal class (THttp, TZip, …) derived from TChilkatBase.
- No compile-time linking — the units resolve all functions at runtime from the native Chilkat C bridge library via
CkDllLoader.pas. - Plain Pascal strings —
stringthroughout; UTF-8 conversion is handled internally. - No circular
uses— object parameters and return values are typed asTChilkatBase, so you add only the units you actually use.
Supported platforms (the chilkat_c_bridge runtime library):
| OS | Architectures |
|---|---|
| Windows | x86, x64, ARM64 |
| Linux | x86_64, arm64, x86, armhf |
| macOS | Universal (Apple Silicon + Intel) |
CkDllLoader.pas selects the correct library for the current OS and architecture automatically, and a custom load path can be specified.
uses
Chilkat.Base, Chilkat.Http;
var
http: THttp;
begin
http := THttp.Create;
if not http.IsValid then
raise Exception.Create('Failed to load the Chilkat library.');
WriteLn(http.QuickGetStr('https://www.example.com/'));
http.Free;
end;
Event-capable classes provide the three synchronous callbacks as Pascal of object event properties — OnAbortCheck, OnPercentDone, and OnProgressInfo (handler types declared in Chilkat.Base.pas). The HeartbeatMs property controls OnAbortCheck frequency, and returning True from OnAbortCheck or OnPercentDone aborts the running method.
⚙️ Scope synchronous API only: no async (*Async) variants, and no Task / TaskChain classes.
📘 Links Reference Documentation · Sample Code
🔷 Chilkat Delphi DLL — Now Cross-Platform
The Chilkat Delphi DLL API, previously available only as a Windows 32-bit/64-bit DLL, is now provided as a native library for every major Delphi target. The same flat API (CkHttp_QuickGetStr, CkZip_Unzip, …) that Delphi applications call on Windows can now be used unchanged in FireMonkey (FMX) applications on Linux, macOS, iOS, and Android, and on Windows-on-ARM devices.
| Platform | Delivered as |
|---|---|
| Linux | shared libraries for x86_64 and arm64 |
| macOS | a universal (Apple Silicon + Intel) dylib, code-signed with a Developer ID certificate and secure-timestamped for notarization |
| iOS | a static library linked directly into the application, per Apple’s requirements for device deployment |
| Android | native libraries for the standard Android ABIs |
| Windows on ARM | a new ARM64 (ARM64EC) DLL — native ARM code on Windows-on-ARM devices, including within existing x64 Delphi apps running under emulation |
🤖 Model Context Protocol (MCP)
Chilkat v11.6.0 adds support for the Model Context Protocol (MCP) — an open protocol that standardizes how applications provide tools, resources, and prompts to AI models. This release introduces a new Mcp class (an MCP client) and integrates MCP tools into the existing Ai class through a new UseMcp method.
New class: Mcp
The Mcp class connects to an MCP server and gives an application unified access to the server’s tools, resources, and prompts. It uses the MCP Streamable HTTP transport (protocol version 2025-06-18): a single endpoint URL handles the JSON-RPC exchange over HTTP POST, and a server response may arrive either as a single JSON object or as a Server-Sent-Events stream — both handled transparently. The stdio transport is not supported in this release.
| Capability | Details |
|---|---|
| Connecting | Connect performs the MCP initialize handshake, then SessionId, ProtocolVersion, ServerName, ServerVersion, and ServerInstructions are populated and Connected is true. Chilkat sends the MCP-Protocol-Version and Mcp-Session-Id headers automatically; Close terminates the session (HTTP DELETE). |
| Tools | ListTools returns each tool’s name, description, and inputSchema; CallTool invokes a tool by name and returns its content array and isError flag. A tool that runs but reports failure returns success with isError true. |
| Resources & prompts | ListResources / ReadResource (text or base64 blob) and ListPrompts / GetPrompt. |
| Auth & settings | AuthToken for a bearer token; SetConnectionSettings copies proxy, bind-IP, and TLS options from a Socket. Timeouts via IdleTimeoutMs (180000) and ConnectTimeoutMs (30000); HeartbeatMs controls the AbortCheck interval. |
MCP tools in the Ai class: UseMcp
Mcp mcp;
mcp.Connect("https://example.com/mcp");
Ai ai;
ai.put_Provider("openai");
ai.put_ApiKey(myKey);
ai.put_Model("gpt-5.1");
ai.NewConvo("chat","You are a helpful assistant","");
// Register the MCP server's tools with the model.
ai.UseMcp(mcp,"myserver");
ai.InputAddText("Use the available tools to answer: ...");
ai.Ask("text");
UseMcp registers the connected server’s tools with the model, namespacing each tool name with the supplied prefix so tools from different servers (and JavaScript tools) cannot collide. Because MCP tools are presented as ordinary function tools, UseMcp works with every provider the Ai class supports — OpenAI, Anthropic Claude, Google Gemini, xAI Grok, Mistral, and Perplexity. When the model requests a tool during an Ask, Chilkat automatically routes the call via Mcp.CallTool, adds the result to the conversation, and continues — no application code is required to run the tool. This works in both the standard Ask and in streaming mode (surfacing as a js_function_call event handled by StreamingJsToolCall). An informational ProgressInfo event named McpToolCall is emitted before each automatic MCP tool call.
📝 Notes Automatic tool use requires a selected conversation (not a stateless query). The Mcp object passed to UseMcp must remain connected and valid for as long as its tools are used.
🎯 Ai — Structured Output (JSON Schema)
Supply a JSON Schema and the AI model returns a response that conforms to it — ideal for reliable data extraction and function-argument generation.
Call SetOutputSchema(name, schema, strict) to request schema-constrained output, then retrieve the parsed result with GetOutputJson. The same code works across OpenAI, Anthropic Claude, Google Gemini, xAI Grok, Mistral, and Perplexity — Chilkat translates your one schema into each provider’s native format. When strict is enabled, Chilkat automatically augments the schema (adding additionalProperties: false and required-property lists) for the providers that need it. Refusals are surfaced distinctly via the LastResponseRefused and RefusalText properties.
📘 See Chilkat AI Structured Output for full details, the provider-support matrix, and examples.
🔎 Ai — Web Search
Unified, provider-hosted web search for the Ai class. When enabled, the AI provider performs a live web search while generating its response and answers using the retrieved results, returning citations. A single Chilkat API drives web search across providers, so the same application code works whether the provider is OpenAI, Anthropic Claude, Google Gemini, xAI Grok, or Perplexity.
Enabling web search — turned on per-request through a new web_search object passed to SetAskParams. Only enabled is required; every other field is optional, and Chilkat silently ignores fields a given provider does not support.
{
"web_search": {
"enabled": true,
"max_uses": 3,
"allowed_domains": [ "wikipedia.org", "nasa.gov" ],
"blocked_domains": [ ],
"recency": "week",
"user_location": {
"country": "US",
"city": "Chicago",
"region": "Illinois",
"timezone": "America/Chicago"
}
}
}
| Field | Meaning |
|---|---|
enabled | Turns web search on for the Ask. For Perplexity, search is always on (no-op). |
max_uses | Maximum searches the model may perform — the primary cost-control knob. |
allowed_domains / blocked_domains | Restrict results to, or exclude, specific domains. |
recency | Limit results by age: day, week, month, or year. |
user_location | Optional country, city, region, timezone to localize results. |
Retrieving the sources — a new GetSearchResults method returns the sources the model used in the most recent Ask, normalizing each provider’s citation format into one flat structure (url, title, snippet, page_age). The complete, unmodified provider response remains available via GetLastJsonData. Streaming — when Streaming is enabled, a standardized web_search_call event is delivered through NextAiEvent while the provider searches.
Provider support:
| Field | openai | claude | xai | perplexity | |
|---|---|---|---|---|---|
enabled | Yes | Yes | grounding | Yes | always on |
max_uses | — | Yes | — | max results | — |
allowed_domains | Yes | Yes | — | Yes | Yes |
blocked_domains | — | Yes | — | Yes | Yes |
recency | — | — | — | date range | Yes |
user_location | Yes | Yes | — | — | — |
📝 Notes Google Gemini web search (grounding) is available only through the native Gemini API, not the OpenAI-compatible path. deepseek and mistral (chat) have no web-search tool: if web_search is set, the Ask proceeds without search and a note is written to LastErrorText, so provider-switching code degrades gracefully. Most providers bill web searches separately from tokens — use max_uses to bound per-request cost.
🔐 Crypt2 — Argon2
Chilkat now implements Argon2, the memory-hard password hashing and key-derivation function specified in RFC 9106 and winner of the Password Hashing Competition. All three variants are supported: Argon2id (the recommended default), Argon2i, and Argon2d. Its memory cost makes large-scale cracking on GPUs and custom hardware impractical, which is why Argon2 is now the recommended choice over PBKDF2 and bcrypt for new applications.
| Method | Purpose |
|---|---|
Argon2DeriveKey | Derives a key of any length from a password (for encryption keys and other key-derivation uses). |
Argon2HashPassword | Hashes a password for storage, returning a PHC-format string such as $argon2id$v=19$m=65536,t=3,p=1$<salt>$<hash>. A random salt is generated automatically. |
Argon2VerifyPassword | Verifies a password against a stored PHC-format hash. All parameters are read from the stored hash. |
Options are passed as a JSON string rather than many new properties. Every member is optional — an empty string uses defaults suitable for password hashing (Argon2id, version 19, 3 iterations, 64 MB memory, 32-byte hash, 16-byte random salt):
{
"variant": "argon2id",
"iterations": 3,
"memoryCostKb": 65536,
"parallelism": 1,
"keyLen": 32,
"salt": "cmFuZG9tc2FsdDEyMzQ="
}
The short RFC 9106 / PHC parameter names (t, m, p, v) are accepted as aliases, and the optional RFC 9106 secret (a pepper) and associated data inputs are supported.
- Hash strings are standard PHC format and interoperate with other Argon2 implementations in both directions.
- If a stored hash string is malformed,
Argon2VerifyPasswordreturnsfalseandLastMethodSuccessisfalse, distinguishing a bad hash string from a wrong password. - A
maxMemoryKboption caps allocation — important when verifying hashes from an untrusted source, since the memory cost is read from the stored string. - Version
0x10(16) hashes can be verified for compatibility; new hashes use version0x13(19).
🔑 Secrets-Aware Methods
Chilkat.Global.UnlockBundle and JsonObject.Load are now secrets aware. Each can accept a secret specification string (beginning with !!) in place of a literal value, and Chilkat resolves it from the Windows Credential Manager (Windows) or Apple Keychain (macOS). Secrets are identified by the structured format !![appName|]service[|domain]|username, letting applications resolve credentials at runtime instead of embedding them in code.
📝 There is no EnableSecrets property — UnlockBundle is always secrets aware. If the secret is not present in a local manager, the spec is used as-is, causing UnlockBundle to either fail or succeed in trial mode.
🧪 Strict Loading for Xml and JsonObject
Chilkat’s XML and JSON parsers are deliberately tolerant: given input that is not well-formed they parse what they can, report success, and leave a partially populated document. That is the wrong behavior when a silently dropped element or member changes what the application does. Both classes now have a Strict property that closes this off.
| Property | Behavior when true |
|---|---|
Xml.Strict(default false) | Checks the input is well-formed XML before parsing; on failure the load fails and the object is left unchanged. Applies to LoadXml, LoadXml2, LoadSb, LoadBd, LoadXmlFile, LoadXmlFile2. (Well-formedness only, not validating.) |
JsonObject.Strict(default false) | Validates the text against the full JSON grammar first; on failure leaves existing contents unchanged. Applies to Load, LoadSb, LoadBd, LoadFile, LoadPredefined. |
Both default to false, so existing applications are unaffected. Turn Strict on for input carrying configuration, credentials, signed content, or security parameters.
✔️ StringBuilder.IsWellFormed
A new method, IsWellFormed(format), returns true if the contents of the StringBuilder are well-formed JSON or XML. The format argument must be "json" or "xml" (case insensitive). It answers the question the tolerant parsers do not — about text already in hand, with no JsonObject or Xml object created first.
sb.LoadFile("config.json","utf-8");
if (!sb.IsWellFormed("json")) {
// the file is not well-formed JSON
}
For "json", the full RFC 8259 grammar is checked; for "xml", XML 1.0 well-formedness (the same checks Strict applies). Empty contents are not well-formed. The contents are never modified, and deeply nested input is rejected at a nesting limit of 256 (validation is iterative, so no depth can exhaust the call stack).
📊 HtmlToText — Table Rendering
HtmlToText now renders HTML tables as fixed-width text tables. Previously a <table> was converted by placing each cell on its own line, losing the row-and-column relationship; tables are now drawn as aligned, bordered text tables that preserve the original structure. No code changes are required to benefit.
⚠️ Output change because this changes the text produced for tables, review the notes below if your application compares HtmlToText output against saved or expected strings.
- Rows and columns preserved — drawn with
|separators and+/-borders, every column aligned. - Header rows set apart —
<th>cells are centered and underlined with a row of=. - Columns sized to content and kept within
RightMargin; long cell text wraps inside the cell rather than overflowing. - Rich cell contents — paragraphs, ordered/unordered lists (including nested),
<pre>blocks, line breaks, and basic inline formatting render within the cell’s column. - Merged and nested tables honored —
colspanandrowspanare supported, and a table inside a cell is drawn as its own bordered table. A<caption>is centered above the table. - Links in cells follow the same link settings as the rest of the document (shared “References” list with bracketed numbers by default).
🖼️ See the HTML Table to Plain Text Gallery for examples rendered with the improved v11.6.0 HtmlToText.
➕ Smaller Additions
Url.Scheme— added theSchemeproperty toChilkat.Url. The scheme is the first part of a URL (e.g.httpsinhttps://www.example.com/page); common schemes includehttp,https,ftp,file, andmailto.Ssh.GetReceivedSb— added to theSshclass, for retrieving received data into aStringBuilder.MailMan.RequireHostnameMatchandMailMan.SniHostName— added properties.RequireHostnameMatch(defaultfalse) requires the TLS hostname to match a name in the server certificate’s Subject Alternative Name extension; it is enforced independently ofRequireSslCertVerify.SniHostNamesets the DNS hostname sent in the TLS Server Name Indication for SMTP and POP3 connections (normally left empty, in which caseSmtpHost/MailHostis used); set it when connecting by IP address or through an alternate endpoint, and it is also the name compared whenRequireHostnameMatchistrue.JsonArray.FindStartIndex— added property.- Azure Key Vault cloud signing — an application may now specify the
access_tokendirectly instead ofclient_id/client_secret/tenant_id, so it can obtain its own token (for example via a Managed Identity) and pass it straight to Chilkat:
See Sign PDF in the Cloud using Azure Key Vault.jsonAzure.UpdateString("service", "azure_keyvault"); jsonAzure.UpdateString("access_token", accessToken); jsonAzure.UpdateString("vault_name", "VAULT_NAME"); jsonAzure.UpdateString("cert_name", "CERT_NAME"); jsonAzure.UpdateString("cert_version", "CERT_VERSION"); - iOS builds — updated
makeUniversalLib.shand added a new script for building an XCFramework; the iOS download page was updated following removal of the obsoletearmv7andarmv7sslices.
🛠️ Fixes & Improvements
🌐 HTTP / REST
⚠️ Breaking change AllowHeaderFolding (on both Chilkat.Rest and Chilkat.Http) now defaults to false. HTTP header folding is obsolete (RFC 7230 says a sender must not generate folded headers), and modern servers increasingly reject folded headers with 400 Bad Request — which previously happened whenever a header value was long (e.g. a lengthy Authorization header). Applications that require folded headers can restore the old behavior by explicitly setting AllowHeaderFolding = true.
Rest — response body after ReadResponseHeader. In the manual request/response pattern (explicit steps rather than a FullRequest* method), the response body was not readable after ReadResponseHeader: the object incorrectly moved to an idle state for all verbs, so every body-read call failed with “not in the state to read the response body.” Fixed — after a valid status code, the object now correctly enters the body-reading state for any request that can have a body. A HEAD request (no body) still correctly stops after the header. FullRequest* methods were never affected.
Rest — ReadRespBodyStream and EndOfStream. Fixed a spurious read failure when downloading a response body into a Stream and reading it on another thread. After the full body was received, EndOfStream could remain false, so a loop on EndOfStream made one extra read that failed. Now EndOfStream becomes true once the body is delivered and consumed, and a read at the very end returns success with no bytes rather than an error. No code changes required.
📄 HtmlToText — Correctness Fixes
A number of correctness and reliability fixes. Existing code does not need to change; items that alter the exact output are marked (output change).
- Fixed a possible crash or garbage output on invalid or truncated UTF-8. Malformed multi-byte characters near a line-wrap boundary could cause the converter to read past the end of the text. Such input is now handled safely.
- Right-margin wrapping for non-ASCII text (output change) — words with multi-byte characters (accented letters, CJK, emoji) are now measured by display width rather than byte count, so lines wrap at the intended margin.
- Removed spurious spaces around hyperlinks (output change) — e.g.
(link)instead of( link ), and no space before punctuation following a link. - Links cross-referenced to the References list (output change) — each link is followed by a bracketed reference number matching the References list; duplicate URLs share a number.
- Ordered lists numbered correctly (output change) — items counted correctly even with stray content in an
<ol>; thestartattribute is honored. - List markers no longer leak into nested lists, and line up consistently (output change).
- Removed a leading blank line (output change) before the first heading, paragraph, or list.
🔒 Crypto — JWE, JWS, Keys
JWE — ECDH-ES key wrapping. ECDH-ES+A128KW / A192KW / A256KW now produce standards-compliant, interoperable output in all cases. The content-encryption key had been sized to twice the key-wrap key length instead of the size required by the chosen enc algorithm, so behavior depended on whether the two happened to line up:
| Outcome | Pairings |
|---|---|
| Unaffected | Valid & interoperable — “aligned” pairings: A128KW+A128CBC-HS256, A192KW+A192CBC-HS384, A256KW+A256CBC-HS512, and A128KW+A256GCM |
| Failed | CBC-HMAC enc whose required size didn’t match — e.g. A128KW+A256CBC-HS512 |
| Wrong output | AES-GCM enc pairings where sizes didn’t align (non-interoperable, or failed) |
The content-encryption key is now always generated at the correct size and wrapped correctly. Only JWEs from the affected combinations need to be regenerated; those from the unaffected pairings remain fully compatible.
JWS — CreateJwsSb serialization. Fixed: CreateJwsSb now respects PreferCompact and PreferFlattened. Previously it always produced the general JSON serialization, even when compact output was requested. To keep the old always-general output, set PreferCompact = false (and, for a single signature, PreferFlattened = false).
PrivateKey — fixes and changes (verified with RSA, P-256 EC, and Ed25519 keys)
- Fixed
SavePemFileandSavePkcs8PemFile, which had been reversed —SavePemFilenow writes the traditional representation,SavePkcs8PemFilewrites PKCS #8. - Ed25519 DER/PEM export now uses the correct OID
1.3.101.112(was sometimes the X25519 OID1.3.101.110). - Ed25519 XML from
GetXmlnow loads successfully. - JWK validation: an unsupported
ktynow fails instead of silently leaving the object empty. GetJwkThumbprint: unsupported/empty hash algorithm now fails instead of silently using SHA-1.Pkcs8EncryptAlg: names normalized consistently; unsupported/empty resets to the default3des.- EC PEM labeling corrected (
EC PRIVATE KEY,PRIVATE KEY, orENCRYPTED PRIVATE KEY) so the label agrees with the DER structure.
PublicKey — fixes and changes (verified with RSA, EC, and Ed25519 keys)
GetJwkThumbprint: unsupported/empty hash algorithm now fails instead of using SHA-1.- JWK validation now fails on missing required members, unsupported key type, or a zero RSA exponent, without leaving a partially initialized object.
LoadEd25519requires exactly 32 bytes (64 hex chars) and rejects prefixes, whitespace, and bad lengths;LoadEcdsarejects malformed/short coordinates, prefixes, whitespace, empty and all-zero values, and unsupported curves.- Standardized failure behavior across all load methods: a failed load clears the object (
Empty = true,KeyType = "empty",KeySize = 0,LastMethodSuccess = false) and preserves no previous key.
📦 MIME
Convert8Bit— MIME parts usingContent-Transfer-Encoding: 8bitorbinaryare now correctly converted to Base64, keeping the serialized MIME, childEncodingproperties, and headers consistent.UrlEncodeBody— URL-encoded text now replaces the existing body instead of being appended; invalid charset names no longer duplicate the body.RemovePart— an out-of-range index returnsfalseand leaves the tree unchanged.SetBodyFromEncoded— improved validation; rejects malformed data and unsupported encodings, preserving existing content on failure.PartsToFiles— the returnedStringTablenow contains the actual sanitized paths, and no nonexistent paths are added when extraction fails.
🔌 Sockets
SoReuseAddron Linux — the property (defaulttrue) was not being applied:SO_REUSEADDRwas never set viasetsockoptbefore the internalbind(), soBindAndListencould fail withEADDRINUSEwhen the port had a socket inTIME_WAIT(e.g. after a server restart). The option is now set prior to binding.ClientPort— now clamped to the valid range 0–65535; out-of-range values leave the property unchanged.
📧 Email — IMAP & MailMan
- Large UID handling — fixed mailboxes mixing ordinary and very large UIDs, where UID-based searches previously mishandled the large values.
Imap.FetchRange— no longer appends an emptyEmail(with an invalidckx-imap-uidof0) when requesting sequence numbers past the end of the mailbox.Imap.QueryMbxwith the specialnew-emailcriterion — a caller-suppliedMessageSetis now cleared when no new messages are found, instead of retaining prior state.Imap.GetMailFlag— now returns-1when the requiredckx-imap-*metadata is missing from theEmail.- MessageSet — improved, better-defined error handling for
FromCompactString, and improved performance for larger id sets. - Fixed a crash bug in
MailMan.FetchUidlSet.
🧮 JSON, PCRE2, Objective-C
JsonObject.StringOfEquals— case-sensitivity was reversed (behavior change). PreviouslycaseSensitive = truecompared case-insensitively and vice-versa. Now corrected:true= case-sensitive,false= case-insensitive. If you had compensated for the old behavior, review those calls.- PCRE2 — upstream bug fix (present in 10.45/10.46, fixed in 10.47).
pcre2_callout_enumerate()crashed with an out-of-bounds read on any pattern containing a Unicode character class (e.g.\p{L},\d,[[:alpha:]]in Unicode mode). Chilkat’s bundled PCRE2 now uses the corrected offset calculation. - Objective-C — 64-bit widening. Several
NSNumber-returning functions were widened to correctly represent large 64-bit sizes and counts:ContentLength64,XferByteCount64,GetSize64,GetSizeByName64,UncompressedLength64,CompressedLength64, andFileSize64.
📦 Deprecations
- Dkim — DomainKeys deprecated. The
Dkimclass’s DomainKeys-related methods and properties are deprecated. DomainKeys (an older Yahoo protocol) was superseded by DKIM, the standardized protocol used by modern email systems, and should be considered obsolete. Ftp2.DetermineSettingsandFtp2.DetermineProxyMethodare deprecated. These can be replaced with simple examples showing what the methods did internally.
🦀 Chilkat v11.6.1 — Rust: the new chilkat crate
Chilkat for Rust is new in v11.6.1: the chilkat crate on crates.io brings the full Chilkat API — all 99 classes — to Rust, with an API that follows Rust conventions.
Installation
cargo add chilkat
or add chilkat = "11.6" under [dependencies] in Cargo.toml. There is nothing to download by hand: on the first build, the crate’s build script downloads the prebuilt Chilkat static library for the build target from chilkatdownload.com, checks its SHA-256 against the checksums compiled into the crate, caches it in the user cache directory for every later build and project, and links it statically. No C or C++ compiler is needed. For build machines without internet access, set CHILKAT_LIB_DIR to a directory containing the library, and nothing is downloaded. Rust 1.70 or later is required.
Platforms
- Windows (MSVC): x64, x86, and ARM64. Each package includes the library for both the dynamic CRT (
/MD, the default) and the static CRT (/MT, used automatically with-C target-feature=+crt-static). - Linux (glibc): x86_64, aarch64, armv7, and i686.
- Alpine Linux (musl): x86_64, aarch64, armv7, and i686 — including
rust:*-alpineDocker images and fully static binaries. - macOS: Apple silicon and Intel.
A Rust API
use chilkat::{Http, JsonObject};
fn main() -> chilkat::Result<()> {
chilkat::unlock_bundle("Anything for 30-day trial")?;
let http = Http::new();
let body = http.quick_get_str("https://api.github.com/repos/rust-lang/rust")?;
let json = JsonObject::new();
json.load(&body)?;
println!("{} stars", json.int_of("stargazers_count"));
Ok(())
}
- Errors are
Results. A method that can fail returnschilkat::Result<T>:Result<()>where other languages return a success/failurebool, andResult<String>orResult<Cert>where they return a string or an object that is null on failure, so?works as usual. The error carries the object’sLastErrorTextfrom the moment of the failure, along with the class and method names, and implementsstd::error::Error. Methods that answer a question (HasMember,TagEquals,IsValid, …) return a plainbool. - Rust naming. The class names are the same (
Http,Zip,JsonObject;CkDateTimeisDateTime). Methods are snake_case (QuickGetStrisquick_get_str), and a propertyAllowGzipis the pairallow_gzip()/set_allow_gzip(..). - Ownership. Objects are created with
new()and freed when they go out of scope; there is nothing to dispose. Every method takes&self, so an object never needs to be declaredmut. Objects areSend, so one can be moved to another thread, but notSync. - Bytes are
&[u8]in andVec<u8>out. - Events.
AbortCheck,PercentDone, andProgressInfoare delivered through thechilkat::EventHandlertrait (set_event_handler) or through closures (on_percent_done(|pct| ..)). Returningtruefromabort_checkorpercent_doneaborts the running method. - No async. Chilkat calls are synchronous: the
*Asyncmethods and theTaskandTaskChainclasses are not included. From an async runtime, run Chilkat calls on a blocking thread (for example,tokio::task::spawn_blocking).
📝 Scope Chilkat for Rust is a new product; no other Chilkat product is affected. See the Chilkat for Rust page for installation, supported targets, and offline builds, the Rust reference documentation for the Rust signature of every class member, and the Rust examples. The crates are chilkat and chilkat-sys (the low-level declarations the chilkat crate is built on).
🔩 Chilkat v11.6.1 — ActiveX fix
Fixed: methods and properties added in v11.6.0 were not callable from the ActiveX.
A build problem caused a small number of members added in v11.6.0 to be left out of the ActiveX component. Applications calling them received an error such as Object doesn't support this property or method (or a similar “member not found” error, depending on the language). Everything else in v11.6.0 worked normally.
The affected members are now available:
| Class | Member |
|---|---|
| Crypt2 | Argon2DeriveKey(password, json, bdKey) — method |
| Crypt2 | Argon2HashPassword(password, json) — method |
| Crypt2 | Argon2VerifyPassword(password, json, phcHash) — method |
| JsonObject | Strict — property |
| Xml | Strict — property |
| StringBuilder | IsWellFormed(format) — method |
📝 Scope This fix affects the ActiveX only — no other Chilkat products are affected, and no application code changes are needed. If you use any of the members above, replace your v11.6.0 ActiveX with v11.6.1 and re-register it. The other changes in v11.6.1 are the Java download repackaging, the Lazarus / Free Pascal fixes, and the Perl, PHP, Ruby, and Tcl updates described next.
☕ Chilkat v11.6.1 — Java: one download per OS/architecture
The separate Java downloads for each JDK version have been replaced by a single download per operating system and CPU architecture.
Previously, Chilkat for Java was offered as a separate package for each JDK release (JDK 8, 11, 17, 21, 25, …), and each new JDK release required a new set of packages. Starting with v11.6.1 there is one package per OS/architecture, and each package works with every JDK from Java 8 up, including future releases. The chilkat.jar is compiled for Java 8 bytecode (so it loads on any later JDK), and the native JNI library uses only the JNI 1.6 interface, which every JDK since Java 6 provides and which later JDKs only extend. Pick the download for the operating system and the architecture of your JVM; the JDK version no longer matters.
- Windows:
chilkat-java-x64,chilkat-java-win32, andchilkat-java-arm64(Windows on ARM is new in this release). - Linux, Alpine Linux, and macOS:
chilkatjava-<arch>-linux,chilkatjava-<arch>-alpine, andchilkatjava-<arch>-macosx. - Android is unchanged.
📝 Scope This is a packaging change only. The com.chilkatsoft package, class names, and method signatures are identical to v11.6.0, so no application code changes are needed — simply replace the old chilkat.jar and native library with the new ones. JDK 6 and JDK 7 are no longer supported. See the Chilkat for Java download page.
🧡 Chilkat v11.6.1 — Lazarus / Free Pascal fixes
Fixes for the Chilkat for Lazarus/FPC API introduced in v11.6.0.
📂 What changed These are fixes to the .pas source files — the Chilkat.*.pas wrapper units in the Chilkat for Lazarus/FPC download. The C bridge shared libraries (chilkat_c_bridge_*.dll, libchilkat_c_bridge_*.so, libchilkat_c_bridge.dylib) are unchanged. To upgrade, replace the .pas files in your project with those from the v11.6.1 download and rebuild; there is no need to replace the shared library.
.pas files that would not compile
Four of the .pas units failed to compile:
- Chilkat.Crypt2 —
SetIVandSetSecretKeywere each declared twice without theoverloaddirective. - Chilkat.Gzip — the same problem with
SetExtraData. - Chilkat.Mcp —
CallToolhad a parameter namedresult, which collides with a function’s implicitResult. - Chilkat.SFtp — methods taking an SFTP file handle declared two parameters named
handle.
In the v11.6.1 .pas files, argument names that collide with a Pascal reserved word, with a type used in the signature, or with an identifier used internally by the wrapper are renamed with an A prefix (result becomes Aresult), and a method name declared more than once in a class carries the overload directive.
“Entry point not found” at program startup
The Chilkat.Crypt2, Chilkat.Dsa, Chilkat.Gzip, Chilkat.HttpResponse, and Chilkat.Xml .pas files declared bridge functions that the Chilkat shared library does not export. Those are resolved in each unit’s initialization section, so any program using one of these units raised Entry point not found before reaching the first line of application code — even though the project compiled cleanly.
The affected members have been removed from the .pas files:
- The byte-array properties
TCrypt2.IV,TCrypt2.Salt,TCrypt2.SecretKey,TDsa.Hash,TDsa.Signature,TGzip.ExtraData, andTHttpResponse.Body. Use the encoded-string equivalents instead —SetEncodedIV,SetEncodedKey,SetEncodedSalt,SetEncodedHash,SetEncodedSignature,SetExtraData(encodedData, encoding)— or, for the HTTP response body,GetBodyBd. TXml.SearchForTag,SearchForContent,SearchForAttribute,SearchAllForContent, and their2variants.
The reference documentation was updated to match, and no longer lists the removed properties and methods.
✅ Result With the v11.6.1 .pas files, all 99 Chilkat classes compile, load, and instantiate.
🐪 Chilkat v11.6.1 — Perl: New Perl versions, and a slimmer platform matrix
Chilkat for Perl adds support for Perl 5.42 and 5.44, and the 32-bit x86 and armv7l builds have been retired on Linux and Alpine Linux.
String arguments accept any defined scalar
Where a method expects a string, you can now pass any defined Perl scalar and Chilkat uses its string value, exactly as Perl itself would — a number, for example, no longer has to be converted to a string first.
New Perl versions, and a slimmer platform matrix
Chilkat for Perl now builds for Perl 5.42 and 5.44 in addition to the earlier versions, including a 5.42 build for Windows (Strawberry Perl). On Linux, Alpine Linux, and macOS each platform offers both a standard module and a Perl with Threads module (pick the one matching your perl); 64-bit Alpine Linux now offers the Perl with Threads build as well.
The 32-bit downloads have been retired on Linux and Alpine Linux: the x86 (32-bit) and armv7l Perl modules are no longer produced, leaving x86_64 and arm64 on both. Builds for earlier Chilkat versions remain available on the older-versions page.
📝 Scope The Perl API is unchanged — the same chilkat::CkXxx classes and methods — so existing scripts run as-is. To upgrade, replace the Chilkat Perl module (chilkat.pm and its shared library) with the one from the v11.6.1 download for your Perl version and platform. See the Chilkat Perl download page.
🐘 Chilkat v11.6.1 — PHP: A rebuilt extension, one-command installation, and a slimmer platform matrix
The PHP extension has been rebuilt on an improved code generator, a stub file has been added for IDE autocompletion, and the 32-bit Alpine Linux builds have been retired.
A rebuilt extension
The layer that connects PHP to the native Chilkat library — the code that turns a PHP method call into a call on the underlying library and converts the arguments and return values — is new in v11.6.1. It is now produced by an improved code generator that works directly from the Chilkat API definition, replacing the previous SWIG-based generator. This keeps the PHP extension in step with the rest of the library and makes it easier to maintain and fix.
This is a change of implementation, not of functionality: the same CkXxx classes, the same method names, the same arguments and return values, behaving as they did before. Your scripts still include 'chilkat.php' exactly as before, and no application code changes are needed.
IDE autocompletion
Each download now includes a chilkat_stubs.php file alongside chilkat.php. It declares the same classes and methods with their parameter and return types but no bodies, so editors and IDEs can offer autocompletion, argument hints, and type information as you write. It is for tooling only and is never included at runtime — your scripts continue to include chilkat.php as before.
One-command installation
Installing the PHP extension used to mean choosing the right download for your PHP version, CPU, and thread-safety, finding extension_dir, and editing php.ini. That is now automated in two ways:
Composer. The extension is on Packagist as chilkat/chilkat. The package provides the CkXxx classes through Composer's autoloader (one class per file, so only what a script uses is loaded, with PHPDoc for IDE autocompletion) and a command that installs the native extension for the PHP that runs it:
composer require chilkat/chilkat
vendor/bin/chilkat-install
chilkat-install detects the PHP version, architecture, and thread-safety, downloads the matching build, verifies its SHA-256, places chilkat.so/chilkat.dll in extension_dir, enables it (phpenmod on Debian/Ubuntu, a conf.d entry on Alpine, RHEL, Homebrew and the official Docker images, or php.ini on Windows), and verifies that a fresh PHP loads it. --dry-run shows what would be done, --uninstall reverses it. The package version is the Chilkat version, so the classes and the extension always match, and composer update followed by chilkat-install upgrades both.
Without Composer. The same installer exists as a shell script for Linux, Alpine Linux and macOS, and a PowerShell script for Windows:
curl -fsSL https://chilkatdownload.com/php/install-php.sh | sudo sh
irm https://chilkatdownload.com/php/install-php.ps1 | iex
The manual download-and-configure steps remain on the install pages for anyone who prefers them.
A slimmer platform matrix
The 32-bit Alpine Linux downloads have been retired: the x86 (32-bit) and armv7l Alpine PHP extensions are no longer produced, leaving x86_64 and arm64 on Alpine Linux. The 32-bit x86 and armv7l builds for standard (glibc) Linux are unchanged. Builds for earlier Chilkat versions remain available on the older-versions page.
📝 Scope The PHP API is unchanged — the same CkXxx classes and methods — so existing scripts run as-is. To upgrade, run composer update chilkat/chilkat && vendor/bin/chilkat-install, re-run the install script, or replace the Chilkat PHP files (chilkat.php and the extension, chilkat.dll or chilkat.so) with those from the v11.6.1 download for your PHP version and platform. See the Chilkat PHP download page.
🐍 Chilkat v11.6.1 — Python (CkPython): A rebuilt extension, one download for every Python 3.7+, and Windows ARM64
The CkPython extension (the chilkat module) has been rebuilt on an improved code generator and now targets the CPython stable ABI, so one download per platform works with every Python from 3.7 onward. Windows ARM64 is new; Python 3.6 and earlier, and the 32-bit x86 and armv7l Alpine builds, have been retired.
A rebuilt extension
The layer that connects Python to the native Chilkat library — the code that turns a Python method call into a call on the underlying library and converts the arguments and return values — is new in v11.6.1. It is now produced by an improved code generator that works directly from the Chilkat API definition, replacing the previous SWIG-based generator. This keeps the Python extension in step with the rest of the library and makes it easier to maintain and fix.
This is a change of implementation, not of functionality: the same CkXxx classes, the same method names, the same arguments and return values, the same ownership rules for returned objects, the same overridable progress classes (CkBaseProgress, CkHttpProgress, …) and the same error messages. Your scripts still import chilkat exactly as before, and no application code changes are needed.
One download works with every Python from 3.7 onward
Until now each Chilkat Python download was built for exactly one Python version — a separate package for 3.12, 3.13, 3.14, and so on, per operating system and processor — and a new Python release meant waiting for a matching Chilkat build. The v11.6.1 extension is built against the CPython stable ABI (the limited API of Python 3.7), so a single _chilkat.pyd or _chilkat.so loads into any CPython from 3.7 on, including versions released after the build.
The download names no longer carry a Python version: chilkat-python-x64.zip, chilkat-python-x86_64-linux.tar.gz, chilkat-python-arm64-macosx.tar.gz, and so on — one per operating system and processor. installChilkat.py copies the module into the site-packages of whichever Python runs it, so the same download can be installed into several Python versions on one machine. On PyPI, pip install chilkat now installs a single cp37-abi3 wheel per platform instead of one wheel per Python version.
Platforms
- New: Windows ARM64. A native build for an ARM64 Python on Windows on ARM (
chilkat-python-arm64). An x64 Python running under emulation continues to use the 64-bit build. - Retired: Python 3.6 and earlier, including Python 2.7. The stable-ABI module requires Python 3.7 or later. The last builds for older Pythons (Chilkat v11.6.0) remain available at their existing download links but receive no further updates.
- Retired: 32-bit x86 Linux, 32-bit x86 Alpine Linux, and armv7l Alpine Linux. The remaining platforms are Windows (x64, win32, ARM64), Linux (x86_64, aarch64, armv7l — the 32-bit ARM build for Raspberry Pi stays), Alpine Linux (x86_64, aarch64), and macOS (Apple silicon, Intel).
Fixes
- The 64-bit event parameters — the byte counts in
UploadRateandDownloadRate, and the sizes inNextTarFile— are now passed correctly on 64-bit Linux, where these events previously did not reach the Python handler. CkByteData.getRangenow returns the requested range rather than the data from the start.CkBinData.GetDataChunkis clamped to the buffer, andCkBinData.AppendDataaccepts only bytes-like data, with the length clamped to the object passed, instead of reading past it.- A progress object passed to
put_EventCallbackObjectis now kept alive by the Chilkat object for as long as it may be called back. Previously a script that dropped its own reference could have events delivered to a freed object. - The result of
__disown__()can be passed directly toput_EventCallbackObject, as in the SWIG-era examples. - The module no longer exports the library’s internal symbols: the files are smaller and import faster.
📝 Scope The Python API is unchanged — the same chilkat.CkXxx classes and methods — so existing scripts run as-is on Python 3.7 or later. To upgrade, run pip install --upgrade chilkat, or replace chilkat.py and the extension (_chilkat.pyd or _chilkat.so) with those from the v11.6.1 download for your platform — there is no longer a separate download per Python version. See the Chilkat Python download page.
Chilkat v11.6.1 — Ruby: A rebuilt extension, and Ruby 3.2 retired
The Ruby extension has been rebuilt on an improved code generator, and Ruby 3.2 has been retired.
A rebuilt extension
The layer that connects Ruby to the native Chilkat shared library — the code that turns a Ruby method call into a call on the underlying library and converts the arguments and return values — is new in v11.6.1. It is now produced by an improved code generator that works directly from the Chilkat API definition, which keeps the Ruby extension in step with the rest of the library and makes it easier to maintain and fix.
This is a change of implementation, not of functionality: the same classes, the same method names, the same arguments and return values, behaving as they did before. No application code changes are needed.
Ruby versions
Chilkat for Ruby builds for Ruby 3.3, 3.4, and 4.0. Ruby 3.2 reached end-of-life in April 2026 and its downloads have been retired; builds for earlier Chilkat versions remain available on the older-versions page.
📝 Scope The Ruby API is unchanged — the same Chilkat::CkXxx classes and methods — so existing scripts run as-is. To upgrade, install the v11.6.1 gem for your Ruby version and platform. See the Chilkat Ruby download page.
📜 Chilkat v11.6.1 — Tcl: Tcl 9.0 on Windows, and UTF-8 by default
Tcl 9.0 is now available for Windows, a Windows download now works with any distribution of its Tcl line, and non-ASCII text no longer needs extra setup.
Chilkat for Tcl already offered Tcl 9.0 builds for Linux, macOS, and Alpine Linux. v11.6.1 adds a Tcl 9.0 build for 64-bit Windows, so both the Tcl 8.6 and Tcl 9.0 lines are now available on every supported platform.
Windows: one download per Tcl line and CPU architecture
32-bit and 64-bit are still separate downloads, as they must be — a 32-bit tclsh can only load a 32-bit DLL, and a 64-bit one only a 64-bit DLL. What changed is that 64-bit Tcl 8.6 no longer needs two of them.
Windows Tcl distributions disagree about what the core library is called: some ship tcl86.dll and others tcl86t.dll, so Chilkat published chilkat-tcl8.6-x64 for the first and a second package, chilkat-tcl8.6.7-x64, for the other. The v11.6.1 extension binds to whichever interpreter loads it rather than to a particular core library file name, so one chilkat-tcl8.6-x64 now works with any Tcl 8.6 distribution, including future patch releases. chilkat-tcl8.6.7-x64 has been removed.
- Windows:
chilkat-tcl9.0-x64(new in v11.6.1),chilkat-tcl8.6-x64, andchilkat-tcl8.6-win32. Tcl 9.0 on Windows is 64-bit only. - Linux, Alpine Linux, and macOS: unchanged — Tcl 8.6 and Tcl 9.0 builds for each architecture.
Strings are UTF-8 by default
Tcl passes strings to an extension as UTF-8, but Chilkat objects used to start with the Utf8 property turned off, so a script had to turn it on itself — on each object, or once through the global default:
set http [new_CkHttp]
CkHttp_put_Utf8 $http 1 ;# no longer necessary
Leaving it out silently corrupted any text outside the ASCII range. In v11.6.1 every Chilkat object is created with Utf8 already on, which is the correct setting for Tcl. Scripts that set it themselves keep working — the call is simply redundant now — and ASCII-only scripts are unaffected.
📝 Scope The Tcl command set is unchanged — the same command names taking the same arguments — so existing scripts run as-is. To upgrade, replace the Chilkat shared library (chilkat.dll, chilkat.so, or chilkat.dylib) with the one from the v11.6.1 download for your Tcl version and platform. Tcl 8.4 and Tcl 8.5 are no longer supported — the minimum is Tcl 8.6. See the Chilkat Tcl download page.
For previous versions and archived updates, visit the Release Notes Archive.