[Interest] Strange undeletable QTemporaryFile. Is it a bug?

Alex Malyushytskyy alexmalvtk at gmail.com
Wed Aug 28 01:55:44 CEST 2013


>> Technically, it is meant to be public. It closes the QIODevice so you
can no
longer read from it or write to it.

>> Actually, isn't "rely on the interface, not
implementation" the primary idea of inheritance?


QIODevice::close() - closes the device

when

QTemporaryFile::close() truncates and repositions, but doesn't *close* the
file. If you really want to close, destroy the object or force it to open a
new
file (with a new name).

According to above, example below does not make sense
cause you can't delete file after call to bar(). .
Relying on  interface is already broken.

>     void bar (QIODevice& zzz)
>     {
>         // ...
>         zzz.close(); // Oops
>     }
>
>     void foo ()
>     {
>         QTemporaryFile file;
>         bar(file);
>     }

The whole problem is that QTemporaryFile::close() does not do what it is
supposed to do.
And I see only 2 ways to fix it:

1. Change the interface so user can't call function which is source of the
problem.
2. Change implementation so close works as expected.

Thiago said that this approach may have security issues.

>> The only way to make it work would be for close() to unset the fileName()
again. When open() is called again, it creates a new file name based on the
template.
>> Which is exactly what you don't want.

I might be missing something , but I would can't see why not.

If you say that lifetime of the temporary file (including name) is limited
by opening and closing
I do not see any security issues.
It is also what I would expect temporary file to do by default.

If user wants to deal with this file later he remember the file name before
closing and disable autodelete.
All functionality is there.
This change might require user to change his code when upgrading if user
relied on implementation though.


Regards,
     Alex



On Mon, Aug 26, 2013 at 8:57 PM, Constantin Makshin <cmakshin at gmail.com>wrote:

> The bar() function from that example may be part of a library that
> neither wants nor needs to know anything about specifics of the actual
> type of 'zzz'. Actually, isn't "rely on the interface, not
> implementation" the primary idea of inheritance?
>
> On 08/27/2013 02:36 AM, Alex Malyushytskyy wrote:
> > Making function which were public in the parent, private in the child
> > shows that function should not be called.
> > That is it.  And that is the case.
> > It does not make it impossible to shoot yourself at the feet (whatever
> > way you choose)  and access it.
> > You can do everything in C++.
> >
> > But if you do it, it is your problem and responsibility and you do not
> > feel frustrated cause the behavior does not meet your expectations.
> > QTemporaryFile::close () is not meant to be public. User have no use of
> > it. Make it private and this question will not ever rise again.
> >
> > On Sun, Aug 25, 2013 at 4:02 AM, Constantin Makshin <cmakshin at gmail.com
> > <mailto:cmakshin at gmail.com>> wrote:
> >
> >     void bar (QIODevice& zzz)
> >     {
> >         // ...
> >         zzz.close(); // Oops
> >     }
> >
> >     void foo ()
> >     {
> >         QTemporaryFile file;
> >         bar(file);
> >     }
> >
> >     The function bar() may be replaced by anything that doesn't care
> >     what type I/O object to work with (e.g. QDataStream). "Why the hell
> >     does a function close an object owned by something else?" is another
> >     question, but the idea as a whole is simple and obvious -- if a
> >     function works with a base class (e.g. anything that can act as an
> >     I/O device, be it an actual file, memory buffer, etc.), the hint
> >     "don't call this method because in one of derived classes it does
> >     not what the name implies" doesn't work.
> >
> >     On Aug 24, 2013 2:05 PM, "Till Oliver Knoll"
> >     <till.oliver.knoll at gmail.com <mailto:till.oliver.knoll at gmail.com>>
> >     wrote:
> >
> >         Am 24.08.2013 um 09:46 schrieb Constantin Makshin
> >         <cmakshin at gmail.com <mailto:cmakshin at gmail.com>>:
> >
> >>         Overriding a public method to make it private doesn't make
> >>         much sense because this restriction can be easily circumvented
> >>         by casting the pointer/reference to a base class (explicitly
> >>         or by passing it to a function, in the context of this thread,
> >>         expects a QFile or even more generic QIODevice).
> >>
> >         Casting? Pointers? Why so complicated?
> >
> >         C++ makes this easy for you:
> >
> >         #define private public
> >         #include "Foo.h"
> >
> >         There you go: all private members of class Foo have just become
> >         public! A hip hip horray for the preprocessor ;)
> >
> >         Oh, by the way: should you feel the urge to pass on this "tip"
> >         to someone else: please don't mention my name, will you? ;)
> >
> >
> >         But on a more serious note: overriding a public method and make
> >         it private is more like a "design decision" and a strong hint to
> >         the caller not to call this member on that concrete class
> >         instance anymore: why not? Go read the docs! (And if you still
> >         feel like calling it: C++ offers you plenty of choices ;))
> >
> >         Cheers,
> >           Oliver
>
>
> _______________________________________________
> Interest mailing list
> Interest at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/interest
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20130827/46d1b681/attachment.html>


More information about the Interest mailing list