• Mihies@programming.dev
    link
    fedilink
    arrow-up
    11
    ·
    1 month ago

    Rust or any other compiler can’t catch those type of bugs because they are not bugs at compiler level 🤷

    • Tobias Hunger@programming.dev
      link
      fedilink
      arrow-up
      8
      ·
      1 month ago

      We said the same about memory safety: That’s something a compiler can not solve. Now it does.

      It is nice to see that sometines things do improve.

      • Mihies@programming.dev
        link
        fedilink
        English
        arrow-up
        3
        arrow-down
        1
        ·
        1 month ago

        Memory safety is something compiler understands and has under control, this stuff it does not. Nor it should.

        • TehPers@beehaw.org
          link
          fedilink
          English
          arrow-up
          3
          ·
          1 month ago

          Many of their TOCTOU issues are something a type system can help with. Require operations to execute on a fd handle directly rather than using convenience functions.

          let fd = FileDescriptor::new(path);
          fd.delete()?;
          fd.create(mode)?;
          
          let is_root = fd == FileDescriptor::new("/"); // does (dev, inode) comparison internally
          // etc
          

          The uutils devs would need to create that themselves, but OpenOptions seems to get them part of the way there at least.

          • BB_C@programming.dev
            link
            fedilink
            arrow-up
            2
            ·
            1 month ago

            That’s a question of API, not type system. And FD types (e.g. OwnedFd, BorrowedFd) are already in std.

            • TehPers@beehaw.org
              link
              fedilink
              English
              arrow-up
              1
              ·
              1 month ago

              That’s a question of API, not type system.

              It’s only enforced because of Rust’s strict type system. Python, on the other hand, lets you do whatever you want by comparison, and complains only at runtime. I’ve seen far too many **kwargs for my liking.

              And FD types (e.g. OwnedFdBorrowedFd) are already in std.

              My example would be a thin wrapper around these, most likely. It’s only an example of what I’m trying to convey, though.

      • davidgro@lemmy.world
        link
        fedilink
        arrow-up
        2
        arrow-down
        1
        ·
        1 month ago

        I thought one of the goals of Java and similar was partial memory safety? If it didn’t have null it seems it would be most of the way there.

        And don’t forget Basic. Yeah most variants had pointers and equivalents to null, but they are ‘advanced’ and not meant for general code. (Although that’s interpreted and you said compiled, often it could be ‘complied’ similarly to Java bytecode)

        • Tempy@programming.dev
          link
          fedilink
          English
          arrow-up
          2
          ·
          26 days ago

          A null does not make it memory unsafe. You aren’t accessing invalid memory, the runtime just raises a NRE. Which is fine. No memory safety violated.

          Java is, as long as you stick to pure java and not native interop, entirely memory safe. And that’s achieved by giving up control of memory allocation to the garbage collector.

          Rust is not the first memory safe language. It does however, manage to achieve memory safety without needing a garbage collector. Which is what drew my initial interest.

  • MoSal@programming.dev
    link
    fedilink
    arrow-up
    7
    ·
    1 month ago
    // Don't bail on the first error, but remember the worst one.
    let mut worst = 0;
    for file in files {
        if let Err(e) = chmod_one(file) {
            worst = worst.max(e.exit_code());
        }
    }
    process::exit(worst);
    

    This is not rustic, I feel.

    files.iter()
      .map(chmod_one)
      .filter_map(Result::err)
    

    is more like it.

    From there, you can next() for first error, last() for last error, or fold() for max error, or collect() if you need to save all errors.


    And no, static compilation doesn’t help here, because get_user_by_name goes through NSS, which dlopens libnss_* modules at runtime regardless of whether your binary is statically linked.

    This is not true in musl systems. I just quickly checked in a Chimera rootfs (which has a system dynamic musl libc btw).

    I believe the described dlopening is one of the well known reasons why GNU libc is not suitable for static linking, unlike musl!

    In Arch, this indeed loads /usr/lib/libnss_systemd.so.2.

    Everyone can test this with strace id 2>&1 | egrep 'open.*\.so'.

  • someacnt@sh.itjust.works
    link
    fedilink
    English
    arrow-up
    2
    ·
    29 days ago

    Don’t Trust a Path Across Two Syscalls

    Wasn’t this a common knowledge among application developers? File system is volatile, and can change any time, do not assume persistence of it. I heard about the principle from ghcup developer a few years ago.

  • Digit@lemmy.wtf
    link
    fedilink
    English
    arrow-up
    2
    ·
    1 month ago

    Time for Haskell?

    How many more bugs would Haskell catch?

    “Entire classes of bugs”?