1

Here's an example given on MSDN (http://msdn.microsoft.com/en-us/library/hh916383.aspx) that tried to explain SAL annotation could help find a common off-by-one error.

wchar_t * wmemcpy(
_Out_writes_all_(count) wchar_t *dest, 
_In_reads_(count) const wchar_t *src, 
size_t count)
{
   size_t i;
   for (i = 0; i <= count; i++) { // BUG: off-by-one error
      dest[i] = src[i];
}
return dest;
}

I don't quite get this example. In this example, it looks like the function signature contains a parameter called count, so we can use In_reads_(count) to make sure the memory space that src is pointing to has at least such number of bytes.
My question is, what if there is a function with signature like this

memcpy_example(wchar_t* dest, wchar_t* src)

In this case, the signature does not contain any information about the sizes. Can I use SAL to tell debugger that dest should be same size or 1-byte larger than src?

Daniel Rose
  • 17,233
  • 9
  • 65
  • 88
Allan Jiang
  • 11,063
  • 27
  • 104
  • 165
  • `memcpy` has a `size` parameter that specifies how many bytes are to be copied. How many bytes do you expect your `memcpy_example` function to copy? – James McNellis Jul 05 '13 at 23:24

1 Answers1

2

The correct annotation would be:

memcpy_example(
    _Out_writes_z_(_String_length_(src) + 1) wchar_t *dest,
    _In_z_ const wchar_t *src)

However, the analysis is much less precise in this case, since the analyzer does not know the actual string-length in most cases (tested with VS 2013):

void test_sal()
{
    wchar_t out[10];
    auto in1 = L"12345678901234";
    auto in2 = _wcsdup(L"12345678901234");

    memcpy_example(out, in1); // SAL warning
    memcpy_example(out, in2); // No warning!
}
Daniel Rose
  • 17,233
  • 9
  • 65
  • 88