Has updating the Go compiler actually been an issue for you in the past? To me, with Go's stability, it's never been more disruptive than updating a library in practice, so I don't see much of a difference.
Has updating the Go compiler actually been an issue for you in the past? To me, with Go's stability, it's never been more disruptive than updating a library in practice, so I don't see much of a difference.
I've run into issues with several go version updates.
Off the top of my head, all of the following caused breakages:
1. go 1.4 making directories named 'internal' special and un-importable. Cross-package imports that used to work no longer would compile with a compiler error.
2. go 1.9 adding monotonic clock readings in a breaking way, i.e. this program changed output from 1.8 to 1.9: https://go.dev/play/p/Mi6cGCPd0rS (I know it looks contrived, but I'm not digging up the actual code that broke)
3. The change of the http.Server default to serving http2 instead of http/1.1 broke stuff. Of course it did. How can that possibly _not_ break stuff?
4. The changes in 'GO111MODULE' defaults broke many imports which had either malformed or incorrect go.mod files. This one was quite painful for the whole ecosystem.
5. go1.17 switched to silently truncating a lot of query strings. Of course that broke stuff, how could it not? https://go.dev/play/p/azODBvkb-zK
Those are all intentional breaking changes which were not fixed upstream (i.e. are "working as intended"). The unintentional breaking changes, from changing error messages to cause string-based error detection to fail (because so many stdlib errors aren't exported so you have to do string matching), to just plain dumb bugs in the stdlib.... those are vastly more common. Those usually do get fixed in point releases. Take a gander at those release notes, many of the issues highlighted in those changelogs come from pain people hit during upgrades.
I think the majority of go version upgrades have had some amount of pain, and most of them have been far more disruptive than updating a well-built library.
I would much rather update just my fuzz-testing library in a commit, and be confident that it's only used in tests so CI is good enough to validate it, than have to update that and my http package and my tls package and my os package all at once and have to look for bugs _everywhere_.
However, I think you only mentioned changes in major releases, whereas in this scenario (vulnerability fix) a minor release would suffice (the parent mentioned updating to a point release of a library). Did you also have issues with minor releases?
Does the Go compiler have LTS releases? Like if I'm on 1.0, but 1.5 is out, are they going to release a 1.0.1 for a vuln that impacts 1.0+ ?
It seems unlikely but I'd be curious to know.
Libraries release patches more frequently, and it's also generally easier to apply a patch yourself if you need to.
Otherwise a point release may still imply a major release.
It's unlikely a fuzzing library has a security issue anyway since it's for test code, so the more pragmatic concern is that new fuzzing features may be adopted slowly because i.e. the feature requires go 1.20, but go 1.20 broke some part of net/http for the 10th time.
And in a sense, yes updating the go compiler was an issue with those because updating the go compiler forcibly updates net/http, with no option to not tie those exactly.
For one thing I update libraries all the time so it's a very fast, simple, well worn operation. Updating the compiler is a bit more of a chore and I'm going to worry a bit more about the impact (since it's global to all code vs local to one package).
For another, I would want to make sure I had tooling that could tell me "is this library in use by service X". I don't know Go's story there, but I would hope it's trivial to do so for a library but I suspect if it's part of the standard library that may be trickier. If not, nbd.
It's a bad smell to me, but if I were a Go developer it wouldn't break me.
Perhaps ironically, until this native fuzzing package, upgrading the compiler if you had fuzz tests would be one case where things would likely break.
This is indeed a chore in other languages. In Go, the compiler is trivially installed. Typically this just means bumping the version in your Dockerfile and “gvm use $newVersion —default”.
> For another, I would want to make sure I had tooling that could tell me "is this library in use by service X". I don't know Go's story there, but I would hope it's trivial to do so for a library but I suspect if it's part of the standard library that may be trickier. If not, nbd.
This is supported out of the box by Go’s tooling. `go mod graph` is what you’re looking for.
The issue isn't with installing the new compiler, that's trivial in our use case as well (for Rust at least, Python's a disaster, but I accept that). The issue is ensuring compatibility, ensuring no new bugs are introduced, etc. It's just a much heavier change to your produced binary vs changing a package.
> This is supported out of the box by Go’s tooling. `go mod graph` is what you’re looking for.
Cool, thanks.