Philippe Nobili wrote:
> 
> The ValidateHook mechanism is really easy to develop  & deploy. Ours is
> rather simple, just fixing bad IDs, excerpt:
> 
> *if( element.hasAttribute(ID) ) {
> 
>            String idstring = element.getAttribute(ID) ;
> 
>            if( idstring == null || !XMLText.isNCName(idstring) ) {
> 
>              element.putAttribute(ID,generateID());
>            }
> }

This is just the obvious part, but there is another part which
integrates the above snippet to XXE.



> 
> *This works fine, except under one circumstance: newly created elements
> are not fixed and keep their bad ID.
> 
> If we run the validator a second time (e.g. from XMLMind),

Such validators are automatically invoked when you use Tools|Validate or
File|Open and/or File|Save.



> their ID is fixed.
> If we create several new elements, then the ValidateHook fails to fix
> them all the first time it is ran, and fixes them all (as expected) the
> second time it is ran.

I don't see how this could be possible. Once attached to the document
tree, there is no difference between newly created elements and other
elements.




> 
> Are newly created elements supposed to be traversed by the ValidateHook
> mechanism, 

Yes.




> or did we do something wrong ?

Almost certainly yes.

Please find attached to your document the source code of a validator
which possibly modifies the document being validated/saved.

Tell your developers to adapt this code to your needs but to really
understand and keep the overall framework (Traversal.traverse,
element.isEditable(), doc.beginEdit()/doc.endEdit(),
UndoManager.describeUndo, etc).

All details are very important in order to have something which runs
really smoothly.






/*
 * Ensures that the value of the cols attribute of the DocBook tgroup element
 * corresponds to the actual number of columns of this tgroup.
 */
package com.xmlmind.xmleditext.docbook.table;

import java.net.URL;
import com.xmlmind.xml.doc.Element;
import com.xmlmind.xml.doc.Document;
import com.xmlmind.xml.doc.Traversal;
import com.xmlmind.xmledit.edit.UndoManager;
import com.xmlmind.xmleditapp.validatehook.Reason;
import com.xmlmind.xmleditapp.validatehook.ValidateHookBase;
import static com.xmlmind.xmleditext.docbook.table.TableAttributeName.COLS;

public final class ValidateHookImpl extends ValidateHookBase {
    @Override
    public void checkingDocument(final Document doc,
                                 Reason reason, URL saveAsURL) {
        // Do nothing unless we are saving the document.
        if (reason == null) {
            return;
        }
        switch (reason) {
        case SAVE:
        case SAVE_AS:
            break;
        default:
            return;
        }
        
        final int[] fixes = new int[1];

        Traversal.traverse(doc.getRootElement(), new Traversal.HandlerBase() {
            public Object enterElement(Element element) {
                String name = element.getLocalName();
                if ("tgroup".equals(name) || "entrytbl".equals(name)) {
                    int columnCount = RowGroupInfo.getColumnCount(element);
                    if (columnCount > 0) {
                        int cols = element.getIntAttribute(COLS, -1);
                        if (cols != columnCount && element.isEditable()) {
                            if (fixes[0] == 0) {
                                doc.beginEdit();
                            }

                            element.putAttribute(COLS,
                                                Integer.toString(columnCount));
                            ++fixes[0];
                        }
                    }
                }

                return null;
            }
        });

        if (fixes[0] > 0) {
            doc.endEdit();

            UndoManager.describeUndo(doc, Msg.msg("fixCols"));
        }
    }
}
 
--
XMLmind XML Editor Support List
[email protected]
http://www.xmlmind.com/mailman/listinfo/xmleditor-support

Reply via email to