@@ -120,8 +120,9 @@ mlt_property mlt_property_init()
120120
121121static void clear_property (mlt_property self )
122122{
123- // Special case data handling
124- if (self -> types & mlt_prop_data && self -> destructor != NULL )
123+ // Special case data handling (destructor may be set even without mlt_prop_data,
124+ // e.g. for the unquoted-string cache used by mlt_property_anim_get_string).
125+ if (self -> destructor != NULL )
125126 self -> destructor (self -> data );
126127
127128 // Special case string handling
@@ -1565,7 +1566,30 @@ char *mlt_property_anim_get_string(
15651566 pthread_mutex_unlock (& self -> mutex );
15661567 } else {
15671568 pthread_mutex_unlock (& self -> mutex );
1568- result = mlt_property_get_string_l (self , locale );
1569+ const char * raw = mlt_property_get_string_l (self , locale );
1570+ if (raw && raw [0 ] == '"' ) {
1571+ size_t len = strlen (raw );
1572+ if (len >= 2 && raw [len - 1 ] == '"' ) {
1573+ // The string is wrapped in double-quotes to prevent it from
1574+ // being interpreted as animation keyframes. Strip the quotes
1575+ // and cache the result in the data field so prop_string (with
1576+ // its quotes) is never modified and is_anim() stays correct.
1577+ char * unquoted = malloc (len - 1 );
1578+ memcpy (unquoted , raw + 1 , len - 2 );
1579+ unquoted [len - 2 ] = '\0' ;
1580+ pthread_mutex_lock (& self -> mutex );
1581+ if (self -> destructor )
1582+ self -> destructor (self -> data );
1583+ self -> data = unquoted ;
1584+ self -> destructor = free ;
1585+ result = (char * ) self -> data ;
1586+ pthread_mutex_unlock (& self -> mutex );
1587+ } else {
1588+ result = (char * ) raw ;
1589+ }
1590+ } else {
1591+ result = (char * ) raw ;
1592+ }
15691593 }
15701594 return result ;
15711595}
0 commit comments