Patchwork [1,of,4] win32: work around a WinError problem handling HRESULT types

login
register
mail settings
Submitter Matt Harbison
Date July 13, 2017, 10:40 p.m.
Message ID <34ade5bfcf96b840ee36.1499985605@MATT7H-PC.attotech.com>
Download mbox | patch
Permalink /patch/22302/
State Accepted
Headers show

Comments

Matt Harbison - July 13, 2017, 10:40 p.m.
# HG changeset patch
# User Matt Harbison <matt_harbison@yahoo.com>
# Date 1490848380 14400
#      Thu Mar 30 00:33:00 2017 -0400
# Node ID 34ade5bfcf96b840ee3643d2429f44865b977749
# Parent  26e4ba058215e536d3827befbea99ff6203d35f8
win32: work around a WinError problem handling HRESULT types

I ran into this ctypes bug while working with the Crypto API.  While this could
be an issue with any Win32 API in theory, the handful of things that we call are
older functions that are unlikely to return COM errors, so I didn't retrofit
this everywhere.
Gregory Szorc - July 14, 2017, 4:29 a.m.
On Thu, Jul 13, 2017 at 3:40 PM, Matt Harbison <mharbison72@gmail.com>
wrote:

> # HG changeset patch
> # User Matt Harbison <matt_harbison@yahoo.com>
> # Date 1490848380 14400
> #      Thu Mar 30 00:33:00 2017 -0400
> # Node ID 34ade5bfcf96b840ee3643d2429f44865b977749
> # Parent  26e4ba058215e536d3827befbea99ff6203d35f8
> win32: work around a WinError problem handling HRESULT types
>

I queued part 1.

My eyes are glazing over the other parts. I'll try to review them tomorrow
if someone else doesn't get to them first.


>
> I ran into this ctypes bug while working with the Crypto API.  While this
> could
> be an issue with any Win32 API in theory, the handful of things that we
> call are
> older functions that are unlikely to return COM errors, so I didn't
> retrofit
> this everywhere.
>
> diff --git a/mercurial/win32.py b/mercurial/win32.py
> --- a/mercurial/win32.py
> +++ b/mercurial/win32.py
> @@ -212,7 +212,12 @@ except AttributeError:
>  _kernel32.PeekNamedPipe.restype = _BOOL
>
>  def _raiseoserror(name):
> -    err = ctypes.WinError()
> +    # Force the code to a signed int to avoid an 'int too large' error.
> +    # See https://bugs.python.org/issue28474
> +    code = _kernel32.GetLastError()
> +    if code > 0x7fffffff:
> +        code -= 2**32
> +    err = ctypes.WinError(code=code)
>      raise OSError(err.errno, '%s: %s' % (name, err.strerror))
>
>  def _getfileinfo(name):
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>

Patch

diff --git a/mercurial/win32.py b/mercurial/win32.py
--- a/mercurial/win32.py
+++ b/mercurial/win32.py
@@ -212,7 +212,12 @@  except AttributeError:
 _kernel32.PeekNamedPipe.restype = _BOOL
 
 def _raiseoserror(name):
-    err = ctypes.WinError()
+    # Force the code to a signed int to avoid an 'int too large' error.
+    # See https://bugs.python.org/issue28474
+    code = _kernel32.GetLastError()
+    if code > 0x7fffffff:
+        code -= 2**32
+    err = ctypes.WinError(code=code)
     raise OSError(err.errno, '%s: %s' % (name, err.strerror))
 
 def _getfileinfo(name):