[Libreoffice-commits] core.git: oox/source

Eilidh McAdam eilidh.mcadam at gmail.com
Mon Apr 15 12:03:09 PDT 2013


 oox/source/vml/vmlformatting.cxx |  107 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 96 insertions(+), 11 deletions(-)

New commits:
commit 942b184d81f129309072ca973fc274c40bac67b8
Author: Eilidh McAdam <eilidh.mcadam at gmail.com>
Date:   Wed Mar 27 13:40:32 2013 +0000

    fdo#36791 Added cases for unsupported VML commands
    
    Fixes crash on two-character VML path commands.
    
    Change-Id: Ia1abca37352b1feb20a41b4bac68ecb9e40ed8dc
    Reviewed-on: https://gerrit.libreoffice.org/3093
    Tested-by: Miklos Vajna <vmiklos at suse.cz>
    Reviewed-by: Eilidh McAdam <eilidh.mcadam at gmail.com>
    Reviewed-by: Miklos Vajna <vmiklos at suse.cz>

diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx
index 05940f9..b3cac88 100644
--- a/oox/source/vml/vmlformatting.cxx
+++ b/oox/source/vml/vmlformatting.cxx
@@ -273,8 +273,9 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r
     sal_Int32 nTokenStart = 0;
     sal_Int32 nTokenLen = 0;
     sal_Int32 nParamCount = 0;
+    bool bCommand = false;
     enum VML_State { START, MOVE_REL, MOVE_ABS, BEZIER_REL, BEZIER_ABS,
-                     LINE_REL, LINE_ABS, CLOSE, END };
+                     LINE_REL, LINE_ABS, CLOSE, END, UNSUPPORTED };
     VML_State state = START;
 
     rPointLists.push_back( ::std::vector< Point>() );
@@ -288,7 +289,7 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r
         else if ( rPath[ i ] != ' ' )
         {
             // Store coordinate from current token
-            if ( state != START )
+            if ( state != START && state != UNSUPPORTED )
             {
                 if ( nTokenLen > 0 )
                     aCoordList.push_back( rPath.copy( nTokenStart, nTokenLen ).toInt32() );
@@ -374,25 +375,109 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r
                     break;
 
                 case START:
+                case UNSUPPORTED:
                     break;
                 }
 
                 aCoordList.clear();
             }
 
-            // Move on to current command state
+            // Allow two-char commands to peek ahead to the next character
+            char nextChar = '\0';
+            if (i+1 < rPath.getLength())
+                nextChar = rPath[i+1];
+
+            // Move to relevant state upon finding a command
+            bCommand = true;
             switch ( rPath[ i ] )
             {
-            case 't': state = MOVE_REL; nTokenLen = 0; nParamCount = 2 * 2; break;
-            case 'm': state = MOVE_ABS; nTokenLen = 0; nParamCount = 2 * 2; break;
-            case 'v': state = BEZIER_REL; nTokenLen = 0; nParamCount = 2 * 6; break;
-            case 'c': state = BEZIER_ABS; nTokenLen = 0; nParamCount = 2 * 6; break;
-            case 'r': state = LINE_REL; nTokenLen = 0; nParamCount = 2 * 2; break;
-            case 'l': state = LINE_ABS; nTokenLen = 0; nParamCount = 2 * 2; break;
-            case 'x': state = CLOSE; nTokenLen = 0; break;
-            case 'e': state = END; break;
+            // Single-character commands
+            case 't': // rmoveto
+                state = MOVE_REL; nParamCount = 2 * 2; break;
+            case 'm': // moveto
+                state = MOVE_ABS; nParamCount = 2 * 2; break;
+            case 'v': // rcurveto
+                state = BEZIER_REL; nParamCount = 2 * 6; break;
+            case 'c': // curveto
+                state = BEZIER_ABS; nParamCount = 2 * 6; break;
+            case 'r': // rlineto
+                state = LINE_REL; nParamCount = 2 * 2; break;
+            case 'l': // lineto
+                state = LINE_ABS; nParamCount = 2 * 2; break;
+            case 'x': // close
+                state = CLOSE; break;
+            case 'e': // end
+                state = END; break;
+
+            // Two-character commands
+            case 'n':
+            {
+                switch ( nextChar )
+                {
+                case 'f': // nf - nofill
+                case 's': // ns - nostroke
+                    state = UNSUPPORTED; i++; break;
+                }
+                break;
+            }
+            case 'a': // Elliptical curves
+            {
+                switch ( nextChar )
+                {
+                case 'e': // ae - angleellipseto
+                case 'l': // al - angleellipse
+                    state = UNSUPPORTED; i++; break;
+                case 't': // at - arcto
+                case 'r': // ar - arc
+                    state = UNSUPPORTED; i++; break;
+                }
+                break;
+            }
+            case 'w': // Clockwise elliptical arcs
+            {
+                switch ( nextChar )
+                {
+                case 'a': // wa - clockwisearcto
+                case 'r': // wr - clockwisearc
+                    state = UNSUPPORTED; i++; break;
+                }
+                break;
+            }
+            case 'q':
+            {
+                switch ( nextChar )
+                {
+                case 'x': // qx - ellipticalquadrantx
+                case 'y': // qy - ellipticalquadranty
+                    state = UNSUPPORTED; i++; break;
+                case 'b': // qb - quadraticbezier
+                    state = UNSUPPORTED; i++; break;
+                }
+                break;
+            }
+            case 'h': // behaviour extensions
+            {
+                switch ( nextChar )
+                {
+                case 'a': // ha - AutoLine
+                case 'b': // hb - AutoCurve
+                case 'c': // hc - CornerLine
+                case 'd': // hd - CornerCurve
+                case 'e': // he - SmoothLine
+                case 'f': // hf - SmoothCurve
+                case 'g': // hg - SymmetricLine
+                case 'h': // hh - SymmetricCurve
+                case 'i': // hi - Freeform
+                    state = UNSUPPORTED; i++; break;
+                }
+                break;
+            }
+            default:
+                bCommand = false;
+                break;
             }
 
+            if (bCommand) nTokenLen = 0;
             nTokenStart = i+1;
         }
     }


More information about the Libreoffice-commits mailing list