@@ -1662,37 +1662,45 @@ MagickExport VirtualPixelMethod GetImageVirtualPixelMethod(const Image *image)
1662
1662
%
1663
1663
*/
1664
1664
MagickExport size_t InterpretImageFilename (const ImageInfo * image_info ,
1665
- Image * image ,const char * format ,int value ,char * filename )
1665
+ Image * image ,const char * format ,int value ,char * filename ,
1666
+ ExceptionInfo * exception )
1666
1667
{
1667
1668
char
1668
- * q ;
1669
+ * p = filename ,
1670
+ pattern [MagickPathExtent ];
1669
1671
1670
1672
const char
1671
- * p ;
1672
-
1673
- int
1674
- c ;
1675
-
1676
- MagickBooleanType
1677
- canonical ;
1673
+ * cursor = format ;
1678
1674
1679
- ssize_t
1680
- offset ;
1681
-
1682
- canonical = MagickFalse ;
1683
- offset = 0 ;
1684
- (void ) CopyMagickString (filename ,format ,MaxTextExtent );
1675
+ /*
1676
+ Start with a copy of the format string.
1677
+ */
1678
+ (void ) CopyMagickString (filename ,format ,MagickPathExtent );
1685
1679
if (IsStringTrue (GetImageOption (image_info ,"filename:literal" )) != MagickFalse )
1686
1680
return (strlen (filename ));
1687
- for ( p = strchr (format ,'%' ); p != (char * ) NULL ; p = strchr ( p + 1 , '%' ) )
1681
+ while (( cursor = strchr (cursor ,'%' )) != (const char * ) NULL )
1688
1682
{
1689
- q = (char * ) p + 1 ;
1690
- if (* q == '%' )
1683
+ const char
1684
+ * q = cursor ;
1685
+
1686
+ ssize_t
1687
+ offset = (ssize_t ) (cursor - format );
1688
+
1689
+ cursor ++ ; /* move past '%' */
1690
+ if (* cursor == '%' )
1691
1691
{
1692
- p ++ ;
1692
+ /*
1693
+ Escaped %%.
1694
+ */
1695
+ cursor ++ ;
1693
1696
continue ;
1694
1697
}
1695
- switch (* q )
1698
+ /*
1699
+ Skip padding digits like %03d.
1700
+ */
1701
+ if (* cursor == '0' )
1702
+ (void ) strtol (cursor ,(char * * ) & cursor ,10 );
1703
+ switch (* cursor )
1696
1704
{
1697
1705
case 'd' :
1698
1706
case 'o' :
@@ -1701,94 +1709,62 @@ MagickExport size_t InterpretImageFilename(const ImageInfo *image_info,
1701
1709
ssize_t
1702
1710
count ;
1703
1711
1704
- q ++ ;
1705
- c = (* q );
1706
- * q = '\0' ;
1707
- count = FormatLocaleString (filename + (p - format - offset ),(size_t )
1708
- (MaxTextExtent - (p - format - offset )),p ,value );
1709
- if ((count <= 0 ) || (count > (MagickPathExtent - (p - format - offset ))))
1712
+ count = FormatLocaleString (pattern ,sizeof (pattern ),q ,value );
1713
+ if ((count <= 0 ) || (count >= MagickPathExtent ))
1710
1714
return (0 );
1711
- offset += (ssize_t ) ((q - p )- count );
1712
- * q = c ;
1713
- (void ) ConcatenateMagickString (filename ,q ,MaxTextExtent );
1714
- canonical = MagickTrue ;
1715
- if (* (q - 1 ) != '%' )
1716
- break ;
1717
- p ++ ;
1715
+ if ((offset + count ) >= MagickPathExtent )
1716
+ return (0 );
1717
+ (void ) CopyMagickString (p + offset ,pattern ,(size_t ) (MagickPathExtent -
1718
+ offset ));
1719
+ cursor ++ ;
1718
1720
break ;
1719
1721
}
1720
1722
case '[' :
1721
1723
{
1722
- char
1723
- pattern [MaxTextExtent ];
1724
-
1725
1724
const char
1726
- * value ;
1725
+ * end = strchr (cursor ,']' ),
1726
+ * option = (const char * ) NULL ;
1727
1727
1728
- char
1729
- * r ;
1730
-
1731
- ssize_t
1732
- i ;
1733
-
1734
- ssize_t
1735
- depth ;
1728
+ size_t
1729
+ extent = (size_t ) (end - cursor );
1736
1730
1737
1731
/*
1738
- Image option.
1732
+ Handle %[key:value];
1739
1733
*/
1740
- if (strchr ( p , ']' ) == (char * ) NULL )
1734
+ if (end == (const char * ) NULL )
1741
1735
break ;
1742
- depth = 1 ;
1743
- r = q + 1 ;
1744
- for (i = 0 ; (i < (MaxTextExtent - 1L )) && (* r != '\0' ); i ++ )
1745
- {
1746
- if (* r == '[' )
1747
- depth ++ ;
1748
- if (* r == ']' )
1749
- depth -- ;
1750
- if (depth <= 0 )
1751
- break ;
1752
- pattern [i ]= (* r ++ );
1753
- }
1754
- pattern [i ]= '\0' ;
1755
- if (LocaleNCompare (pattern ,"filename:" ,9 ) != 0 )
1736
+ if (extent >= sizeof (pattern ))
1756
1737
break ;
1757
- value = (const char * ) NULL ;
1738
+ (void ) CopyMagickString (pattern ,cursor ,extent );
1739
+ pattern [extent ]= '\0' ;
1758
1740
if (image != (Image * ) NULL )
1759
- value = GetImageProperty (image ,pattern );
1760
- if ((value == (const char * ) NULL ) &&
1761
- (image != (Image * ) NULL ))
1762
- value = GetImageArtifact (image ,pattern );
1763
- if ((value == (const char * ) NULL ) &&
1741
+ option = GetImageProperty (image ,pattern ,exception );
1742
+ if ((option == (const char * ) NULL ) && (image != (Image * )NULL ))
1743
+ option = GetImageArtifact (image ,pattern );
1744
+ if ((option == (const char * ) NULL ) &&
1764
1745
(image_info != (ImageInfo * ) NULL ))
1765
- value = GetImageOption (image_info ,pattern );
1766
- if (value == (const char * ) NULL )
1767
- break ;
1768
- q -- ;
1769
- c = (* q );
1770
- * q = '\0' ;
1771
- (void ) CopyMagickString (filename + (p - format - offset ),value ,(size_t )
1772
- (MaxTextExtent - (p - format - offset )));
1773
- offset += (ssize_t ) strlen (pattern )- (ssize_t ) strlen (value )+ 3 ;
1774
- * q = c ;
1775
- (void ) ConcatenateMagickString (filename ,r + 1 ,MaxTextExtent );
1776
- canonical = MagickTrue ;
1777
- if (* (q - 1 ) != '%' )
1746
+ option = GetImageOption (image_info ,pattern );
1747
+ if (option == (const char * ) NULL )
1778
1748
break ;
1779
- p ++ ;
1749
+ (void ) CopyMagickString (p + offset ,option ,(size_t ) (MagickPathExtent -
1750
+ offset ));
1751
+ cursor = end + 1 ;
1780
1752
break ;
1781
1753
}
1782
1754
default :
1783
1755
break ;
1784
1756
}
1785
1757
}
1786
- if (canonical == MagickFalse )
1787
- (void ) CopyMagickString (filename ,format ,MaxTextExtent );
1788
- else
1789
- for (q = filename ; * q != '\0' ; q ++ )
1790
- if ((* q == '%' ) && (* (q + 1 ) == '%' ))
1791
- (void ) CopyMagickString (q ,q + 1 ,(size_t ) (MaxTextExtent - (q - filename )));
1758
+ for (p = filename ; * p != '\0' ; )
1759
+ {
1760
+ /*
1761
+ Replace "%%" with "%".
1762
+ */
1763
+ if ((* p == '%' ) && (* (p + 1 ) == '%' ))
1764
+ (void ) memmove (p ,p + 1 ,strlen (p )); /* shift left */
1765
+ else
1766
+ p ++ ;
1767
+ }
1792
1768
return (strlen (filename ));
1793
1769
}
1794
1770
0 commit comments