Skip to content

Commit 4c1438b

Browse files
committed
FrameRange : Prevent creation of FrameRanges with negative steps
Previously, you could create a FrameRange object with a negative step, but it would go into an infinite loop if you tried to get the frame list Given that we have the ReversedFrameList that achieves the same as a negative step, it felt like using that was the correct approach. Note that we still include the support for the negative step in the parse method, so that we can provide a more useful error message during init.
1 parent 225c6fa commit 4c1438b

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

Changes

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
10.4.x.x (relative to 10.4.10.0)
22
========
33

4+
Fixes
5+
-----
6+
7+
- FrameRange : Prevented creation of FrameRanges with negative steps
8+
49
10.4.10.0 (relative to 10.4.9.1)
510
========
611

src/IECore/FrameRange.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ FrameRange::FrameRange( Frame start, Frame end, Frame step ) : m_start( start ),
5858
{
5959
throw Exception( "FrameRange step cannot be zero" );
6060
}
61+
if ( step < 0 )
62+
{
63+
throw Exception( "FrameRange step cannot be negative. Consider using the reverse suffix instead." );
64+
}
6165
}
6266

6367
FrameRange::~FrameRange()
@@ -102,6 +106,10 @@ void FrameRange::setStep( Frame step )
102106
{
103107
throw Exception( "FrameRange step cannot be zero" );
104108
}
109+
if ( step < 0 )
110+
{
111+
throw Exception( "FrameRange step cannot be negative. Consider using the reverse suffix instead." );
112+
}
105113
m_step = step;
106114
}
107115

test/IECore/FrameList.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,24 @@ def testReverseConstruction( self ) :
5555
self.assertEqual( f.asList(), [ 5, 4, 3, 2, 1 ] )
5656
self.assertEqual( IECore.frameListFromList( [ 5, 4, 3, 2, 1 ] ), f )
5757

58+
def testFrameRange( self ) :
59+
60+
f = IECore.FrameList.parse( "1-5" )
61+
self.assertTrue( isinstance( f, IECore.FrameRange ) )
62+
self.assertEqual( f.asList(), [ 1, 2, 3, 4, 5 ] )
63+
# test step
64+
f = IECore.FrameList.parse( "10-20x5" )
65+
self.assertTrue( isinstance( f, IECore.FrameRange ) )
66+
self.assertEqual( f.asList(), [ 10, 15, 20 ] )
67+
# start must be smaller or equal to end
68+
self.assertRaises( Exception, IECore.FrameList.parse, "5-1" )
69+
# step must be positive
70+
self.assertRaises( Exception, IECore.FrameList.parse, "1-5x0" )
71+
self.assertRaises( Exception, IECore.FrameList.parse, "1-5x-1" )
72+
self.assertRaises( Exception, IECore.FrameList.parse, "5-1x-1" )
73+
74+
5875
## \todo: there should probably be a lot more tests in here...
5976

6077
if __name__ == "__main__":
61-
unittest.main()
78+
unittest.main()

0 commit comments

Comments
 (0)