• 0 Posts
  • 337 Comments
Joined 2 years ago
cake
Cake day: June 10th, 2024

help-circle

  • balsoft@lemmy.mltoProgrammer Humor@lemmy.mlrustmas
    link
    fedilink
    arrow-up
    5
    ·
    edit-2
    2 days ago

    Rust does not have exceptions. You never have to try/catch. Functions usually encode the possible failures in their types, so you’d have something like this C++ snippet:

    struct HttpError {
      std::string message;
      int responseCode;
    }
    
    struct FsError {
      std::string message;
    }
    
    typedef std::variant<HttpError, IoError> FileDownloadError;
    
    std::variant<std::filesystem::path, FileDownloadError> downloadFile(std::string url) { /* ... */ }
    

    And then the caller of downloadFile has to decide what to do if it returns an error:

    auto res = std::visit(overloaded {
    	[](FileDownloadError e) { /* ignore error, or handle it somehow, and return a new path */ },
    	[](std::filesystem::path p) { return p; }
    }, downloadFile(url));
    
    /* res is guaranteed to be a valid std::filesystem::path, you don't have to care about errors from downloadFile anymore */
    

    However, Rust makes this whole thing a lot easier, by providing syntax sugar, and there are helper libraries that reduce the boilerplate. You usually end up with something like

    #[derive(Error, Debug)]
    enum FileDownloadError {
      #[error("HTTP request failed")]
      HttpError(http::status::StatusCode),
      #[error("Filesystem error: {0}")
      FSError(#[from] std::io::Error),
    }
    
    fn download_file(String url) -> Result<Path, FileDownloadError> {/* ... */}
    

    (notice the #[from], which forwards the error message etc from the std::io::Error type)

    The Result type is kind of like a std::variant with two template arguments, and, mostly by convention, the first one denotes the successful execution, while the second one is the error type. Result has a bunch of methods defined on it that help you with error handling.

    Consumer code is something like this:

    let res : Path = download_file(url).unwrap_or_else(|e| {
      /* Ignore the error or handle it. You have to return a new path here */
    });
    
    /* res is guaranteed to be a valid Path, you don't have to care about errors from download_file anymore */
    

    Or

    let res : Path = download_file(url)?;
    
    /* res is guaranteed to be a valid Path, you don't have to care about errors from download_file anymore */
    

    Which will just forward the error to your caller (but your function has to return Result as well), or proceed with the execution if the function succeeded.

    Finally, download_file(url).unwrap() is if you can neither ignore, nor handle, nor pass the error to the caller. It will abort if the function fails in any way, and there’s no (practical) way to catch that abort.


  • balsoft@lemmy.mltoProgrammer Humor@lemmy.mlrustmas
    link
    fedilink
    arrow-up
    6
    ·
    edit-2
    2 days ago

    It’s worse than just exceptions in C++. There’s (almost) no way for the caller of your function to catch it. It’s a bit like this snippet:

    std::optional<int> foo = <...>;
    try {
      return foo.value();
    } catch(const std::bad_optional_access& e) {
      std::cout << e.what() << std::endl;
      abort();
    }
    

    It’s the abort that is the crux of the issue here. Usually you would pass the std::optional up/down the call stack. If you don’t control the types (e.g. using a library or a framework) you’d come up with some “default” value instead, like this:

    std::optional<int> foo = <...>;
    return foo.value_or(123);
    

    Or in Rust:

    let foo : Option<i32> = <...>;
    return foo.unwrap_or(123);
    

    But sometimes there’s no good “default” value, and then you have to resort to just unwrap-ing the value, and accepting that the entire program will abort when that function call fails. Usually this is a sign of poor engineering somewhere, likely in a library you’re using, and should be fixed; but sometimes you don’t have the time to fix it, and then it ends up in production.


  • Telegram can serve you your old “Cloud” messages, in a decrypted form, on a new device, without any communication with the old device.

    This means that they possess the keys to decrypt the messages, since they can send them to you in a decrypted form.

    Those messages can’t even be encrypted with your cloud password (which would be a pretty weak encryption anyways), because you can reset the cloud password via your recovery email, and still retain access to your messages.

    Contrast this with encrypted chats on Matrix, where you have to go through the device verification procedure, which prompts the old device to send decryption keys to the new device (it’s actually more complicated but this gets the point across). If you lose access to all your devices (and your recovery key), your encrypted messages are gone, the server admin can’t restore them because they simply don’t have the key.

    No one can’t prove that Telegram use MTProto to encrypt content sent using Cloud Chat, stores them encrypted, and them decrypt them upon opening because the source code for MTProto is closed. So how can you prove that what you’re saying is the way they use?

    This is a distinction without a difference.

    My claim is:

    They possess the keys to decrypt your messages

    Whether this is implemented via MTProto encryption or disk encryption or whatever, it doesn’t matter, they can read your messages if they want to.

    Telegram is actually pretty transparent that Cloud chats are not e2e encrypted in their FAQ. They also go on to babble about “MTProto client-server encryption” but if you spend 2 minutes looking at it, you can see it’s just 256-bit AES with a shared key generated via Diffie-Hellman, not too dissimilar from plain HTTPS. In that sense it’s about as secure as e-mail over encrypted IMAP/SMTP, or IRC over TLS, or DMs here on lemmy.

    They also claim that their at-rest encryption keys are separate from the data they encrypt, and claim that somehow this “requires court orders from multiple jurisdictions” to force them to give over your data, which is just ridiculous from a legal standpoint and won’t stand up in court. And actually, it’s way more likely that they will just cave in and give up your message history without a lawsuit at all, just look at what happened to Durov in France.


  • All data sent to Telegram’s servers will be encrypted once they reach the servers

    Except for “secret chat” (which are only 1-on-1 chats, have flaky client support, and require both participants to be online at the same time to initiate; in other words, they are near useless) - this is just simple at-rest storage encryption. They possess the keys to decrypt your messages (again, except for secret chats), because that is necessarily what happens when they serve those messages to recepients.







  • I think if you have some use-case that Wayland doesn’t fulfill, it’s totally fine to just pin some version of Plasma and stick with it. Maybe even switch to Trinity. Chances are it will keep working for like a decade or more.

    I still use kdenlive 18.08, because I know how to use that version, and it does what I need it to do perfectly well. They broke something I needed in 19.whatever (I don’t remember what it was anymore), so I just pinned it and kept using it ever since. Maybe one day I’ll try to figure out the latest version, but there’s no real incentive for me to do so.







  • I guess we have vastly different expectations from our phones, then. At a minimum, I need to:

    1. Have reliable, snappy maps with precise GPS (for trekking)
    2. Be able to interact with my bank on the go, at least via a web app
    3. Be able to chat with people via Matrix
    4. Get transit routing via a web app

    And in my experience, Librem5 just doesn’t have enough processing power and RAM to do any of those quickly and reliably. It was not comfortable at all, e.g. the browser kept filling up RAM and locking up the device with constant swapping, and finally OOMing. GPS took 5-10 minutes to get a lock, even with AGPS, and after that wouldn’t reliably keep it. Both Nheko and NeoChat were slow and laggy. It also died after 4-5 hours of suspend with a modem on, unacceptable for a reliable daily.

    OnePlus6 is a rocketship in comparison, and performs all those tasks with ease. The battery also lasts for an entire day with conservative suspend settings (but with the modem on), and for a couple days in airplane mode (e.g. while hiking in the mountains).



  • I understand Unicode and its various encodings (UTF-8, UTF-16, UTF-32) fairly well. UTF-8 is backwards-compatible with ASCII and only takes up the extra bytes if you are using characters outside of the 0x00-0x7F range. E.g. this comment I’m writing is simultaneously valid UTF-8 and valid ASCII.

    I’d like to see some good evidence for the claim that Unicode support increases memory usage so drastically. Especially given that most data in RAM is typically things other than encoded text (e.g. videos, photos, internal state of software).