GNOME has no thumbnails in the file picker (and my toilets are blocked)
The file picker is the pop-up box thingy that appears when you’re opening a file, usually when uploading something online. The GNOME desktop environment uses the file picker package GtkFileChooser. This file picker does not have a thumbnail view. It is broken software. Thumbnails are not a cute little extra, they are essential. This is as bad as a file picker that doesn’t list the name of the files, only their creation date, or inode serial number. It is broken software.
Personally, not a big deal, but fair point.
Sandboxing and Workload Isolation
Workload isolation makes it harder for a vulnerability in one service to compromise every other part of the platform. It has a long history going back to 1990s qmail, and we generally agree that it’s a good, useful thing.
From chroot to privsep to docker to firecracker.
Against essential and accidental complexity
In the classic 1986 essay, No Silver Bullet, Fred Brooks argued that there is, in some sense, not that much that can be done to improve programmer productivity. His line of reasoning is that programming tasks contain a core of essential/conceptual1 complexity that’s fundamentally not amenable to attack by any potential advances in technology (such as languages or tooling). He then uses an Ahmdahl’s law argument, saying that because 1/X of complexity is essential, it’s impossible to ever get more than a factor of X improvement via technological improvements.
To summarize, Brooks states a bound on how much programmer productivity can improve. But, in practice, to state this bound correctly, one would have to be able to conceive of problems that no one would reasonably attempt to solve due to the amount of friction involved in solving the problem with current technologies.
The Easy Ones – Three Bugs Hiding in the Open
If everyone on a project spends all of their time heads-down working on the features and known bugs then there are probably some easy bugs hiding in plain sight. Take some time to look through the logs, clean up compiler warnings (although, really, if you have compiler warnings you need to rethink your life choices), and spend a few minutes running a profiler. Extra points if you add custom logging, enable some new warnings, or use a profiler that nobody else does.
Why software ends up complex
Every feature request has a constituency – some group who wants it implemented, because they benefit from it. Simplicity does not have a constituency in the same way, it’s what economists call a non-excludable good – everyone benefits from it. This means that supporters can always point to concrete benefits to their specific use cases, while detractors claim far more abstract drawbacks. The result is that objectors to any given feature adition tend to be smaller in number and more easily ignored. Leading to constant addition of features, and subtraction of simplicity.
I agree with the premise, but challenge the idea that it’s not possible to deny feature requests.
retvals, terrible teaching, and admitting we have a problem
Really though, this is everywhere. It’s not just that one class. It’s not just that one school. It shows up all over the place. The vast majority of pages about this kind of stuff manage to convey it incorrectly. It’s clear that not only is the horse out of the barn, but the cat is out of the bag, and the whole damn menagerie has cut loose and is running down Broadway singing show tunes. You just can’t expect people to do the right thing when the right thing is implemented this way. Too many people have voted with their feet and have decreed that they are just going to not check, and whatever happens, happens.
What went wrong with the libdispatch. A tale of caution for the future of concurrency.
The future was multithreading and we had to use the libdispatch to get there. So we did.
As we went down that rabbit hole, things got progressively worse.
Rust after the honeymoon
So Rust is going really well for us at Oxide, but for the moment I want to focus on more personal things — reasons that I personally have enjoyed implementing in Rust. These run the gamut: some are tiny but beautiful details that allow me to indulge in the pleasure of the craft; some are much more profound features that represent important advances in the state of the art; and some are bodies of software developed by the Rust community, notable as much for their reflection of who is attracted to Rust (and why) as for the artifacts themselves.
Reconstruct Instead of Validating
What I want to focus on is (2), because it’s a lesson we learned the hard way in cryptography and didn’t transfer effectively to the rest of security engineering.
One of my favorite cryptographic attacks is the Bleichenbacher‘06 signature forgery. I wrote up how it works when I found it in python-rsa, so again go read that, but here’s a tl;dr. When you verify an RSA PKCS#1 v1.5 signature, you get a ASN.1 DER structure wrapping the message hash that you need to check. If you don’t parse it strictly, for example by allowing extra fields or trailing bytes, an attacker can fake the signature. This was exploited countless times.
The lesson we learned was that instead of parsing the ASN.1 DER to extract the message hash, we should reconstruct the ASN.1 DER we’d expect to see, and then simply compare it byte-by-byte.
The same technique would have saved Vault.
Rust programming language exploit mitigations
This section documents the exploit mitigations applicable to the Rust compiler when building programs for the Linux operating system on the AMD64 architecture and equivalent.
Zig's New Relationship with LLVM
In the early days, Zig was but a thin frontend in front of LLVM. This was instrumental for getting started quickly and filling in gaps of Andrew’s knowledge as a compiler developer. Now, the training wheels of the bicycle are coming off, and LLVM is transitioning into an optional component.
The move to a self-hosted compiler for Zig has similar advantages for the core contributors, but it also makes LLVM an optional dependency, increases compilation speed (instead of losing it), and adds an amazing feature for debug builds of your code: incremental compilation with in-place binary patching, another unique Zig feature.
.NET Memory Performance Analysis
This document aims to help folks who develop applications in .NET with how to think about memory performance analysis and finding the right approaches to perform such analysis if they need to. In this context .NET includes .NET Framework and .NET Core. In order to get the latest memory improvements in both the garbage collector and the rest of the framework I strongly encourage you to be on .NET Core if you are not already, because that’s where the active development happens.
When I was writing this document I intended to introduce concepts like concurrent GC or pinning as needed by the explanation of the analysis. So as you read it, you’ll gradually come across them. If you already kind of knew what they are and are looking for explanation on a specific concept here are the links to them
The Door Problem
Game design is one of those nebulous terms to people outside the game industry that’s about as clear as the “astrophysicist” job title is to me. It’s also my job, so I find myself explaining what game design means to a lot of people from different backgrounds, some of whom don’t know anything about games.
I like to describe my job in terms of “The Door Problem”.
This is a fun read.
Rolling your own crypto gone wrong: A look at a .NET Branca implementation
This is a pretty good example of code that probably looks decent to a casual inspection, and seems to call functions with the right names, etc., but it’s pretty bad.
"Rust does not have a stable ABI"
Or more exactly, why does this happen, and why do people perceive it as a problem?
I still believe it would be possible to build a high quality editor based on the original design. But I also believe that this would be quite a complex system, and require significantly more work than necessary.
A few good ideas and observations could be mined out of this post.
Improving Chromium's browser compatibility in 2020
It is clear that it is still painful to develop a website or web app that works reliably across browsers.
How to Put More “Character” Into Your NPCs
There’s something about the term “NPC” (Non-Player Character) that sounds hollow to me. Maybe it’s the ambiguousness of acronyms, or how the term literally sounds like “empty.” As a narrative designer, my philosophy is to think of NPCs less like assets on a spreadsheet, and more like my cast. There are big and small parts, but I believe designers can give any character soul. (Even a character whose soul was stolen by an evil wizard of some sort!) A bit more effort can make a minor NPC more human, and a game’s world more alive.
The Deprecated *nix API
But for “*nix”, without any clarifying context, I for one think in terms of shell scripts and their utilities. And the problem is that my own naïve scripts, despite being written on a legit *nix variant, simply will not run on a vanilla Linux, macOS, or *BSD installation. They certainly can—I can install fish, and sd, and ripgrep, and whatever else I’m using, very easily—but those tools aren’t available out-of-the-box, any more than, I dunno, the PowerShell 6 for Linux is.
The Success and Failure of Ninja
Ninja has been by far my most successful open source project, depending on how you quantify success. (Other projects of mine like Chrome have more users, but I was responsible for only parts of Chrome; Ninja also has had important contributions by collaborators but it feels more like “mine”.) I released Ninja in 2011, gave ownership of the Ninja project away in 2014, and it has since been passed on again to a third maintainer, so now that my part in the story is pretty much over I here would like to reflect on what I learned.