Git Product home page Git Product logo

Comments (8)

jendrikw avatar jendrikw commented on June 20, 2024 5

We already lint temporary-cstring-as-ptr, so linting similar situations with String and Vec don't seem far-fetched.

from rust.

workingjubilee avatar workingjubilee commented on June 20, 2024 4

The String::with_capacity function only guarantees to allocate enough memory to store the specified number of characters. It does not guarantee that the allocated memory is valid.

To be clear, it sure as hell does allocate valid memory, the problem is that the string doesn't last past the end of that expression so you created a pointer to some valid memory, and then it becomes invalid just as quickly.

from rust.

saethlin avatar saethlin commented on June 20, 2024 3

We should have a lint against this pattern of creating an instantly-dangling pointer. I've seen this pattern mistakenly used in unit tests; it's a funny sort of canary for people who write unsafe code but didn't use ASan before publishing their work.

from rust.

workingjubilee avatar workingjubilee commented on June 20, 2024 1

@FlorentinoJink The problem is not truly with_capacity or as_mut_ptr but your subsequent usage of copy_nonoverlapping and from_raw_parts on an invalid pointer. The program is perfectly sound until that point. Yes, invalid pointers are fairly useless, but they are often created for various reasons.

More unfortunately, a raw pointer does not have a lifetime. This is a fundamental reality of Rust. Code that requires eschewing lifetimes needs that. And you have chosen to eschew lifetimes, and then ignore the invariants of ptr::copy_nonoverlapping and String::from_raw_parts, which state that they require valid pointers as input. There are many functions on pointers that do not require valid pointers and in fact can be quite useful without them (though most of the uses I can immediately think of have now been superceded by offset_of!).

It is indeed an undesirable API but I do not see how we can realistically require it to not compile anymore, as this code, for instance, is perfectly reasonable, and also has no lifetime bound, for the same reason:

fn main() {
    let str1_len = String::from("does not live to the next line").len();
}

And you seem to claim this code does not compile? Or perhaps that was a "should not"?

fn main() {
    let str1 = String::from("x").as_mut_ptr();
}

Unfortunately, it does.

Ultimately, you have not fully explained how the safe functions in question are at fault, you have only specified how irresponsible use of unsafe code can cause this problem. It is undesirable that the current APIs are shaped as they are, and I would not have chosen them, to be sure. But I do not think we can simply break them, as we promise we do not alter the type signatures of stable interfaces.

from rust.

saethlin avatar saethlin commented on June 20, 2024 1

I do not think that the scenario as described in the initial issue description is a reasonable thing to detect and warn about in the frontend. We have Miri and ASan for that.

from rust.

FlorentinoJink avatar FlorentinoJink commented on June 20, 2024

Thank you for your patient explanation. I will be more careful when using raw pointers in the future.

from rust.

workingjubilee avatar workingjubilee commented on June 20, 2024

@saethlin Hmm. It would be worthwhile if possible but how would we do this without also linting on e.g. hand-implementations of offset_of! that exist in the wild? Do we only do it for standard library types, do we make the lint passes aware of deallocation...?

I suppose we could have the Rust wrapper of the system allocator contain debug assertions (e.g. this particular example winds up deallocating the same pointer twice for a double-free, the second time after the String::from_raw_parts call, which is recreated with an invalid layout: 30 is not a valid capacity to pass).

from rust.

saethlin avatar saethlin commented on June 20, 2024

What I'm suggesting is just a lint against the specific pattern of calling a constructor function then a function called as_ptr or as_mut_ptr, then a semicolon. What I'm imagining targeting here is just the case where someone creates a String or a Vec but then their IDE suggests that they apply as_ptr or as_mut_ptr as a conversion function, because the IDE is stupid and just playing Type Tetris.

from rust.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.