Ticket #3931: mythtv_xml_include_v2.diff

File mythtv_xml_include_v2.diff, 3.3 KB (added by Roo <roo.watt@…>, 14 years ago)

v2 addresses the issue raised by paulh

  • mythtv/libs/libmyth/xmlparse.h

     
    6464    double hmult;
    6565
    6666    int usetrans;
     67
     68    enum {INCLUDE_ITERATION_LIMIT = 10};
    6769   
    6870    QString fontSizeType;
    6971};
  • mythtv/libs/libmyth/xmlparse.cpp

     
    7575    f.close();
    7676
    7777    QDomElement docElem = doc.documentElement();
     78    QDomDocument incDoc;
     79    uint includeRecursionCount = 0;
     80
     81    // Find include elements
     82    QDomNodeList includeFileList = docElem.elementsByTagName("include_file");
     83    while ( includeFileList.count() )
     84    {
     85        // Node to be replaced in original document
     86        QDomNode replacementNode = includeFileList.item(0);
     87
     88        // Get include file name
     89        QString includeFile = replacementNode.toElement().attribute("src","");
     90        if (includeFile.isEmpty())
     91        {
     92            cerr << "Expecting <include_file src=\"filename.xml\"/>" << endl;
     93            return false;
     94        }
     95
     96        QFile g;
     97        bool fileSuccess = false;
     98        QValueList<QString> searchpath = gContext->GetThemeSearchPath();
     99        for (QValueList<QString>::const_iterator ii = searchpath.begin();
     100            ii != searchpath.end(); ii++)
     101        {
     102            g.setName( *ii + includeFile );
     103            if (g.open(IO_ReadOnly))
     104            {
     105                fileSuccess = true;
     106                break;
     107            }
     108        }
     109
     110        if (!fileSuccess)
     111        {
     112            cerr << "XMLParse::LoadTheme(): Can't open include_file: "
     113                << includeFile << endl;
     114            return false;
     115        }
     116
     117        // Import doc reporting on errors
     118        if (!incDoc.setContent(&g, false, &errorMsg, &errorLine, &errorColumn))
     119        {
     120            cerr << "Error parsing: " << includeFile << endl;
     121            cerr << "at line: " << errorLine
     122                 << "  column: " << errorColumn << endl;
     123            cerr << errorMsg << endl;
     124            cerr << "Includes MUST be valid XML documents"
     125                    " with a single root element!" << endl;
     126            g.close();
     127            return false;
     128        }
     129        g.close();
     130
     131        // Insert all children from the include file root
     132        QDomNodeList includeNodeList = incDoc.documentElement().childNodes();
     133        while( includeNodeList.count() )
     134            replacementNode.parentNode()
     135                .insertBefore( includeNodeList.item(0), replacementNode );
     136
     137        if ( docElem.isNull() )
     138        {
     139            cerr << "*** Error detected whilst including \""
     140                 << includeFile << "\"!" << endl;
     141            return false;
     142        }
     143
     144        // Error out if include iteration limit met
     145        if ( ++includeRecursionCount >= INCLUDE_ITERATION_LIMIT )
     146        {
     147            cerr << "Error iteration limit reached: " << INCLUDE_ITERATION_LIMIT << endl;
     148            return false;
     149        }
     150
     151        // Delete <include_file>s
     152        replacementNode.parentNode().removeChild( replacementNode );
     153    }
     154
    78155    QDomNode n = docElem.firstChild();
    79156    while (!n.isNull())
    80157    {