Page 1 of 1

Safe sprintf?

Posted: Mon Feb 27, 2017 10:35 pm
by aclassifier
Is there a safe sprintf in XC?

I used stdio's sprintf and it overflows gladly into the variable after the array. It was my fault, but still. I had forgotten to add space for the NUL in addition to the visible chars. But it could have been worse.

The XMOS Programming Guide talks in chapter 12 about "Using safe pointers for string processing".

Is there an XMOS version of sprintf that's safe (to detect at compile-time)? Or a wrapper (for run-time checks, I assume, to detect overwrite)? Has anybody written one?

I guess that just formatting of an int is difficult in any case since the compiler would need to know the range to know how many characters would be built. And then there's the format string...

I ended up with checking the return value to detect overwrite. But it would have been much nicer to have the compiler take this! Are there cases where a certain piece of code could not be implemented with safe pointers only? From an algorithmic/language point of view?

Re: Safe sprintf?

Posted: Tue Feb 28, 2017 10:29 am
by robertxmos
XC does not provide native support.
In C there is snprintf() that takes the size of the buffer as one of the arguments
#include <stdio.h>
int snprintf(char *s, size_t n, const char *format, /* args */ ...);
int sprintf(char *s, const char *format, ...);

Re: Safe sprintf?

Posted: Tue Feb 28, 2017 12:19 pm
by aclassifier
Great! The cpp reference http://en.cppreference.com/w/c/io/fprintf states that:

"Calling snprintf with zero bufsz and null pointer for buffer is useful to determine the necessary buffer size to contain the output."
"snprintf_s, just like snprintf, but unlike sprintf_s, will truncate the output to fit in bufsz-1."

Will these points also go for the the library that xTIMEcomposer uses?

Re: Safe sprintf?

Posted: Tue Feb 28, 2017 12:25 pm
by robertxmos
We ship a standard implementation of the C libraries (newlib) so I would expect the behaviour to be as per reference.

Re: Safe sprintf?

Posted: Tue Feb 28, 2017 12:36 pm
by aclassifier
Thanks. In that case, I _think_ I found it here(?): https://chromium.googlesource.com/nativ ... /sprintf.c

<<snprintf>> is like <<sprintf>>, except that output is limited to at most <[size]> bytes, including the terminating <<NUL>>. As a special case, if <[size]> is 0, <[str]> can be NULL, and <<snprintf>> merely calculates how many bytes would be printed.

I'll test in a day or two and come back and report.

Re: Safe sprintf?

Posted: Wed Mar 01, 2017 8:00 am
by aclassifier
I removed all sprintf and replaced them with snprintf. It cost 12.3k:

Code: Select all

sprintf:
  Memory available:       65536,   used:      50420 .  OKAY
  (Stack: 10652, Code: 33882, Data: 5886)
snprintf:    
  Memory available:       65536,   used:      63064 .  OKAY
  (Stack: 10660, Code: 45862, Data: 6542)
Nice to know, but prohibitive for me. I really have no place where I now don't have control, so it's ok.

I did add a check the sprintf return, it does inform of number of filled chars, including overflowed chars and/or terminating NUL.