Hacker News new | ask | show | jobs
by rwmj 2853 days ago
> He asked: why is there no argument to memcpy() to specify the maximum destination length?

I'm confused by this. The third argument provides the destination length, so what good would a "maximum destination length" do? I guess he must mean that because the length is often computed, you'd need a fourth argument to ensure the length isn't greater than some sane upper bound. But you can easily fix that using an if statement around the memcpy.

2 comments

Perhaps because the memory buffers might be of different size.

Maybe memcpy_oobp (out of bounds protection) signature could be:

  memcpy_oobp(void* dst, size_t dst_size, void* src, size_t src_size);
Then again, I guess you could just as well do:

  memcpy(dst, src, min(dst_size, src_size));
But having to explicitly specify both destination and source sizes might have prevented a lot of buffer overwrite bugs.
> But having to explicitly specify both destination and source sizes might prevented a lot of buffer overwrite bugs.

A good way to prevent this is to have a buffer abstraction, where the size is a property of the type, e.g.,

    typedef struct {
      size_t bytes_used;
      size_t capacity;
      void *data;
    } buf_t;

    int buf_init(buf_t *buf);
    void buf_cleanup(buf_t *buf);
    void buf_copy(buf_t *dst, buf_t *src);
    /* ... */
Of course, it doesn't prevent people from using memcpy directly.
I guess so. One of the LWN comments mentions a Microsoft function memcpy_s defined as:

    memcpy_s (void *dest, size_t destSize, const void *src, size_t count);
which is effectively equivalent to your memcpy_oobp function.

However the Microsoft function also returns an error code which must be checked (because count might be larger than destSize), thus providing another way for the programmer to screw up. I'm not sure if this is better or worse than just copying the min() as in your second example. It probably depends on the situation.

Using min() seems like it could be incredibly dangerous as an "implicit" behavior, not to mention surprising.

I'd wager it'd be much better to just specify that abort() gets called in the "overflow" case. (Given that overflow is basically never what you want anyway.)

Yeah, it'll crash but at least it won't be suprising/undefined behavior.

For extra fun, the Microsoft implementation of memcpy_s returns an error instead of crashing if either of the pointers is NULL (thankfully doesn't apply if the copy size is 0). There's a reason I don't like writing software for Windows ...
Just use memcpy_s. This has the destbuf size argument. It's even in C11, but you need the safeclib or MSVC, as no libc cares about the safety annex.