Nim version 2.2.14 released

The Nim Team is happy to announce version 2.2.14, the seventh patch release for our stable release, Nim 2.2.

It comes seven weeks after the 2.2.12 release and it contains 142 commits, bringing bugfixes and improvements.

If you’re still on Nim 1.6, take a look at the version 2.0 release article to see all the features you’re missing. If you’ve been using Nim 2.0, the version 2.2 release article shows the improvements available in Nim 2.2.

Installing Nim 2.2.14

Check out if the package manager of your OS already ships version 2.2.14 or install it as described here.

If you have installed a previous version of Nim using choosenim, getting Nim 2.2.14 is as easy as:

$ choosenim update self
$ choosenim update stable

NOTE: We recommend that you install and use the latest version of choosenim, v0.8.16, available in our choosenim repo.

Alternatively, you can download Nim 2.2.14 from our nightlies builds.

Security fixes

This release hardens several standard library modules against malicious input:

  • httpclient: on a redirect that leaves the origin (scheme, host, port) of the requested URL, the Authorization, Cookie and Host headers are now dropped, so a server can no longer redirect the client to a host it controls and read its credentials. (STD-001)
  • asynchttpserver: request bodies are now always read completely. Chunked bodies of methods other than POST, chunk extensions and trailer fields could previously be parsed as the next request on the connection, which allowed request smuggling behind a reverse proxy. (STD-002)
  • asynchttpserver: requests with ambiguous body framing (both Content-Length and Transfer-Encoding, repeated or malformed Content-Length, unknown transfer codings, whitespace before the colon) are now rejected following RFC 9112, section 6.3. (STD-003)
  • net, asyncnet: when a TLS client connects to an IP address, the address is now checked against the certificate’s IP SANs. Previously any certificate signed by a trusted CA was accepted. (STD-004)
  • cmdline: parseCmdLine (and thus parseopt.initOptParser(string)) no longer loops forever and exhausts memory on control characters. (STD-005)
  • httpclient: CR, LF and NUL in the request target, the Host header and header fields now raise ValueError instead of allowing header and request injection. (STD-006)
  • xmlparser, htmlparser: the nesting depth is now limited (xmlMaxDepth, 256, and htmlMaxDepth, 512, both {.intdefine.}s), so deeply nested input can no longer exhaust the stack. (STD-007)
  • xmltree: the output of $ is no longer quadratic in the nesting depth; indentation stops growing at 80 columns. (STD-008)
  • httpclient: chunk sizes that overflow an int now raise ProtocolError instead of wrapping around and misframing the body. (STD-009)

Additionally, asyncnet now verifies the TLS hostname (#26455).

Bugfixes

  • Fixed “[GCASSERT] incRef: interiorPtrTraceback/SIGSEGV with closure iterator iterating over tuples in refc” (#26158)
  • Fixed “cyclic ref type with lifetime extend beyond nested function calls setting it creates UB in ORC” (#26172)
  • Fixed “nim js: explicit {.closure.} on a lambda with parameters crashes codegen” (#26176)
  • Fixed “wrapWords(splitLongWords = true) drops the separator before a word it has to split” (#26183)
  • Fixed “Closure iterator local released at yield instead of scope exit” (#26041)
  • Fixed “Nim 2.2.12 compiler SIGSEGV with –exceptions:setjmp in try/except/finally” (#26189)
  • Fixed “TSlice returned by template as an expr does not work in range[]” (#560)
  • Fixed “strutils.rsplit mishandles overlapping separators” (#24949)
  • Fixed “Wrong sizeof computed on linux for certain types (abi mismatch)” (#26220)
  • Fixed “vm: cast to distinct pointer broken” (#26213)
  • Fixed “sizeof miscomputed in object with void fields” (#26225)
  • Fixed “Provide an alternative format for error/warning messages; eg: file:line:col instead of file(line, col)” (#690)
  • Fixed “AST: nkIfExpr missing typ” (#26218)
  • Fixed “memory leak with nested Exceptions via function” (#25037)
  • Fixed “Closure environment is moved (=wasMoved) while still live: SIGSEGV on a later read” (#26247)
  • Fixed “Duplicate/redundant nimZeroMem() in --mm:refc” (#23383)
  • Fixed “Document isMainModule and appType for libraries” (#17496)
  • Fixed “Wrong sizeof computation in sizeof test” (#26255)
  • Fixed “nimsuggest, nim check: nimbus-eth1: SIGSEGV: Illegal storage access. (Attempt to read from nil?)” (#26244)
  • Fixed “type T[P]=proc{.f.} in nim check triggers unhandled exception: field 'sym' is not accessible for type 'TNode' using 'kind = nkIdent' ” (#26260)
  • Fixed “std/uri , removeDotSegments: i advancement incorrectly conditional on stack being non-empty” (#26259)
  • Fixed “when expression not considered as such in type section” (#26272)
  • Fixed “74f4042f8 (#24867) causes significant compile-time regression” (#26349)
  • Fixed “TSAN-detected data race on ARM64 Linux with createThread/joinThread with ORC and refc” (#26354)
  • Fixed “Object constructor with an array field reading the destination gives a wrong value” (#26329)
  • Fixed “importc distinct pointer shares C typedef with pointer in proc types” (#26312)
  • Fixed “–debugger:native: unreachable assertion with default static generic parameters” (#26336)
  • Fixed “Generic instantiation treats different importc aliases of pointer as identical” (#26311)
  • Fixed “Closure iterator with try/except and yield SIGSEGVs then hangs” (#26337)
  • Fixed “VM memory leak during compilation in iterating over seq elements” (#26273)
  • Fixed “nimsuggest: def not working properly with ./[module1, module2] syntax” (#26307)
  • Fixed “Closure iterator: yield inside an expression pragma block crashes the compiler” (#26335)
  • Fixed “Closure iterator: case on an if expression skips all branches” (#26324)
  • Fixed “getTypeImpl of generic ref object instance has uninstantiated field types” (#26374)
  • Fixed “Assigning to moved-from nested case object frees the moved seq” (#26369)
  • Fixed “marshal.load into a reset case object writes through a freed string” (#26370)
  • Fixed “strutils.formatFloat uses a 2500 character buffer for sprintf output” (#26330)
  • Fixed “arc/orc: add of an empty string to a literal-backed string leaves no NUL terminator” (#26411)
  • Fixed “vccplatform() missing cpuArm64 case — Windows ARM64 builds fail with LNK1112” (#26434)
  • Fixed “Windows/ARM64 with MSVC: dragonbox uses the x64-only _umul128 intrinsic (LNK2019)” (#26250)
  • Fixed “Closure iterator SIGSEGV: nested try with yield inside except” (#26291)
  • Fixed “{.push checks: off.} around an import disables checks in the imported module” (#26431)
  • Fixed “vccexe: –platform:arm64 and –platform:arm crash with “Invalid enum value” — the stock tool rejects the flags extccomp emits for ARM targets” (#26453)
  • Fixed “Cannot resolve pragmas when new type is defined from typeof expression” (#25140)
  • Fixed “hasCustomPragma fails on field inherited from generic object” (#26372)
  • Fixed “hasCustomPragma ignores fields declared under when” (#26373)
  • Fixed “hasCustomPragma hits VM iteration limit for typeof alias of generic instance” (#26400)
  • Fixed “devel Regression: getTypeImpl returns a symbol for a typeof alias of a generic instance” (#26412)
  • Fixed “ARC/ORC: Option value freed while variable in outer scope aliases it” (#26461)
  • Fixed “finally sees a variable assigned from a call that raised in –mm:orc” (#26333)
  • Fixed “False 'cmd' should be: 'Cmd' styleCheck error for a field type taken from getTypeImpl” (#26464)
  • Fixed “unicode.strip raises IndexDefect on a string ending in a truncated UTF-8 sequence” (#26415)
  • Fixed “unicode.splitWhitespace() and strutils.splitWhitespace() have different results for ASCII string” (#23619)
  • Fixed “Issue with insertSep function in strutils” (#24788)
  • Fixed “xmltree does not escape newlines but prevents them from being escaped” (#24062)
  • Fixed “Compiler crashes with IndexDefect on O[] as a parameter type” (#26477)
  • Fixed “getCursorPos() from std/terminal is off by one on POSIX” (#26301)
  • Fixed “parseXml unexpectedly creates xnText nodes after encountering an xml comment” (#25462)
  • Fixed “asyncnet: TLS hostname is never verified on any platform — AsyncSocket and AsyncHttpClient accept any CA-valid certificate for any hostname” (#26455)
  • Fixed “times.parse raises RangeDefect instead of TimeParseError for minute 60-99 or second 61-99” (#26408)
  • Fixed “signalHandler hangs with –gc:boehm when the signal comes from inside Boehm (GC_disable deadlocks)” (#26513)
  • Fixed “Method call on a var-param call passes the argument by value” (#26521)
  • Fixed “-d:useMalloc doesn’t check malloc/calloc/realloc for nil outside Zephyr” (#26331)
  • Fixed “seq[var T].mitems() uses incorrect element stride for variant case-object T with 2+ elements, causing writes to the wrong element’s memory” (#26058)
  • Fixed “Pragma alias expands to p() instead of p after its first use” (#26473)
  • Fixed “Bad error message for forbids violation” (#25978)
  • Fixed “refc: =dup of a seq whose element type has a hook returns an empty seq” (#26540)
  • Fixed “Regression from 2.2.x to version-2-4/devel in doAssert [0].items.typeof is int” (#26547)
  • Fixed “[Regression 2.2.12 –> 2.2.13/2.4/devel] refc: GC marker reads uninitialized Deque slots of case objects” (#26539)
  • Fixed “refc: resetting a case object zeroes GC-free arrays element by element” (#26552)

The complete list of changes is available here.