Skip to content

more sprintf removals#23502

Merged
opencv-pushbot merged 1 commit intoopencv:4.xfrom
seanm:sprintf3
Apr 26, 2023
Merged

more sprintf removals#23502
opencv-pushbot merged 1 commit intoopencv:4.xfrom
seanm:sprintf3

Conversation

@seanm
Copy link
Copy Markdown
Contributor

@seanm seanm commented Apr 17, 2023

This first 3 commits are from #23055 (I'll rebase this after that is merged).

The last commit is an incomplete proposal to deprecated convertTypeStr and make a new variant using std::string. If it's acceptable, I'll complete the PR to use the new method everywhere.

force_builders=Linux OpenCL,Win64 OpenCL

@seanm seanm mentioned this pull request Apr 17, 2023
@seanm
Copy link
Copy Markdown
Contributor Author

seanm commented Apr 24, 2023

@opencv-alalek @asmorkalov care to review this one too? The -Wdeprecated-declarations warnings on CI are why this is WIP.

If you are happy with the technique, I will finish the conversion.

int cn = (elem_type == CV_SEQ_ELTYPE_PTR/*CV_USRTYPE1*/) ? 1 : CV_MAT_CN(elem_type);
char symbol = (elem_type == CV_SEQ_ELTYPE_PTR/*CV_USRTYPE1*/) ? 'r' : typeSymbol(CV_MAT_DEPTH(elem_type));
sprintf(dt, "%d%c", cn, symbol);
snprintf(dt, dt_len, "%d%c", cn, symbol);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we need to check the return code of snprintf call (as we pass dt_len):

a return value of size or more means that the output was truncated.
CV_CheckGE(snprintf_result, 0, "");  // check for snprintf errors
CV_CheckLT((size_t)snprintf_result, dt_len, "output is truncated");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But dt and dt_len are both given by the caller. If truncation occurs, it's because:

  1. the caller passed the wrong size for dt_len
  2. truncation was desired

The callers do the correct thing, one example:

fs << "dt" << fs::encodeFormat( m.type(), dt, sizeof(dt) );

tmp += snprintf( buffer + tmp, bufsize - tmp, "WIDTH %d\n", width);
tmp += snprintf( buffer + tmp, bufsize - tmp, "HEIGHT %d\n", height);
tmp += snprintf( buffer + tmp, bufsize - tmp, "DEPTH %d\n", img.channels());
tmp += snprintf( buffer + tmp, bufsize - tmp, "MAXVAL %d\n", (1 << img.elemSize1()*8) - 1);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to use std::string / std::ostringstream (preferable) instead (refactor code).

snprintf could return negative values (in general, but not in this case) and they are not handled properly.

int header_sz = sprintf(buffer, "P%c\n%d %d\n",
int header_sz = snprintf(buffer, bufferSize, "P%c\n%d %d\n",
(char)('0' + code), width, height);
CV_Assert(header_sz > 0);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bufferSize < bufferSize should be checked too.


CV_EXPORTS const char* convertTypeStr(int sdepth, int ddepth, int cn, char* buf);
CV_EXPORTS CV_DEPRECATED const char* convertTypeStr(int sdepth, int ddepth, int cn, char* buf);
CV_EXPORTS String convertTypeStr(int sdepth, int ddepth, int cn);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add buf_size parameter instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of returning String? i.e. you would prefer:

CV_EXPORTS const char* convertTypeStr(int sdepth, int ddepth, int cn, char* buf, size_t buf_size);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, lets avoid calls for heap memory allocation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK done.

@seanm
Copy link
Copy Markdown
Contributor Author

seanm commented Apr 25, 2023

Hmmm, I'm a bit confused as to why this PR is showing the commits from #23055 even though I have done git rebase master. That PR shows as merged, but I don't see them in git log...

@opencv-alalek
Copy link
Copy Markdown
Contributor

git rebase master

Please rebase on "4.x" instead of "master" (as the target branch of this PR is "4.x"). E.g.:

git rebase -i upstream/4.x

BTW, due to banned credentials master is not updating in our infrastructure (master is just a shadow copy of 4.x).

…ffer size

This allows removing the unsafe sprintf.
@seanm seanm changed the title WIP: more sprintf removals more sprintf removals Apr 26, 2023
@seanm
Copy link
Copy Markdown
Contributor Author

seanm commented Apr 26, 2023

git rebase -i upstream/4.x

That seemed to work, thanks!

Copy link
Copy Markdown
Contributor

@opencv-alalek opencv-alalek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 Thank you!

snprintf(buf, buf_size, "convert_%s%s_rte", typestr, (ddepth < CV_32S ? "_sat" : ""));
else
snprintf(buf, buf_max, "convert_%s_sat", typestr);
snprintf(buf, buf_size, "convert_%s_sat", typestr);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to check snprintf return values.
We don't really want to go forward with truncated messages ("fail fast" is preferable).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And do what if truncation occurs? Return NULL? None of the callers of convertTypeStr appear ready to get NULL.

Anyway, truncation is much better than a buffer overrun, which is what would happen before this PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return NULL

No, my proposal to use CV_Assert() or CV_Check*() macros (they work in both debug/release modes). These calls raise C++ exception on a problem.


Anyway, truncation is much better than a buffer overrun, which is what would happen before this PR.

Agreed. Thank you for the fix!

@opencv-alalek opencv-alalek self-assigned this Apr 26, 2023
@opencv-pushbot opencv-pushbot merged commit 46e2b67 into opencv:4.x Apr 26, 2023
@asmorkalov asmorkalov mentioned this pull request May 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants