3 ms·
A rewrite in C++ would not make it any safer. Rewriting it to make it easier to understand could make it safer, but you do not need a different language for tha
by joushou 10y ago
A rewrite in C++ would not make it any safer. Rewriting it to make it easier to understand could make it safer, but you do not need a different language for that.
- blub 10y agoYes it would, because this is basically string processing where C is the worst possible language one could use. I've detailed in another comment how std::string could be used.
- joushou 10y agoYou're talking about naked char[]. You can just as easily make a struct{ int len; char* str; } in C, and combined with the "n" variants of string operations, would work just fine with common tools. Again, C++ does not make anything safer, and its types can easily be replicated in any other language.
- kccqzy 10y agoI believe this is called pascal style strings and GCC has builtin support for it.
- pjmlp 10y agoBeing possible, doesn't mean the majority of C developers make use of it. The "n" variants are a joke in terms of security, even the C99 annex, that was demoted to optional in C11. I call them a joke, because tracking the pointer and length separately is hardly an improvement in terms of security. The only improvement that the "n" variants added is that the null character is always added to the end, instead of how strncpy does it, by only adding the character if there is enough space.
- NoGravitas 10y agoYou could stay in C and use glib strings.
- claudius 10y agoIf you can change the name_path struct to a standard STL data structure (std::vector<std::string> might work just fine), you can easily rewrite the function such that all memory allocation and all exploitable memory access is delegated to STL containers. If your STL std::string has a buffer overflow issue, you’re of course still in trouble, but the same is true if there are bugs in the STL/implementation of Go/Rust/Python/Java/Haskell… Something like: std::string path_name(std::vector<std::string> const& dirs, std::string const& name) { std::string p; for(auto const& dir : dirs) { p += (dirs + "/"); } p += name; return p; } should work. If you feel like it, you can also add something like: std::size_t len = name.size(); for(auto const& dir : dirs) { len += dir.size(); } p.reserve(len); Of course, len may overflow, but even if it does, all the harm that causes is that the string will have to reallocate memory during growth until running in a segfault when further memory allocation fails.
- smitherfield 10y agoI think you have a typo in your first code block. p += (dir + "/");
- claudius 10y agoOh, yes, sorry and now it’s too late to fix (both that and the horrible formatting). Though I suppose it would have been a compile-time error, so at least it shouldn’t be exploitable :')
- smitherfield 10y agoNo worries! :)
- joushou 10y agoRight, and you can do the same with C, using libraries providing this functionality wrapped as well. There's plenty of std::string and std::vector like containers, which handle the magic for you. But even then, you can work with struct {len int; void* data;} to get your vector, and replace void* with char* to get a string. A simple vector and simple string is in no way difficult to implement, and many implementations exist. I'm just trying to point out that the convenience of some C++ standard library features is not isolated to C++, and C++ is not a "memory safe" language by meaning of the word.