Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
7506dab2
Commit
7506dab2
authored
Jul 19, 2012
by
Meador Inge
Browse files
Options
Browse Files
Download
Plain Diff
Issue #6493: Fix handling of c_uint32 bitfields with width of 32 on Windows.
parents
c958ca8f
60c2266a
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
46 additions
and
28 deletions
+46
-28
Lib/ctypes/test/test_bitfields.py
Lib/ctypes/test/test_bitfields.py
+20
-0
Misc/NEWS
Misc/NEWS
+3
-0
Modules/_ctypes/cfield.c
Modules/_ctypes/cfield.c
+23
-28
No files found.
Lib/ctypes/test/test_bitfields.py
View file @
7506dab2
...
@@ -240,5 +240,25 @@ class BitFieldTest(unittest.TestCase):
...
@@ -240,5 +240,25 @@ class BitFieldTest(unittest.TestCase):
_anonymous_
=
[
"_"
]
_anonymous_
=
[
"_"
]
_fields_
=
[(
"_"
,
X
)]
_fields_
=
[(
"_"
,
X
)]
@
unittest
.
skipUnless
(
hasattr
(
ctypes
,
"c_uint32"
),
"c_int32 is required"
)
def
test_uint32
(
self
):
class
X
(
Structure
):
_fields_
=
[(
"a"
,
c_uint32
,
32
)]
x
=
X
()
x
.
a
=
10
self
.
assertEquals
(
x
.
a
,
10
)
x
.
a
=
0xFDCBA987
self
.
assertEquals
(
x
.
a
,
0xFDCBA987
)
@
unittest
.
skipUnless
(
hasattr
(
ctypes
,
"c_uint64"
),
"c_int64 is required"
)
def
test_uint64
(
self
):
class
X
(
Structure
):
_fields_
=
[(
"a"
,
c_uint64
,
64
)]
x
=
X
()
x
.
a
=
10
self
.
assertEquals
(
x
.
a
,
10
)
x
.
a
=
0xFEDCBA9876543211
self
.
assertEquals
(
x
.
a
,
0xFEDCBA9876543211
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
unittest
.
main
()
unittest
.
main
()
Misc/NEWS
View file @
7506dab2
...
@@ -138,6 +138,9 @@ C API
...
@@ -138,6 +138,9 @@ C API
Extension Modules
Extension Modules
-----------------
-----------------
- Issue #6493: An issue in ctypes on Windows that caused structure bitfields
of type ctypes.c_uint32 and width 32 to incorrectly be set has been fixed.
- Issue #15194: Update libffi to the 3.0.11 release.
- Issue #15194: Update libffi to the 3.0.11 release.
Tools/Demos
Tools/Demos
...
...
Modules/_ctypes/cfield.c
View file @
7506dab2
...
@@ -427,12 +427,8 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
...
@@ -427,12 +427,8 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
#define LOW_BIT(x) ((x) & 0xFFFF)
#define LOW_BIT(x) ((x) & 0xFFFF)
#define NUM_BITS(x) ((x) >> 16)
#define NUM_BITS(x) ((x) >> 16)
/* This seems nore a compiler issue than a Windows/non-Windows one */
/* Doesn't work if NUM_BITS(size) == 0, but it never happens in SET() call. */
#ifdef MS_WIN32
#define BIT_MASK(type, size) (((((type)1 << (NUM_BITS(size) - 1)) - 1) << 1) + 1)
# define BIT_MASK(size) ((1 << NUM_BITS(size))-1)
#else
# define BIT_MASK(size) ((1LL << NUM_BITS(size))-1)
#endif
/* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
/* This macro CHANGES the first parameter IN PLACE. For proper sign handling,
we must first shift left, then right.
we must first shift left, then right.
...
@@ -444,10 +440,10 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
...
@@ -444,10 +440,10 @@ get_ulonglong(PyObject *v, unsigned PY_LONG_LONG *p)
}
}
/* This macro RETURNS the first parameter with the bit field CHANGED. */
/* This macro RETURNS the first parameter with the bit field CHANGED. */
#define SET(x, v, size) \
#define SET(
type,
x, v, size) \
(NUM_BITS(size) ? \
(NUM_BITS(size) ? \
( (
x & ~(BIT_MASK(size) << LOW_BIT(size)) ) | ( (v & BIT_MASK(
size)) << LOW_BIT(size) ) ) \
( (
(type)x & ~(BIT_MASK(type, size) << LOW_BIT(size)) ) | ( ((type)v & BIT_MASK(type,
size)) << LOW_BIT(size) ) ) \
: v)
:
(type)
v)
/* byte swapping macros */
/* byte swapping macros */
#define SWAP_2(v) \
#define SWAP_2(v) \
...
@@ -519,7 +515,7 @@ b_set(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -519,7 +515,7 @@ b_set(void *ptr, PyObject *value, Py_ssize_t size)
long
val
;
long
val
;
if
(
get_long
(
value
,
&
val
)
<
0
)
if
(
get_long
(
value
,
&
val
)
<
0
)
return
NULL
;
return
NULL
;
*
(
signed
char
*
)
ptr
=
(
signed
char
)
SET
(
*
(
signed
char
*
)
ptr
,
(
signed
char
)
val
,
size
);
*
(
signed
char
*
)
ptr
=
SET
(
signed
char
,
*
(
signed
char
*
)
ptr
,
val
,
size
);
_RET
(
value
);
_RET
(
value
);
}
}
...
@@ -538,8 +534,7 @@ B_set(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -538,8 +534,7 @@ B_set(void *ptr, PyObject *value, Py_ssize_t size)
unsigned
long
val
;
unsigned
long
val
;
if
(
get_ulong
(
value
,
&
val
)
<
0
)
if
(
get_ulong
(
value
,
&
val
)
<
0
)
return
NULL
;
return
NULL
;
*
(
unsigned
char
*
)
ptr
=
(
unsigned
char
)
SET
(
*
(
unsigned
char
*
)
ptr
,
*
(
unsigned
char
*
)
ptr
=
SET
(
unsigned
char
,
*
(
unsigned
char
*
)
ptr
,
val
,
size
);
(
unsigned
short
)
val
,
size
);
_RET
(
value
);
_RET
(
value
);
}
}
...
@@ -560,7 +555,7 @@ h_set(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -560,7 +555,7 @@ h_set(void *ptr, PyObject *value, Py_ssize_t size)
if
(
get_long
(
value
,
&
val
)
<
0
)
if
(
get_long
(
value
,
&
val
)
<
0
)
return
NULL
;
return
NULL
;
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
x
=
SET
(
x
,
(
short
)
val
,
size
);
x
=
SET
(
short
,
x
,
val
,
size
);
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
_RET
(
value
);
_RET
(
value
);
}
}
...
@@ -575,7 +570,7 @@ h_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -575,7 +570,7 @@ h_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return
NULL
;
return
NULL
;
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
field
=
SWAP_2
(
field
);
field
=
SWAP_2
(
field
);
field
=
SET
(
field
,
(
short
)
val
,
size
);
field
=
SET
(
short
,
field
,
val
,
size
);
field
=
SWAP_2
(
field
);
field
=
SWAP_2
(
field
);
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
_RET
(
value
);
_RET
(
value
);
...
@@ -608,7 +603,7 @@ H_set(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -608,7 +603,7 @@ H_set(void *ptr, PyObject *value, Py_ssize_t size)
if
(
get_ulong
(
value
,
&
val
)
<
0
)
if
(
get_ulong
(
value
,
&
val
)
<
0
)
return
NULL
;
return
NULL
;
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
x
=
SET
(
x
,
(
unsigned
short
)
val
,
size
);
x
=
SET
(
unsigned
short
,
x
,
val
,
size
);
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
_RET
(
value
);
_RET
(
value
);
}
}
...
@@ -622,7 +617,7 @@ H_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -622,7 +617,7 @@ H_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return
NULL
;
return
NULL
;
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
field
=
SWAP_2
(
field
);
field
=
SWAP_2
(
field
);
field
=
SET
(
field
,
(
unsigned
short
)
val
,
size
);
field
=
SET
(
unsigned
short
,
field
,
val
,
size
);
field
=
SWAP_2
(
field
);
field
=
SWAP_2
(
field
);
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
_RET
(
value
);
_RET
(
value
);
...
@@ -656,7 +651,7 @@ i_set(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -656,7 +651,7 @@ i_set(void *ptr, PyObject *value, Py_ssize_t size)
if
(
get_long
(
value
,
&
val
)
<
0
)
if
(
get_long
(
value
,
&
val
)
<
0
)
return
NULL
;
return
NULL
;
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
x
=
SET
(
x
,
(
int
)
val
,
size
);
x
=
SET
(
int
,
x
,
val
,
size
);
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
_RET
(
value
);
_RET
(
value
);
}
}
...
@@ -670,7 +665,7 @@ i_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -670,7 +665,7 @@ i_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return
NULL
;
return
NULL
;
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
field
=
SWAP_INT
(
field
);
field
=
SWAP_INT
(
field
);
field
=
SET
(
field
,
(
int
)
val
,
size
);
field
=
SET
(
int
,
field
,
val
,
size
);
field
=
SWAP_INT
(
field
);
field
=
SWAP_INT
(
field
);
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
_RET
(
value
);
_RET
(
value
);
...
@@ -757,7 +752,7 @@ I_set(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -757,7 +752,7 @@ I_set(void *ptr, PyObject *value, Py_ssize_t size)
if
(
get_ulong
(
value
,
&
val
)
<
0
)
if
(
get_ulong
(
value
,
&
val
)
<
0
)
return
NULL
;
return
NULL
;
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
x
=
SET
(
x
,
(
unsigned
int
)
val
,
size
);
x
=
SET
(
unsigned
int
,
x
,
val
,
size
);
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
_RET
(
value
);
_RET
(
value
);
}
}
...
@@ -770,7 +765,7 @@ I_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -770,7 +765,7 @@ I_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
if
(
get_ulong
(
value
,
&
val
)
<
0
)
if
(
get_ulong
(
value
,
&
val
)
<
0
)
return
NULL
;
return
NULL
;
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
field
=
(
unsigned
int
)
SET
(
field
,
(
unsigned
int
)
val
,
size
);
field
=
SET
(
unsigned
int
,
field
,
(
unsigned
int
)
val
,
size
);
field
=
SWAP_INT
(
field
);
field
=
SWAP_INT
(
field
);
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
_RET
(
value
);
_RET
(
value
);
...
@@ -804,7 +799,7 @@ l_set(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -804,7 +799,7 @@ l_set(void *ptr, PyObject *value, Py_ssize_t size)
if
(
get_long
(
value
,
&
val
)
<
0
)
if
(
get_long
(
value
,
&
val
)
<
0
)
return
NULL
;
return
NULL
;
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
x
=
SET
(
x
,
val
,
size
);
x
=
SET
(
long
,
x
,
val
,
size
);
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
_RET
(
value
);
_RET
(
value
);
}
}
...
@@ -818,7 +813,7 @@ l_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -818,7 +813,7 @@ l_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return
NULL
;
return
NULL
;
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
field
=
SWAP_LONG
(
field
);
field
=
SWAP_LONG
(
field
);
field
=
(
long
)
SET
(
field
,
val
,
size
);
field
=
SET
(
long
,
field
,
val
,
size
);
field
=
SWAP_LONG
(
field
);
field
=
SWAP_LONG
(
field
);
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
_RET
(
value
);
_RET
(
value
);
...
@@ -852,7 +847,7 @@ L_set(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -852,7 +847,7 @@ L_set(void *ptr, PyObject *value, Py_ssize_t size)
if
(
get_ulong
(
value
,
&
val
)
<
0
)
if
(
get_ulong
(
value
,
&
val
)
<
0
)
return
NULL
;
return
NULL
;
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
x
=
SET
(
x
,
val
,
size
);
x
=
SET
(
unsigned
long
,
x
,
val
,
size
);
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
_RET
(
value
);
_RET
(
value
);
}
}
...
@@ -866,7 +861,7 @@ L_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -866,7 +861,7 @@ L_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return
NULL
;
return
NULL
;
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
field
=
SWAP_LONG
(
field
);
field
=
SWAP_LONG
(
field
);
field
=
(
unsigned
long
)
SET
(
field
,
val
,
size
);
field
=
SET
(
unsigned
long
,
field
,
val
,
size
);
field
=
SWAP_LONG
(
field
);
field
=
SWAP_LONG
(
field
);
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
_RET
(
value
);
_RET
(
value
);
...
@@ -901,7 +896,7 @@ q_set(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -901,7 +896,7 @@ q_set(void *ptr, PyObject *value, Py_ssize_t size)
if
(
get_longlong
(
value
,
&
val
)
<
0
)
if
(
get_longlong
(
value
,
&
val
)
<
0
)
return
NULL
;
return
NULL
;
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
x
=
SET
(
x
,
val
,
size
);
x
=
SET
(
PY_LONG_LONG
,
x
,
val
,
size
);
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
_RET
(
value
);
_RET
(
value
);
}
}
...
@@ -915,7 +910,7 @@ q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -915,7 +910,7 @@ q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return
NULL
;
return
NULL
;
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
field
=
SWAP_8
(
field
);
field
=
SWAP_8
(
field
);
field
=
(
PY_LONG_LONG
)
SET
(
field
,
val
,
size
);
field
=
SET
(
PY_LONG_LONG
,
field
,
val
,
size
);
field
=
SWAP_8
(
field
);
field
=
SWAP_8
(
field
);
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
_RET
(
value
);
_RET
(
value
);
...
@@ -948,7 +943,7 @@ Q_set(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -948,7 +943,7 @@ Q_set(void *ptr, PyObject *value, Py_ssize_t size)
if
(
get_ulonglong
(
value
,
&
val
)
<
0
)
if
(
get_ulonglong
(
value
,
&
val
)
<
0
)
return
NULL
;
return
NULL
;
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
memcpy
(
&
x
,
ptr
,
sizeof
(
x
));
x
=
SET
(
x
,
val
,
size
);
x
=
SET
(
PY_LONG_LONG
,
x
,
val
,
size
);
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
memcpy
(
ptr
,
&
x
,
sizeof
(
x
));
_RET
(
value
);
_RET
(
value
);
}
}
...
@@ -962,7 +957,7 @@ Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
...
@@ -962,7 +957,7 @@ Q_set_sw(void *ptr, PyObject *value, Py_ssize_t size)
return
NULL
;
return
NULL
;
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
memcpy
(
&
field
,
ptr
,
sizeof
(
field
));
field
=
SWAP_8
(
field
);
field
=
SWAP_8
(
field
);
field
=
(
unsigned
PY_LONG_LONG
)
SET
(
field
,
val
,
size
);
field
=
SET
(
unsigned
PY_LONG_LONG
,
field
,
val
,
size
);
field
=
SWAP_8
(
field
);
field
=
SWAP_8
(
field
);
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
memcpy
(
ptr
,
&
field
,
sizeof
(
field
));
_RET
(
value
);
_RET
(
value
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment