eddelbuettel / bh

R package providing Boost Header files
85 stars 32 forks source link

CRAN warning "Found 'sprintf', possibly from 'sprintf' (C)" using BH #89

Closed mclements closed 1 year ago

mclements commented 1 year ago

Thank you for this excellent package.

When including boost/numeric/odeint.hpp in the rstpm2 package on CRAN, I get a warning "Found 'sprintf', possibly from 'sprintf' (C)" (https://cran.r-project.org/web/checks/check_results_rstpm2.html). A possible explanation is that https://github.com/eddelbuettel/bh/blob/master/inst/include/boost/numeric/odeint/integrate/max_step_checker.hpp#L72 and https://github.com/eddelbuettel/bh/blob/master/inst/include/boost/numeric/odeint/integrate/max_step_checker.hpp#L104 include std::sprintf calls. Is there a simple way to get around this warning? Any help with this would be appreciated.

Sincerely, Mark.

eddelbuettel commented 1 year ago

I am aware. I have no fix. I said I have no plan to edit BH manually:

edd@rob:~/git/bh(master)$ ag -c sprint inst/include/ 
inst/include/boost/asio/detail/impl/handler_tracking.ipp:3
inst/include/boost/asio/detail/impl/win_static_mutex.ipp:1
inst/include/boost/asio/detail/impl/socket_ops.ipp:11
inst/include/boost/asio/ip/impl/network_v4.ipp:3
inst/include/boost/asio/ip/impl/network_v6.ipp:3
inst/include/boost/asio/impl/connect_pipe.ipp:1
inst/include/boost/assert/source_location.hpp:1
inst/include/boost/lexical_cast/detail/converter_lexical_streams.hpp:6
inst/include/boost/test/utils/setcolor.hpp:2
inst/include/boost/test/impl/debug.ipp:2
inst/include/boost/test/impl/test_tools.ipp:2
inst/include/boost/compute/detail/parameter_cache.hpp:1
inst/include/boost/interprocess/detail/win32_api.hpp:1
inst/include/boost/xpressive/traits/detail/c_ctype.hpp:2
inst/include/boost/spirit/home/support/char_encoding/ascii.hpp:2
inst/include/boost/spirit/home/support/char_encoding/standard.hpp:2
inst/include/boost/spirit/home/support/char_encoding/iso8859_1.hpp:2
inst/include/boost/spirit/home/support/char_encoding/unicode.hpp:1
inst/include/boost/spirit/home/support/char_encoding/standard_wide.hpp:1
inst/include/boost/spirit/home/support/char_class.hpp:1
inst/include/boost/spirit/home/x3/support/traits/print_attribute.hpp:1
inst/include/boost/spirit/home/x3/support/traits/print_token.hpp:1
inst/include/boost/spirit/home/classic/core/primitives/impl/primitives.ipp:4
inst/include/boost/spirit/home/classic/core/primitives/primitives.hpp:1
inst/include/boost/regex/v4/c_regex_traits.hpp:1
inst/include/boost/regex/v4/regex_workaround.hpp:1
inst/include/boost/regex/v5/c_regex_traits.hpp:1
inst/include/boost/numeric/odeint/integrate/max_step_checker.hpp:2
inst/include/boost/core/lightweight_test.hpp:2
inst/include/boost/core/type_name.hpp:1
edd@rob:~/git/bh(master)$ 

That is from using the release candidate 1.81.0 described here: https://github.com/eddelbuettel/bh/issues/88

eddelbuettel commented 1 year ago

A closer look reveals that a few of them are in fact sprintf_s (also safe) or preceded (in the case of Asio) by an #ifdef for snprintf so maybe I can get to this.

I am a little fearful of fat-fingering it but CRAN leaves me little choice I guess.

eddelbuettel commented 1 year ago

Some notes to self: Using ag from emacs showing the matches reveals some are in comment. sprintf_s is also fine

``` -*- mode: ag; default-directory: "~/git/bh/inst/include/boost/" -*- Ag started at Thu Dec 29 11:24:15 ag --literal --group --line-number --column --color --color-match 30\;43 --color-path 1\;32 --smart-case --stats -- sprintf . File: asio/detail/impl/handler_tracking.ipp 363:31: using namespace std; // For sprintf (or equivalent). 372:17: int length = vsprintf_s(line, sizeof(line), format, args); 374:17: int length = vsprintf(line, format, args); File: asio/detail/impl/win_static_mutex.ipp 43:31: using namespace std; // For sprintf. File: asio/detail/impl/socket_ops.ipp 2416:31: using namespace std; // For sprintf. 2420:5: sprintf_s(dest, length, "%u.%u.%u.%u", 2432:14: n += sprintf_s(dest + n, length - n, ":%s", b < 16 ? "" : ":"), ++z; 2436:14: n += sprintf_s(dest + n, length - n, "%s%x", b ? ":" : "", 2442:12: n += sprintf_s(dest + n, length - n, "%%%lu", scope_id); 2514:44: using namespace std; // For strcat and sprintf. 2526:7: sprintf(if_name + 1, "%lu", scope_id); 3638:7: sprintf_s(serv, servlen, "%u", ntohs(port)); 3640:7: sprintf(serv, "%u", ntohs(port)); 3663:9: sprintf_s(serv, servlen, "%u", ntohs(port)); 3665:9: sprintf(serv, "%u", ntohs(port)); File: asio/ip/impl/network_v6.ipp 99:31: using namespace std; // For sprintf. 105:3: sprintf_s(prefix_len, sizeof(prefix_len), "/%u", prefix_length_); 107:3: sprintf(prefix_len, "/%u", prefix_length_); File: asio/ip/impl/network_v4.ipp 130:31: using namespace std; // For sprintf. 136:3: sprintf_s(prefix_len, sizeof(prefix_len), "/%u", prefix_length_); 138:3: sprintf(prefix_len, "/%u", prefix_length_); File: asio/impl/connect_pipe.ipp 49:31: using namespace std; // For sprintf and memcmp. File: assert/source_location.hpp 79:58:# define BOOST_ASSERT_SNPRINTF(buffer, format, arg) std::sprintf(buffer, format, arg) File: lexical_cast/detail/converter_lexical_streams.hpp 283:21: sprintf_s(begin, CharacterBufferSize, 285:21: sprintf(begin, 295:21: sprintf_s(begin, CharacterBufferSize, 297:21: sprintf(begin, 308:21: sprintf_s(begin, CharacterBufferSize, 310:21: sprintf(begin, File: test/utils/setcolor.hpp 92:31: m_command_size = std::sprintf( m_control_command, "%c[%c;3%c;4%cm", 103:31: m_command_size = std::sprintf(m_control_command, "%c[%c;3%c;4%cm", File: test/impl/debug.ipp 45:41:namespace std { using ::memset; using ::sprintf; } 883:10: std::sprintf( cmd_line, format, ::GetCurrentProcessId(), dbg_init_done_ev ); File: compute/detail/parameter_cache.hpp 123:37: #define DETAIL_SNPRINTF sprintf_s File: interprocess/detail/win32_api.hpp 1801:24: std::sprintf(&stamp_str[0], "%u", ((unsigned int)pTypedRecord->TimeGenerated)); File: regex/v4/regex_workaround.hpp 53:12: using ::sprintf; using ::strcpy; using ::strcat; using ::strlen; File: numeric/odeint/integrate/max_step_checker.hpp 72:18: std::sprintf(error_msg, "Max number of iterations exceeded (%d).", m_max_steps); 104:18: std::sprintf(error_msg, "Max number of iterations exceeded (%d). A new step size was not found.", m_max_steps); File: core/lightweight_test.hpp 214:14: std::sprintf( buffer, "\\x%02X", static_cast( v ) ); File: core/type_name.hpp 191:10: std::sprintf( buffer, "%lu", static_cast< unsigned long >( n ) ); 40 matches 16 files contained matches 12575 files searched 129671692 bytes searched 0.101163 seconds Ag finished at Thu Dec 29 11:24:15 ```

lexical_cast seems gnarlier but points to a new (portable) boost::core:snprintf in this Boost Core PR which may get combined with this PR in lexical_cast.

Several other ones are easier.

eddelbuettel commented 1 year ago

Thanks for the gentle prodding. I created a new branch and the changeset is actually small and reasonable (apart from the issue mentioned in the previous comment, for which I found the proper treatment in that PR.

Testing this now, and with some luck this should be on CRAN soon after they reopen (and we take care of process in #88, i.e. let a small number of packages update) after which your issue will be taken care of.

mclements commented 1 year ago

Well done! (I was concerned that was going to be a much larger task.)