Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Crash when using character with umlaut #2016

Merged
merged 1 commit into from

2 participants

@mdboom
Owner

From the matplotlib-users thread entitled "problem with a umlaut" started by Ojala Janne.

    -*- coding: utf-8 -*-
    import matplotlib.pyplot as plt

    fig = plt.figure( )

    ax = fig.add_subplot(111)
    ax.hist([1,2,3,4,5,6,7,8,9,10], bins=range(1,11) )

    plt.ylabel(u'ä')
    fig.savefig('test.eps')

Christoph Gohlke adds:

I can reproduce the crash on Python 2.7, 32 and 64 bit. Python 2.6 and 3.3 appear to work. The call stack is attached. The crash is in ttfont_add_glyph_dependencies() at https://github.com/matplotlib/matplotlib/blob/v1.2.x/ttconv/pprdrv_tt2.cpp#L703

@mdboom
Owner

As a data point, I can't reproduce this with 1.2.x or master on Linux Python 2.7 or 3.3. So it's most likely something Windows-specific, and apparently specific to the STL implementation at that (oh joy).

@mdboom
Owner

As a workaround, does setting adding to the top

import matplotlib
matplotlib.rcParams['ps.fonttype'] = 42

help?

@mdboom
Owner

@cgohlke: This is a wild guess, but would you mind trying:

diff --git a/ttconv/pprdrv_tt2.cpp b/ttconv/pprdrv_tt2.cpp
index b3fc4b3..ca134e0 100644
--- a/ttconv/pprdrv_tt2.cpp
+++ b/ttconv/pprdrv_tt2.cpp
@@ -700,7 +700,7 @@ void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glyph_

                     std::vector<int>::iterator insertion =
                         std::lower_bound(glyph_ids.begin(), glyph_ids.end(), gind);
-                    if (*insertion != gind)
+                    if (insertion < glyph_ids.end() && *insertion != gind)
                     {
                         glyph_ids.insert(insertion, gind);
                         glyph_stack.push(gind);
@cgohlke

That doesn't crash but produces a corrupt EPS output.

@cgohlke

For reference, here's the relevant part of the call stack:

    msvcr90.dll!__crt_debugger_hook(int _Reserved=0)  Line 65   C
    msvcr90.dll!_invoke_watson(const wchar_t * pszExpression=0x000000000022e750, const wchar_t * pszFunction=0x00000000798363d3, const wchar_t * pszFile=0x0000000005ed9ddc, unsigned int nLine=109701576, unsigned __int64 pReserved=0)  Line 233  C++
    msvcr90.dll!_invalid_parameter(const wchar_t * pszExpression=0x0000000005f649a8, const wchar_t * pszFunction=0x0000000005b8ce88, const wchar_t * pszFile=0x000000000022e708, unsigned int nLine=2288096, unsigned __int64 pReserved=0)  Line 115    C++
    msvcr90.dll!_invalid_parameter_noinfo()  Line 126   C++
    ttconv.pyd!std::_Vector_const_iterator<int,std::allocator<int> >::operator*()  Line 106 C++
    ttconv.pyd!std::_Vector_iterator<int,std::allocator<int> >::operator*()  Line 340   C++
>   ttconv.pyd!ttfont_add_glyph_dependencies(TTFONT * font=0x000000000022e8c0, std::vector<int,std::allocator<int> > & glyph_ids=[13](17,19,20,21,22,23,24,25,26,27,28,36,174))  Line 703 + 0xd bytes   C++
    ttconv.pyd!read_font(const char * filename=0x0000000005f7fa60, font_type_enum target_type=PS_TYPE_3, std::vector<int,std::allocator<int> > & glyph_ids=[13](17,19,20,21,22,23,24,25,26,27,28,36,174), TTFONT & font={...})  Line 1326   C++
    ttconv.pyd!insert_ttfont(const char * filename=0x0000000005f7fa60, TTStreamWriter & stream={...}, font_type_enum target_type=PS_TYPE_3, std::vector<int,std::allocator<int> > & glyph_ids=[13](17,19,20,21,22,23,24,25,26,27,28,36,174))  Line 1336 C++
    ttconv.pyd!convert_ttf_to_ps(_object * self=0x0000000000000000, _object * args=0x0000000005f649a8, _object * kwds=0x0000000000000000)  Line 149 + 0x1f bytes    C++
    python27.dll!PyCFunction_Call(_object * func=0x0000000000000004, _object * arg=0x0000000001d57760, _object * kw=0x0000000005b8ce88)  Line 85 + 0x8 bytes    C

@mdboom
Owner

Sorry to "debug by remote"... Try this:

diff --git a/ttconv/pprdrv_tt2.cpp b/ttconv/pprdrv_tt2.cpp
index b3fc4b3..ca134e0 100644
--- a/ttconv/pprdrv_tt2.cpp
+++ b/ttconv/pprdrv_tt2.cpp
@@ -700,7 +700,7 @@ void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glyph_

                     std::vector<int>::iterator insertion =
                         std::lower_bound(glyph_ids.begin(), glyph_ids.end(), gind);
-                    if (*insertion != gind)
+                    if (insertion == glyph_ids.end() || *insertion != gind)
                     {
                         glyph_ids.insert(insertion, gind);
                         glyph_stack.push(gind);
@cgohlke

Thanks! That fixes the crash and produces the correct output. Any idea why this would only surface on Python 2.7?

@mdboom
Owner

I have no idea. The crash is happening because it's reading one element beyond the end of a STL vector, which in many cases wouldn't matter, but I think just due to unluckiness of memory layout it does. In any event, glad we've found a fix. I'll attach a real PR to this issue so we can merge it.

@mdboom mdboom merged commit 141c28b into matplotlib:v1.2.x
@mdboom mdboom deleted the mdboom:ttconv-crash branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 1 addition and 1 deletion.
  1. +1 −1  ttconv/pprdrv_tt2.cpp
View
2  ttconv/pprdrv_tt2.cpp
@@ -700,7 +700,7 @@ void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glyph_
std::vector<int>::iterator insertion =
std::lower_bound(glyph_ids.begin(), glyph_ids.end(), gind);
- if (*insertion != gind)
+ if (insertion == glyph_ids.end() || *insertion != gind)
{
glyph_ids.insert(insertion, gind);
glyph_stack.push(gind);
Something went wrong with that request. Please try again.