Safe sprintf? Topic is solved

Technical questions regarding the xTIMEcomposer, xSOFTip Explorer and Programming with XMOS.
User avatar
aclassifier
Respected Member
Posts: 425
Joined: Wed Apr 25, 2012 8:52 pm

Safe sprintf?

Post 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?


--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
View Solution
robertxmos
XCore Addict
Posts: 169
Joined: Fri Oct 23, 2015 10:23 am

Post 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, ...);
User avatar
aclassifier
Respected Member
Posts: 425
Joined: Wed Apr 25, 2012 8:52 pm

Post 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?
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
robertxmos
XCore Addict
Posts: 169
Joined: Fri Oct 23, 2015 10:23 am

Post by robertxmos »

We ship a standard implementation of the C libraries (newlib) so I would expect the behaviour to be as per reference.
User avatar
aclassifier
Respected Member
Posts: 425
Joined: Wed Apr 25, 2012 8:52 pm

Post 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.
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/
User avatar
aclassifier
Respected Member
Posts: 425
Joined: Wed Apr 25, 2012 8:52 pm

Post 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.
--
Øyvind Teig
Trondheim (Norway)
https://www.teigfam.net/oyvind/home/