This is long. I'm sorry. But there are a lot of issues here.

Georg Baum wrote:
> The case that you are adressing was not thought of: Stuff that comes from
> a .lyx file is assumed to be correct (we do this elsewhere, too), and we
> were not aware about the minibuffer.
>   
The same issue arises with the server pipe, which is what I was actually
investigating. The minibuffer was just an easier way to test commands,
and a typo is what first triggered the crash.
>> In any event, this information was already 
>> stored in the name_ variable. I'm just storing it in a different form
>> and, in the process, dissocating the inset type from the command name,
>> which would allow a bit more flexibility if it were wanted. The key to
>> the patch is really the isCompatible() method, and that could have been
>> written without a converter or the InsetParamType enum thus:
>>     if (newname == "bibtex")
>>        if (oldname == "bibtext") return true;
>>        else return false;
>>     ...
>>     if (newname == "url" || newname == "htmlurl")
>>        if (oldname == "url" || oldname == "htmlurl") return true;
>>        else return false;
>> But that gets very ugly when you get more names involved. Hence the idea
>> of using the converter as a kind of helper method.
>>     
> This does not fit into the current design. Please do not soften it, if you 
> wnat to go along the lines of your patch please do it completely, 
I also don't know, apparently, what doing it completely would be. I
wasn't trying to do it half way!
> or use something that is compatible with the current design. For example, you
> could add an InsetBase::Code field to the CommandInfo struct. Then you can
> check very easily if the command is compatible to an inset by comparing the
> codes e.g. in the inset constructor. 
I thought about that, and in a way that's similar to the pure virtual
idea. But there are problems. First, and least importantly, it seems as
if we would then have to re-write the constructor of every inset that
uses InsetCommandParams. That's easy enough, just copying and modifying
code from findInfo(), e.g.:

InsetRef::InsetRef(InsetCommandParams const & p, Buffer const & buf)
: InsetCommand(p, "ref"), isLatex(buf.isLatex())
{
string cmd = params().getCommandName();
if (cmd != "eqref" && cmd != "pageref" && cmd != "vpageref" &&
cmd != "vref" && cmd != "prettyref" && cmd != "ref")
throw ExceptionMessage(WarningException,
_("Invalid command"),
from_utf8("Command " + cmd + " not recognized by InsetRef."));
}

Maybe that's the right way to do it, but it seems like duplication.
Perhaps it could be done in the InsetCommand constructor, but then
you're putting all the information about which inset accepts which kind
of command there rather than in InsetCommandParams, and I again don't
see the difference.

More importantly, however, if you really want to deal with this kind of
crash, this isn't the only place this check would need to be made.
InsetCommandParams has a setCmdName() method where an incompatible
command name could just as well be set, and then you'd get the same
crash. At present, this is only called directly in the apply() methods
of various dialogs, and perhaps we can trust them to ensure that only
valid commands are ever passed. But maybe not---are we sure no dialog
will ever allow the user to enter a command directly? And maybe it could
be called from somewhere else. But worse still, I haven't actually
tried, but I'm prepared to wager that I can trigger the same crash using
inset-apply rather than inset-insert. If I have an open inset, I'll go
through InsetCommand::doDispatch to string2params and from there to
InsetCommandParams::read(). So now we're doing the check in doDispatch,
too. Is there anywhere else it has to be done? I have no idea.

Surely there needs to be some central place this check is done. The only
central place is in InsetCommandParams itself. And the real issue, for
me, is that it just seems all wrong to me to make the parameter list
depend on the name of the command rather than on the type of the inset.
This issue comes up very sharply when you start to think about
supporting BibLaTeX, since there is no predefined list of citation
commands in BibLaTeX. Yes, you could try making the list of commands in
bilbio.C more flexible and call is_possible_cite_command instead of
hard-coding that same list in findInfo. But it still seems backwards to
me to have the list of parameters be determined by the command rather
than by the type of inset. And what now happens in findInfo is in fact
that the command name is mapped to the inset type. It's just not done
that way, though the comments make it plain that this is in fact what is
happening.

But here's a different question. Is there really any good reason to
allow info_ to be reset? Resetting it is what really causes the crash.
It needs to be reset only if the list of acceptable parameters could
change depending upon what name_ was, which is to say: If the list of
parameters associated with a given inset could change depending upon
what LaTeX command it represented. The extant code allows for this, but
no inset actually works that way. So suppose for a minute that we
decided not to permit this. Then the calls to findInfo() that are
presently made in setCmdName() and read() can be deleted, and the crash
is no more.

Now suppose we did want to permit it---and, again, maybe proper BibLaTeX
support requires it, and maybe it just seems like a good idea to permit
that flexibility. Then the inset can handle this: It can just destroy
its old params_ and make a new one. That's the simplest solution by far.
What do you think?
> Tnis would be an extension of thecurrent design: Simply store one more item 
> in the info table, but there is no duplicated list of command names.
>   
> PS: Did you read the comments in the header? InsetCommandParams is in a 
> transitional state, several methods that look ugly are supposed to go.
>   
Yes. The ugly methods don't impinge on what I was doing, but I did
briefly investigate how to get rid of them. Some of them are simple, but
getContents() is called a lot.

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

Reply via email to