Kaydet (Commit) 942b184d authored tarafından Eilidh McAdam's avatar Eilidh McAdam Kaydeden (comit) Miklos Vajna

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/3093Tested-by: 's avatarMiklos Vajna <vmiklos@suse.cz>
Reviewed-by: 's avatarEilidh McAdam <eilidh.mcadam@gmail.com>
Reviewed-by: 's avatarMiklos Vajna <vmiklos@suse.cz>
üst 77f36fe3
...@@ -273,8 +273,9 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r ...@@ -273,8 +273,9 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r
sal_Int32 nTokenStart = 0; sal_Int32 nTokenStart = 0;
sal_Int32 nTokenLen = 0; sal_Int32 nTokenLen = 0;
sal_Int32 nParamCount = 0; sal_Int32 nParamCount = 0;
bool bCommand = false;
enum VML_State { START, MOVE_REL, MOVE_ABS, BEZIER_REL, BEZIER_ABS, 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; VML_State state = START;
rPointLists.push_back( ::std::vector< Point>() ); rPointLists.push_back( ::std::vector< Point>() );
...@@ -288,7 +289,7 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r ...@@ -288,7 +289,7 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r
else if ( rPath[ i ] != ' ' ) else if ( rPath[ i ] != ' ' )
{ {
// Store coordinate from current token // Store coordinate from current token
if ( state != START ) if ( state != START && state != UNSUPPORTED )
{ {
if ( nTokenLen > 0 ) if ( nTokenLen > 0 )
aCoordList.push_back( rPath.copy( nTokenStart, nTokenLen ).toInt32() ); aCoordList.push_back( rPath.copy( nTokenStart, nTokenLen ).toInt32() );
...@@ -374,25 +375,109 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r ...@@ -374,25 +375,109 @@ bool lclExtractDouble( double& orfValue, sal_Int32& ornEndPos, const OUString& r
break; break;
case START: case START:
case UNSUPPORTED:
break; break;
} }
aCoordList.clear(); 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 ] ) switch ( rPath[ i ] )
{ {
case 't': state = MOVE_REL; nTokenLen = 0; nParamCount = 2 * 2; break; // Single-character commands
case 'm': state = MOVE_ABS; nTokenLen = 0; nParamCount = 2 * 2; break; case 't': // rmoveto
case 'v': state = BEZIER_REL; nTokenLen = 0; nParamCount = 2 * 6; break; state = MOVE_REL; nParamCount = 2 * 2; break;
case 'c': state = BEZIER_ABS; nTokenLen = 0; nParamCount = 2 * 6; break; case 'm': // moveto
case 'r': state = LINE_REL; nTokenLen = 0; nParamCount = 2 * 2; break; state = MOVE_ABS; nParamCount = 2 * 2; break;
case 'l': state = LINE_ABS; nTokenLen = 0; nParamCount = 2 * 2; break; case 'v': // rcurveto
case 'x': state = CLOSE; nTokenLen = 0; break; state = BEZIER_REL; nParamCount = 2 * 6; break;
case 'e': state = END; 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; nTokenStart = i+1;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment