Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Convert unicode index to long, not int, in get_char_index #7768

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

Merged
merged 1 commit into from
Jan 9, 2017

Conversation

AdamWill
Copy link
Contributor

@AdamWill AdamWill commented Jan 9, 2017

There's an error in the PyFT2Font.get_char_index() method
added in 2d56ffeb . The type for the unicode index to be sent
to FT_Get_Char_Index is FT_ULong - an unsigned long - but
the PyArg_ParseTuple call that converts it from Python used
I in the format string, which converts a Python int to a C
unsigned int, not a C unsigned long. This doesn't seem to cause
a problem on little-endian arches, but it results in completely
incorrect conversion on big-endian arches, which in turn would
result in wrong glyphs, unfound glyphs, and even in an infinite
recursion in UnicodeFonts._get_glyph.

To get correct conversion we must use k not I, which is
the specifier for a C unsigned long.

Ref: https://docs.python.org/3/c-api/arg.html#numbers

There's an error in the `PyFT2Font.get_char_index()` method
added in 2d56ffeb . The type for the unicode index to be sent
to `FT_Get_Char_Index` is `FT_ULong` - an unsigned long - but
the `PyArg_ParseTuple` call that converts it from Python used
`I` in the format string, which converts a Python int to a C
unsigned int, not a C unsigned long. This doesn't seem to cause
a problem on little-endian arches, but it results in completely
incorrect conversion on big-endian arches, which in turn would
result in wrong glyphs, unfound glyphs, and even in an infinite
recursion in `UnicodeFonts._get_glyph`.

To get correct conversion we must use `k` not `I`, which is
the specifier for a C unsigned long.

Ref: https://docs.python.org/3/c-api/arg.html#numbers
@AdamWill
Copy link
Contributor Author

AdamWill commented Jan 9, 2017

BTW, I figured this out by modifying mathtext.py to log the uniindex value it was sending to get_char_index, and modifying get_char_index to log the ccode value, which obviously should be the same. On a big-endian arch (ppc64), it was not the same at all. This change makes it work - the Python and C functions log the same values, and all the conversion errors I was seeing before go away.

@AdamWill
Copy link
Contributor Author

AdamWill commented Jan 9, 2017

@mdboom (author of 2d56ffe)

Copy link
Member

@QuLogic QuLogic left a comment

Choose a reason for hiding this comment

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

Makes sense; on LE arches, the first 4 bytes would be filled, and assuming a zeroing stack, it should result in the same value. On BE arches, the first 4 bytes are the top-most bytes, so everything would be multiplied by 2**32.

Since it's an unsigned long, probably this worked fine on 32-bit BE arches (if any exist and were used.)

@AdamWill
Copy link
Contributor Author

AdamWill commented Jan 9, 2017

Note, there still appear to be several hundred other errors in the test suite on a ppc64 build. It seems like it would be a good idea to set up the CI to run the tests on a 64-bit be arch, if at all possible, so all those problems can be fixed and future ones won't be introduced...

@QuLogic yeah, that adds up. The incorrect values were indeed very large.

@QuLogic QuLogic added this to the 2.0 (style change major release) milestone Jan 9, 2017
@QuLogic
Copy link
Member

QuLogic commented Jan 9, 2017

I'm not sure there are any GitHub integrations that support ppc64; maybe copr, but I never understood how their webhooks worked.

@codecov-io
Copy link

Current coverage is 62.12% (diff: 100%)

Merging #7768 into master will not change coverage

@@             master      #7768   diff @@
==========================================
  Files           174        174          
  Lines         56028      56028          
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
  Hits          34805      34805          
  Misses        21223      21223          
  Partials          0          0          

Powered by Codecov. Last update eba130f...c4c0b65

@AdamWill
Copy link
Contributor Author

AdamWill commented Jan 9, 2017

hah, well, copr is a Fedora thing, so I guess that'd be my department...I could maybe talk to some people and see if we can hook anything up, I'll try and remember to give it a shot.

Copy link
Contributor

@dopplershift dopplershift left a comment

Choose a reason for hiding this comment

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

Good catch!

@dopplershift dopplershift merged commit b0e4b67 into matplotlib:master Jan 9, 2017
@QuLogic
Copy link
Member

QuLogic commented Jan 9, 2017 via email

@tacaswell
Copy link
Member

Is there a public log of the test results? iirc, from looking at the failures from debian's build system any of the failures are in the spectra tests in mlab which are very sensitive to small differences in floating point math.

@AdamWill
Copy link
Contributor Author

AdamWill commented Jan 9, 2017

Well, I did my test ppc64 build with the test suite enabled in a sandbox that fedora releng set up for me, but I can run it again and grab the log and put it up somewhere, I'll do that.

A more long-term solution might be, as @QuLogic suggested, to set up a COPR repository which has a simple spec (and uses the bundled freetype and so on, not like the official Fedora package build) and just tries to run a build every time there's a commit to this repo (or just does it every day or something).

@AdamWill
Copy link
Contributor Author

AdamWill commented Jan 9, 2017

Here's the build log of the ppc64 build with tests enabled:

build.log.txt

Looking at that, I'm seeing some more fun issues with integer types...digging into that right now. The freetype FT_Int32 and FT_UInt32 types (that are used for a couple of flags) are theoretically problematic as they can be int or long, but in practice they'll almost always be int, I think.

dopplershift added a commit that referenced this pull request Jan 9, 2017
Convert unicode index to long, not int, in get_char_index
@dopplershift
Copy link
Contributor

Backported to 2.x in bffe631

@QuLogic
Copy link
Member

QuLogic commented Jan 10, 2017

The freetype FT_Int32 and FT_UInt32 types (that are used for a couple of flags) are rather problematic as their type varies by arch, I think; I think they are ints on 64-bit arches and longs on 32-bit arches...

The preference seems to be (unsigned) int unless it's not 32-bit, but unless we're talking about embedded stuff, I'm not sure Fedora runs on anything that uses a 16-bit int.

@QuLogic
Copy link
Member

QuLogic commented Jan 10, 2017

@AdamWill BTW, that build is with beta4; you should try with rc2. I believe there should be fixes for several of those size warnings.

@AdamWill
Copy link
Contributor Author

@QuLogic yeah, I'm building beta4 for now just because the package spec has several patches applied that don't apply cleanly to rc2.

#7781 cuts the failure count down to 38, for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants