I've been studying this bug a bit and think I know where the problem is,
more or less. The attached file is as minimal as I can get it. The
change of font is crucial. Without it, there is no crash.

Font::writeLatexEndChanges we have this code:
    if (open_encoding_) {
        // We need to close the encoding even if it does not change
        // to do correct environment nesting
        Encoding const * const ascii = encodings.getFromLyXName("ascii");
        int const c = switchEncoding(os, bparams,
                runparams.moving_arg, *(runparams.encoding),
                *ascii);
        BOOST_ASSERT(c > 0);
        count += c;
        runparams.encoding = ascii;
        open_encoding_ = false;
    }
It's the c>0 assertion that's triggering the crash. Now look at the
switchEncoding code that it hits:
int switchEncoding(odocstream & os, BufferParams const & bparams,
                   bool moving_arg, Encoding const & oldEnc,
                   Encoding const & newEnc)
{
[snip]
    docstring const inputenc(from_ascii(newEnc.latexName()));
    switch (newEnc.package()) {
        case Encoding::none:
            return 0;
        case Encoding::inputenc: {
[snip]
         }
        case Encoding::CJK: {
[snip]
        }
    }
This is going to return 0, since the call to switchEncoding()
essentially hardcoded newEnc as  ascii =
encodings.getFromLyXName("ascii"), and ascii->package() is
Encoding::none. That's clearly not what was wanted. The comment in
latexWriteEndChanges was: "We need to close the encoding even if it does
not change to do correct environment nesting". Passing *ascii doesn't do
that. You could pass a null pointer as a flag to force the encoding
closed, but there are other ways you COULD return 0. But maybe if we put
this right at the very beginning:
  if (!newEnc) {
    if (oldEnc.package() == Encoding::CJK) {
                os << "\\end{CJK}";
                return 9;
            }
     os << "{}"; // ugly hack
     return 2;
  }
Or something like that.

There's other weirdness here. Why do we get here anyway? This is above:
    if (oldEnc.package() == Encoding::none
        || newEnc.package() == Encoding::none)
        return 0;
I'm guessing that ought to have more parentheses.

Richard




-- 
==================================================================
Richard G Heck, Jr
Professor of Philosophy
Brown University
http://frege.brown.edu/heck/
==================================================================
Get my public key from http://sks.keyserver.penguin.de
Hash: 0x1DE91F1E66FFBDEC
Learn how to sign your email using Thunderbird and GnuPG at:
http://dudu.dyn.2-h.org/nist/gpg-enigmail-howto

Attachment: encoding.lyx
Description: application/lyx

Reply via email to