The answer would be "it depends on whether you consider denial-of-service a problem". The key detail which makes all the difference is that, unless you're playing with raw pointers (which can only be dereferenced in "unsafe" blocks), the pointer to a buffer slice is always kept together with its length (in a "fat pointer"). Attempting to write through it past the buffer's bounds will result in a Rust panic, which usually aborts the whole process (there are ways to abort just one thread, or even to treat it similarly to a C++ exception, but a library cannot depend on them since the program might be compiled in the panic=abort mode). While that's obviously better than allowing for remote code execution, it still could be considered an issue.
Of course, that's assuming you want a similar API and are writing the code in a similar style, just replacing the direct pointer manipulation with slice manipulation. I don't know whether, in this particular case, more idiomatic Rust code would have avoided the issue. And, of course, the "growable container" approach would completely avoid it, but Rust is also used in places where memory allocation is not allowed, so having a non-allocating API still makes sense.
Yes, there is more code, but it does not become a lot more complex, if you need to you can unwrap to explicitly panic. You should still insert asserts to catch issues. But if there is an issue, such as running out of memory or anything else, you can handle it more appropriately than producing a Denial-of-Service issue immediately, which is definitely not good.
Yet these errors consistently happen in C projects of various sizes.
Yes, Rust would eliminate this error, but you can still do it "safer" in C (but you have to give up certain things to do it that way).
At the moment rust is used for some very marginal and unimportant leaf projects.
It is not a failure of C that we couldn't improve on it for so many decades.