Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mmap.flush does not check for errors on windows #46375

Closed
schmir mannequin opened this issue Feb 15, 2008 · 11 comments
Closed

mmap.flush does not check for errors on windows #46375

schmir mannequin opened this issue Feb 15, 2008 · 11 comments
Labels
3.8 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error

Comments

@schmir
Copy link
Mannequin

schmir mannequin commented Feb 15, 2008

BPO 2122
Nosy @pfmoore, @atsuoishimoto, @pitrou, @tjguk, @berkerpeksag, @zware, @serhiy-storchaka, @zooba
PRs
  • bpo-2122: Make mmap.flush() behave same on all platforms #8692
  • Files
  • mmap-flush.txt: make flush return None
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2018-08-22.18:22:51.751>
    created_at = <Date 2008-02-15.13:20:02.687>
    labels = ['3.8', 'type-bug', 'library']
    title = 'mmap.flush does not check for errors on windows'
    updated_at = <Date 2018-08-22.18:22:51.750>
    user = 'https://bugs.python.org/schmir'

    bugs.python.org fields:

    activity = <Date 2018-08-22.18:22:51.750>
    actor = 'berker.peksag'
    assignee = 'none'
    closed = True
    closed_date = <Date 2018-08-22.18:22:51.751>
    closer = 'berker.peksag'
    components = ['Library (Lib)']
    creation = <Date 2008-02-15.13:20:02.687>
    creator = 'schmir'
    dependencies = []
    files = ['9645']
    hgrepos = []
    issue_num = 2122
    keywords = ['patch']
    message_count = 11.0
    messages = ['62427', '63436', '65549', '65550', '65551', '138227', '242715', '323563', '323571', '323898', '323899']
    nosy_count = 10.0
    nosy_names = ['paul.moore', 'ishimoto', 'pitrou', 'ocean-city', 'schmir', 'tim.golden', 'berker.peksag', 'zach.ware', 'serhiy.storchaka', 'steve.dower']
    pr_nums = ['8692']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'behavior'
    url = 'https://bugs.python.org/issue2122'
    versions = ['Python 3.8']

    @schmir
    Copy link
    Mannequin Author

    schmir mannequin commented Feb 15, 2008

    mmap.flush returns the result of the call to FlushViewOfFile as an
    integer, and does not check for errors. On unix it does check for
    errors. The function should return None and raise an exception if an
    error occurs...
    This bug can lead to data loss...

    Here's the current version of that function:

    static PyObject *
    mmap_flush_method(mmap_object *self, PyObject *args)
    {
    	Py_ssize_t offset = 0;
    	Py_ssize_t size = self->size;
    	CHECK_VALID(NULL);
    	if (!PyArg_ParseTuple(args, "|nn:flush", &offset, &size))
    		return NULL;
    	if ((size_t)(offset + size) > self->size) {
    		PyErr_SetString(PyExc_ValueError, "flush values out of range");
    		return NULL;
    	}
    #ifdef MS_WINDOWS
    	return PyInt_FromLong((long) FlushViewOfFile(self->data+offset, size));
    #elif defined(UNIX)
    	/* XXX semantics of return value? */
    	/* XXX flags for msync? */
    	if (-1 == msync(self->data + offset, size, MS_SYNC)) {
    		PyErr_SetFromErrno(mmap_module_error);
    		return NULL;
    	}
    	return PyInt_FromLong(0);
    #else
    	PyErr_SetString(PyExc_ValueError, "flush not supported on this system");
    	return NULL;
    #endif
    }

    @schmir schmir mannequin added stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error labels Feb 15, 2008
    @schmir
    Copy link
    Mannequin Author

    schmir mannequin commented Mar 10, 2008

    attached is a patch. I hope it is ok to change the semantics a bit.
    They were very strange:

    • on unix it raises an exception on errors. otherwise it always returns 0.
    • on windows it returns non-zero on success, and returns zero on errors.

    Now, flush returns None or raises an Exception.

    @schmir
    Copy link
    Mannequin Author

    schmir mannequin commented Apr 16, 2008

    now this insanity is even documented with svn revision 62359
    (http://hgpy.de/py/trunk/rev/442252bce780)

    @pitrou
    Copy link
    Member

    pitrou commented Apr 16, 2008

    Perhaps it would be better if the patch came with unit tests. I agree
    that the situation right now is insane.

    PS : I have no power to commit or even accept a patch :)

    @schmir
    Copy link
    Mannequin Author

    schmir mannequin commented Apr 16, 2008

    I thought about this too, but I don't know of a way to provoke an error.
    (Other than passing in illegal values, but the code tries to catch
    those. And btw, raises an Exception on windows :)

    One could currently pass in a negative value for size (this isn't caught
    in the checks). e.g.

    m.flush(500, -500) gives an 'error: [Errno 22] Invalid argument' on linux.

    but then you don't want to rely on another bug for testing purposes.

    @briancurtin briancurtin self-assigned this Sep 3, 2010
    @ocean-city
    Copy link
    Mannequin

    ocean-city mannequin commented Jun 13, 2011

    This issue seems to be reproduced in following way.

    1. Attach USB flash drive. (On my machine, it was attached as E drive)

    2. Run python interactive shell and run following commands.
      (Confirmed on Python2.6)

    > import mmap
    > f = open("e:/temp.tmp", "w+b")
    > f.write("foo")
    > f.flush()
    > m = mmap.mmap(f.fileno(), 3)
    > m[:] = "xxx"

    1. Detach USB flash drive violently here! (Without safety mechanism
      to detach USB flash drive, just plug it off) Note that
      python shell is still running.

    2. Enter following command in python shell.
      > m.flush()
      It returns *0*. (Means failure)

    @BreamoreBoy
    Copy link
    Mannequin

    BreamoreBoy mannequin commented May 7, 2015

    I think we should be properly handling errors. If people agree I'll provide a new patch to cover code and doc changes, but I've no idea how to provide any form of unit test for the change.

    @serhiy-storchaka
    Copy link
    Member

    If we break compatibility in any case, what if return None instead of 0? The function always returning 0 looks strange. The function always returning None is common.

    @serhiy-storchaka serhiy-storchaka added the 3.8 only security fixes label Aug 15, 2018
    @zooba
    Copy link
    Member

    zooba commented Aug 15, 2018

    I agree. We should definitely document it as a change, but I don't think there's anything useful you can do in the case of a flush failing anyway, so it seems unlikely that anyone could depend on the return value.

    Returning None for success and exception on error sounds like a good change. Technically this is no longer returning zero, as previously documented, so if anyone wants to get *really* pedantic, we're not returning the "failed" result for success ;)

    @berkerpeksag
    Copy link
    Member

    New changeset e7d4b2f by Berker Peksag in branch 'master':
    bpo-2122: Make mmap.flush() behave same on all platforms (GH-8692)
    e7d4b2f

    @berkerpeksag
    Copy link
    Member

    Thanks for the suggestions and for the reviews!

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.8 only security fixes stdlib Python modules in the Lib dir type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    5 participants