C3 0.8.1 released: Raiding the stdlib for bugs

birdculture1 pts0 comments

C3 0.8.1 Raiding the stdlib for bugs - C3 Programming Language Skip to content

Initializing search

Language Overview<br>C to C3<br>Language Fundamentals<br>Language Common<br>Generic Programming<br>Build Your Project<br>Language Rules<br>Misc Advanced<br>Implementation Details<br>FAQ

Get Involved

Thank You

Single Page Docs<br>📖 Standard Library<br>Blog

Stdlib changes

Fixes<br>Summarizing<br>Thank yous

C3 0.8.1 Raiding the stdlib for bugs<br>"Bug fixes" is probably the least exciting thing you can lead with, but after 0.8.0 settled things in the language, it was natural to spend 0.8.1 hunting bugs.<br>Quite a few were found: over 100 fixes landed — most being corner cases, but a few are real, including a textbook Zip-Slip vulnerability in the zip extractor(!).<br>Outside of compiler development, there's also been significant progress on the specification here, which is necessary for C3 to be able to sign off on 1.0 in two years.<br>Language changes&para;<br>Access reflected fields using a.$field and a.$field = b.&para;<br>Previously, you could mutate and access fields on a struct by using $field.get(struct_value) and $field.set(struct_value, new_field_value). This is replaced by a much more streamlined struct_value.$field and struct_value.$field = new_field_value with the old variants deprecated:<br>struct Foo<br>int i;<br>bool b;

fn void test()<br>var $field = $reflect(Foo.i);<br>Foo f = { 45, true };<br>// 0.8.0 prints 45<br>io::printn($field.get(f));<br>// 0.8.1 prints 45<br>io::printn(f.$field);<br>// 0.8.1 alternative syntax, also prints 45<br>io::printn(f.$eval($reflect(Foo.i)));

// 0.8.0 sets f.i to 44<br>$field.set(f, 44);<br>// 0.8.1 sets f.i to 44<br>f.$field = 44;<br>// 0.8.1 alternative syntax<br>f.$eval($reflect(Foo.i)) = 44;

Access to project path at compile time&para;<br>env::PROJECT_PATH now returns the path to the project at compile time. This is mainly useful with $embed and similar compile time commands.<br>$vaarg[^1] supported&para;<br>macro foo(...)<br>// 0.8.0<br>var x = $vaarg[$vaarg.len - 1];<br>// 0.8.1 – with ^ support<br>var x = $vaarg[^1];

Stdlib changes&para;<br>Changes to API:&para;<br>LinkedHashMap renamed OrderedMap, LinkedHashSet renamed OrderedSet. Old names are deprecated.<br>Enhanced path::ls functionality: it now supports wildcard search.<br>ini::parse and related take an error_line argument to identify the line with error.<br>Stricter JSON marshaling: it will return INVALID_NUMBER when encountering an inf or NaN for a float, and reject 1. literals.<br>@loop_over_ai would leak fds, deprecated and replaced by @loop_over_addresses.<br>spawn now allows binding I/O and using different settings per pipe.<br>io::write_all now retries on incomplete writes.<br>FixedThreadPool and ThreadPool are deprecated; they will be replaced by a new thread pool in a later 0.8.x version.<br>Additions to the stdlib&para;<br>Concurrency & Threads&para;<br>The BufferedChannel and UnbufferedChannel both gained non-blocking push/pop, using try_push and try_pop. In addition, UnboundedChannel was added. Such a channel will grow on demand, unlike BufferedChannel which has a fixed size.<br>This release also offers a preview of ThreadGroup for running tasks in parallel and collecting the results.<br>Platform support&para;<br>libc::errno is now available on FreeBSD.<br>Compile time&para;<br>The new values::expand macro turns strings containing expressions into values. This can be useful in some cases, as $reflect only creates statements.<br>Fixes&para;<br>The 0.8.1 release contains over 100 fixes to stdlib, almost exclusively on the stdlib. The vast majority are stdlib corner cases.<br>The largest category is encoding and parsing : UTF-8/16/32 conversion edge cases (BOM handling, surrogate pairs, length detection), JSON's float precision and surrogate pair handling, varint signed-integer round-trips, base32/base64/codepage encoders that leaked memory on error, and PEM parsing on malformed input.<br>Memory management got a sweep. BackingArenaAllocator, DynamicArenaAllocator, OnStackAllocator, and the Vmem temp allocator each had at least one bug in a realloc, calloc, or destroy path. SortedMap had a possible array overflow. Deque.free didn't reset capacity, leaving the struct in a state that crashed on reuse. Wasm allocation could over-reserve unnecessarily.<br>Threading and synchronization got a check too: __atomic_compare_exchange had an incorrect implementation, lock_timeout on POSIX would sleep the full requested duration on every retry, the stack_size setting for thread creation was ignored on POSIX, and thread priority on Win32 was off by one. UnbufferedChannel could yield unpredictable values because its memory wasn't zeroed at creation.<br>Security : the Zip extraction code had a textbook Zip-Slip vulnerability — a malicious archive could write outside the target directory via .. components, absolute paths, or sibling-prefix paths in entry names. Fixed with up-front rejection of obviously-bad names plus a post-normalization containment check.<br>A handful of small correctness fixes touched types people use every day: DateTime.diff_years now handles leap years correctly,...

para field stdlib language fixes bugs

Related Articles