Skip to content

fixes #15155#16509

Merged
opencv-pushbot merged 1 commit intoopencv:3.4from
ohtlab:imwrite-throwerr-permissiondenied
Feb 6, 2020
Merged

fixes #15155#16509
opencv-pushbot merged 1 commit intoopencv:3.4from
ohtlab:imwrite-throwerr-permissiondenied

Conversation

@ohtlab
Copy link
Copy Markdown
Contributor

@ohtlab ohtlab commented Feb 5, 2020

resolves #15155

This pull request adds changes to modules/imgcodecs/src/loadsave.cpp

imwrite_ now describes permission denied error when a user does not have write permission in directory.

Example:

import cv2
import numpy as np

img = 255*np.ones((100,100),dtype=np.uint8)

#writing in permissible directory
ret = cv2.imwrite('myImage.png',img)
print('imwrite returned: ',ret)

#writing in non permissible directory
ret = cv2.imwrite('/myImage.png',img)
print('imwrite returned: ',ret)

Code Output:

imwrite returned:  True
[ WARN:0] imwrite_('/myImage.png'): can't open file for writing: permission denied
imwrite returned:  False

@dkurt
Copy link
Copy Markdown
Member

dkurt commented Feb 5, 2020

This patch changes key behavior of imwrite - it returns boolean flag to indicate success of operation. Nobody expect exceptions here.

So as the solution mentioned issue we expected documentation improvement regarding it.

@ohtlab ohtlab force-pushed the imwrite-throwerr-permissiondenied branch from 4cb93dd to 5538b70 Compare February 5, 2020 08:27
@ohtlab
Copy link
Copy Markdown
Contributor Author

ohtlab commented Feb 5, 2020

@dkurt Output of imwrite will still be a boolean, however, permission denied error message will simply be printed on stdcerr in case of exception as it is being catched in try { } catch { } block. This patch simply describes the permission denied error so it will be easier to debug for end user. I do notice that imwrite does not always return a boolean i.e. if invalid file extension is specified: cv2.imwrite('test.abc',img), it will throw an exception and exit code. I'm sorry if I misunderstood your comment, I'm open to suggestions.

@ohtlab ohtlab force-pushed the imwrite-throwerr-permissiondenied branch from 5538b70 to 789d048 Compare February 5, 2020 09:17
Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

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

It is better to avoid trying file before decoding.
Avoid changes in "successful path".

Perhaps it make sense to try:

  • moving this check in encoders itself (some of them don't open files directly - uses 3rdparty libraries which we should not change)
  • and/or trying permission denied diagnostic only if encoding call was failed.

{
if (errno == EACCES)
{
CV_Error( Error::StsError, "permission denied" );
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please use logging:

CV_LOG_WARNING(NULL, "imwrite(): Can't open file for writing: " << filename);
return false;

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.

I have updated my code accordingly. I did initially consider trying for file access in all encoders however, as you've said, the implementations of encoder.write are different. This could potentially raise more issues in the process and may not be so elegant. Thus I've opted for second suggestion.

else
{
fclose(f);
remove(filename.c_str());
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There is some chance that we may get problem like this again: #12342
See general note.

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.

I believe this issue is not something caused by OpenCV itself but rather an inherent could-be problem that can occur in some OS's like Windows which don't allow mutual sharing of file. In the unlikely scenario that the program lands on this else condition, it will at worse create a temporary file that is not removed, imwrite will still not crash as remove will simply return non zero. I think this could occur if another process from OS accesses the temporary file in between fclose() and remove() function. I will try to generate this occurrence by building opencv without the condition imposed by if( !f ) and share my findings. Additionally, I could further add warning log if fclose() and remove() do not return 0.

@dkurt
Copy link
Copy Markdown
Member

dkurt commented Feb 5, 2020

@omasaht, thanks, got it! With code example it's clear now.

…write_ function when user does not have write permission
@ohtlab ohtlab force-pushed the imwrite-throwerr-permissiondenied branch from 789d048 to 8dd0fd8 Compare February 5, 2020 18:04
Copy link
Copy Markdown
Member

@alalek alalek left a comment

Choose a reason for hiding this comment

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

Well done! Thank you 👍

@opencv-pushbot opencv-pushbot merged commit 8dd0fd8 into opencv:3.4 Feb 6, 2020
@alalek alalek mentioned this pull request Feb 10, 2020
@asmorkalov asmorkalov added the Hackathon https://opencv.org/opencv-hackathon-starts-next-week/ label Feb 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: imgcodecs feature Hackathon https://opencv.org/opencv-hackathon-starts-next-week/

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cv2.imwrite does not report error if user does not have permission to write to a directory

5 participants