rism-digital / verovio

🎵 Music notation engraving library for MEI with MusicXML and Humdrum support and various toolkits (JavaScript, Python)
https://www.verovio.org
GNU Lesser General Public License v3.0
683 stars 185 forks source link

MIDI generation segmentation fault when syl contains rend #3546

Closed craigsapp closed 1 year ago

craigsapp commented 1 year ago

The following example MEI data causes a segmentation fault when calculating MIDI data:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0">
   <meiHead>
      <fileDesc>
         <titleStmt>
            <title />
         </titleStmt>
         <pubStmt />
      </fileDesc>
   </meiHead>
   <music>
      <body>
         <mdiv>
            <score>
               <scoreDef>
                  <staffGrp>
                     <staffDef n="1" lines="5">
                        <clef shape="G" line="2" />
                     </staffDef>
                  </staffGrp>
               </scoreDef>
               <section>
                  <measure>
                     <staff n="1">
                        <layer n="1">
                           <note dur="1" oct="4" pname="c">
                              <verse n="1">
                                 <syl>
                                    <rend fontstyle="italic">A</rend>
                                 </syl>
                              </verse>
                           </note>
                        </layer>
                     </staff>
                  </measure>
               </section>
            </score>
         </mdiv>
      </body>
   </music>
</mei>

Here is the function stack at the time of the crash:

0   verovio                                0x10517928c vrv::GenerateMIDIFunctor::VisitSyl(vrv::Syl const*) + 68
1   verovio                                0x1051793b8 non-virtual thunk to vrv::GenerateMIDIFunctor::VisitSyl(vrv::Syl const*) + 16
2   verovio                                0x10518c744 vrv::Object::Process(vrv::ConstFunctor&, int, bool) const + 76
3   verovio                                0x10518c83c vrv::Object::Process(vrv::ConstFunctor&, int, bool) const + 324
4   verovio                                0x10518c83c vrv::Object::Process(vrv::ConstFunctor&, int, bool) const + 324
5   verovio                                0x10518c83c vrv::Object::Process(vrv::ConstFunctor&, int, bool) const + 324
6   verovio                                0x10518c83c vrv::Object::Process(vrv::ConstFunctor&, int, bool) const + 324
7   verovio                                0x10518c83c vrv::Object::Process(vrv::ConstFunctor&, int, bool) const + 324
8   verovio                                0x10518c83c vrv::Object::Process(vrv::ConstFunctor&, int, bool) const + 324
9   verovio                                0x10518c83c vrv::Object::Process(vrv::ConstFunctor&, int, bool) const + 324
10  verovio                                0x10518c83c vrv::Object::Process(vrv::ConstFunctor&, int, bool) const + 324
11  verovio                                0x10518c83c vrv::Object::Process(vrv::ConstFunctor&, int, bool) const + 324
12  verovio                                0x104f91bf4 vrv::Doc::ExportMIDI(smf::MidiFile*) + 1908
13  verovio                                0x105224cd4 vrv::Toolkit::RenderToMIDIFile(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>> const&) + 84
14  verovio                                0x104f3af28 main + 5532
15  dyld                                   0x1884eff28 start + 2236

If the italics rend is removed, there is no segmentation fault:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="https://music-encoding.org/schema/5.0/mei-all.rng" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<mei xmlns="http://www.music-encoding.org/ns/mei" meiversion="5.0">
   <meiHead>
      <fileDesc>
         <titleStmt>
            <title />
         </titleStmt>
         <pubStmt />
      </fileDesc>
   </meiHead>
   <music>
      <body>
         <mdiv>
            <score>
               <scoreDef>
                  <staffGrp>
                     <staffDef n="1" lines="5">
                        <clef shape="G" line="2" />
                     </staffDef>
                  </staffGrp>
               </scoreDef>
               <section>
                  <measure>
                     <staff n="1">
                        <layer n="1">
                           <note dur="1" oct="4" pname="c">
                              <verse n="1">
                                 <syl>
                                    A
                                 </syl>
                              </verse>
                           </note>
                        </layer>
                     </staff>
                  </measure>
               </section>
            </score>
         </mdiv>
      </body>
   </music>
</mei>

GenerateMIDIFunctor::VisitSyl():

FunctorCode GenerateMIDIFunctor::VisitSyl(const Syl *syl)
{
    const int startTime = m_totalTime + m_lastNote->GetScoreTimeOnset();
    const Text *text = vrv_cast<const Text *>(syl->GetChild(0, TEXT));
    const std::string sylText = UTF32to8(text->GetText());

    m_midiFile->addLyric(m_midiTrack, startTime * m_midiFile->getTPQ(), sylText);

    return FUNCTOR_SIBLINGS;
}

syl->GetChild(0, TEXT) is probably causing the problem.

Something equivalent to element.textContent in Javascript should be implemented to extract the text content from the descendents of <syl> to remove <rend> markup of the text.

For now null values for syl->GetChild(0, TEXT) could be checked to prevent segmentation fault, and then do not add any lyric for the rend-wrapped lyric content.

craigsapp commented 1 year ago

That was fast!