Live data from Hacker News

Failing to Learn Zig via Advent of Code

forrestthewoods.com

321–330 of 338 posts

Re: Failing to Learn Zig via Advent of Code

#321
post #311
post #266

Earlier quoted context omitted.

I think the comparison should be more nuanced and holistic than only memory safety, if it is to be a discussion on security and not theater. For example, to get the conversation started, how do both languages compare in terms of checked integer arithmetic? Do they enable checked arithmetic by default in safe builds with an opt-out for performance, or do they leave default builds unsafe with an opt-in for safety? Anot…

> All 100% memory safety, and yet security is still a thing. And nobody has ever claimed that memory safety is the only thing that matters with security, but it’s definitely high on the list. Can you imagine how much more of a nightmare NPM would be if JavaScript weren’t memory safe? This is the relevant counterfactual. > Zig is an order of magnitude safer than C, much closer to Rust actually, and more so in some are…

> As for integer overflows, I don’t think they are nearly as big a security concern in a memory safe language with bounds checking. Feel free to correct me though.

See HeartBleed, CloudBleed, all buffer underflows resulting in buffer bleeds, letting someone read all your sensitive server memory, with no UAF.

They can also be caused just by integer overflow, which is what makes unchecked integer arithmetic so incredibly dangerous. It's easy for programmers to be oblivious to this, and overly rely on the borrow checker, thinking it can provide 100% memory safety, when by definition it can't.

And all kinds of software systems have these vulnerabilities. For example, I've worked on static analysis security software that could detect bleeds automatically in outgoing email attachments and it would find different bank systems leaking data in autogenerated statements.

From this experience, and from some bug bounty and security engagements I've done, I'm much more comfortable actually with Zig's approach to correctness and safety overall. I think the borrow checker is pretty awesome and has some serious muscle, but nevertheless Zig impresses me with its strict focus on explicitness, which I believe is the best approach still to eliminate these kinds of semantic gaps in general.

The borrow checker obviously can't protect you from bleeds (it can from some where static allocation is at play), but checked arithmetic would, or at least go pretty far — and again, it's about the spectrum, not the extreme.

It would be great for Rust to enable checked arithmetic by default for safety, with an opt-out for performance. Flipping this around would be a better default.

Re: Failing to Learn Zig via Advent of Code

#322
post #293

Earlier quoted context omitted.

> If dealing with potentially hostile data, Zig certainly isn't more appropriate than Rust in my opinion, try maybe WUFFS. Thanks! Great recommendation on WUFFS! And completely agreed, it's also easy to turn on checked arithmetic for Rust (if you know about it, but Rust definitely has an unsafe default there for those that don't, which is surprising to me). At the same time, WUFFS is not always applicable, for exampl…

Something like WUFFS is exactly what we should be using for Wrangling Untrusted File Formats as it says in the name, even if you've decided to do that in a distributed system. Realistically you're definitely going to get this wrong, so, use a language where the worst case is it doesn't work is a massive improvement over using languages where it's all additional attack surface. That recent Apple bug where they render…

> Something like WUFFS is exactly what we should be using for Wrangling Untrusted File Formats as it says in the name, even if you've decided to do that in a distributed system.

No, I was saying earlier that there are limits to WUFFS. The example I gave was that you can't write something like a distributed system (think consensus protocol like Viewstamped Replication, Raft or Paxos) in WUFFS, but where safety is nevertheless still critical, and where you reach that through crystal clear control flow and explicitness. In other words, safety is the other side of the coin to security. Hope it's a little more clear now.

> That recent Apple bug where they render PNGs incorrectly can (in principle) happen in WUFFS. The other recent Apple bug where bad guys seize control of your iPhone by sending a malicious image file cannot. One of these things is not like the other.

Of course.

> I think you're missing the point if you expect the borrow checker to care about buffer underflow.

No, I was stating the obvious, that it can't (or at least not always, but in some cases it can), not that it should.

> I don't buy the "surfaces the bug" thing

I was just trying to convey a little bit about how security works and how hackers (or at least red teamers) think, especially when blue teams are involved. I've found that the more I get into this, it becomes much less about preventing the breach and more about "assume breach, okay, now how do we detect it?". And a software DoS is also really just bottom-of-the-rung, you'll find almost no programs paying out for any findings. You shouldn't worry about them. Asserts are the safe thing to do. They close semantic gaps and make your code much more secure. It's like putting in a thousand trip wires, any thing off and an attacker can't get further. It completely shuts down exploit chaining.

Re: Failing to Learn Zig via Advent of Code

#323
post #319
post #290

Earlier quoted context omitted.

So here is a sample, Chapel, HPC language mostly sponsored by Intel and HPC https://chapel-lang.org/ D programming language, https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in... Ada/SPARK, https://docs.adacore.com/spark2014-docs/html/ug/en/source/la... Swift, https://github.com/apple/swift/blob/main/docs/OwnershipManif... ParaSail http://www.parasail-lang.org/ Project Verona from Microsoft Research https:/…

At least most of these don't seem to be added language features, but separate "static analyzers" that rely on inference from existing language structures.

Sounds like a lot of "contemporary automation today" to me - automation that would often apply about as well to C code bases as well as horrifically overcomplex C++ codebases.

Also, why even draw a stark contrast between "a language" and "its tooling"? As a dev, you get to use both.

What is even the line..? Almost every compiler for anything provides options. Does gcc -fsanitize=.. not count because it's not "standardized" or only because its not activated in "typical" deployments like Rust integer overflow checks?

Re: Failing to Learn Zig via Advent of Code

#324
post #312

Earlier quoted context omitted.

Perl uses ~ for string concatenation. Nothing says that you cannot use both infix "++" for concatenation and unary ++ for increment. "-" is both a unary prefix and binary infix operator, for example.

Perl uses '.' for string concatenation. Nothing says that I can't do that but in context of deliberately -not- re-using operators for completely different things it would seem rather self-defeating.

Oof, you're right. I was thinking of Raku.

Re: Failing to Learn Zig via Advent of Code

#325
post #261
post #114

Earlier quoted context omitted.

Interesting. I had the impression Zig proponents were praising it because it wasn't as low-level as Rust.

Where did you get that impression? No one has ever done that.

Here at HN.

I never read anything about Zig outside of HN.

What I remember was mostly that Zig should be easier to use than Rust, because Zig doesn't have lifetimes.

Re: Failing to Learn Zig via Advent of Code

#326
I did improve my Go skills solving all problems in Go, learning many things the hard way, but at end my solutions were way longer and so much less ergonomic than the NumPy & Python-based I saw by the top 100 guys! I mean, come on, Go doesn't even have built-in min(), max(), abs(), and other basics (for ints)! Some of the top developers had their solutions done in a shorter time that I needed to read the overly convoluted and confusing problems. I just didn't appreciate the infantile, and wasteful pseudo-comical style of problem definitions! I've attended any programming contest back in Bulgaria and I can't recall anything that required me to read everything carefully 2-3 times before I get what needs to be done (oh, well, I wasn't 48 back then). I also got fascinated by GitHub Copilot, which actually autocompleted many of those missing basics and surprisingly "guessed" what I was trying to accomplished and offer meaningful productivity boost. I also looked into Zig, but, honestly, I didn't like many of the syntax choices made. Instead, I installed V [0], and will actually try to use it as it fits me better.

[0]: https://vlang.io/

Re: Failing to Learn Zig via Advent of Code

#327
post #323
post #319

Earlier quoted context omitted.

At least most of these don't seem to be added language features, but separate "static analyzers" that rely on inference from existing language structures.

Sounds like a lot of "contemporary automation today" to me - automation that would often apply about as well to C code bases as well as horrifically overcomplex C++ codebases. Also, why even draw a stark contrast between "a language" and "its tooling"? As a dev, you get to use both. What is even the line..? Almost every compiler for anything provides options. Does gcc -fsanitize=.. not count because it's not "standar…

The line is very, very easy: if it is in the language, you can see it represented syntactically in the source code, and programmers using the language write it there. If not, not.

Re: Failing to Learn Zig via Advent of Code

#328
post #319
post #290

Earlier quoted context omitted.

So here is a sample, Chapel, HPC language mostly sponsored by Intel and HPC https://chapel-lang.org/ D programming language, https://dlang.org/blog/2019/07/15/ownership-and-borrowing-in... Ada/SPARK, https://docs.adacore.com/spark2014-docs/html/ug/en/source/la... Swift, https://github.com/apple/swift/blob/main/docs/OwnershipManif... ParaSail http://www.parasail-lang.org/ Project Verona from Microsoft Research https:/…

At least most of these don't seem to be added language features, but separate "static analyzers" that rely on inference from existing language structures.

With exception of C++, they certainly aren't.

C++ type system is impossible to fix while keeping backwards compatibility, so static analysis tooling is the only possible solution.

Re: Failing to Learn Zig via Advent of Code

#329
post #327
post #323

Earlier quoted context omitted.

Sounds like a lot of "contemporary automation today" to me - automation that would often apply about as well to C code bases as well as horrifically overcomplex C++ codebases. Also, why even draw a stark contrast between "a language" and "its tooling"? As a dev, you get to use both. What is even the line..? Almost every compiler for anything provides options. Does gcc -fsanitize=.. not count because it's not "standar…

The line is very, very easy: if it is in the language, you can see it represented syntactically in the source code, and programmers using the language write it there. If not, not.

Clang and Visual C++ static analysis tooling can be represented on the source code via C++ attributes and blessed library types, so...

Re: Failing to Learn Zig via Advent of Code

#330
post #153

Earlier quoted context omitted.

I agree that with vector math, overloaded arithmetic operators are easier to read. However, I don't see how you could add "overloading, but only for actual math" - once it's in, people will repurpose it for all kinds of cursed purposes. The implementation would probably be ugly, but I wonder if it could be implemented by using a comptime string to represent the operation, e.g. something like: fn doMath(comptime op: […

I think vector math is a compelling example but it is far from the only one. Bignum arithmetic is probably just as common if not more so, in fact I see that Zig actually has a bignum library built in if I understand correctly. Using that library will be painful because of this choice. There are plenty of other such examples, imagine implementing (and then using) something like SymPy in Zig.

One of the issues with operator overloading itself in relation to bignums and similar is the need for an allocator (there's nowhere to pass one) along with the lack of error handling (suppose allocation fails) and when/how to cleanup. Same with string concatenation at runtime via operators and many other places where it could be used.

So even if zig allowed for operator overloading, those issues would have to be solved.

Post reply on HN