Skip to content

Commit

Permalink
USDScene : Fix crash trying to write to an open stage
Browse files Browse the repository at this point in the history
In this case, `UsdStage::CreateNew()` returns a null result, which we were dereferencing, leading to a crash. We now just throw an exception describing the problem instead.
  • Loading branch information
johnhaddon committed Sep 3, 2024
1 parent 1be00fb commit 313cd25
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 8 deletions.
4 changes: 3 additions & 1 deletion Changes
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
10.5.x.x (relative to 10.5.9.2)
========

Fixes
-----


- USDScene : Fixed crash attempting to write to a file that is already open for reading. An exception is now thrown instead.

10.5.9.2 (relative to 10.5.9.1)
========
Expand Down
17 changes: 10 additions & 7 deletions contrib/IECoreUSD/src/IECoreUSD/USDScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,11 +761,11 @@ class USDScene::IO : public RefCounted

static pxr::UsdStageRefPtr makeStage( const std::string &fileName, IndexedIO::OpenMode openMode )
{
pxr::UsdStageRefPtr stage;
switch( openMode )
{
case IndexedIO::Read : {
static const std::string g_stageCachePrefix( "stageCache:" );
pxr::UsdStageRefPtr stage;
if( boost::starts_with( fileName, g_stageCachePrefix ) )
{
// Get Id from filename of form "stageCache:{id}.usd"
Expand All @@ -779,17 +779,20 @@ class USDScene::IO : public RefCounted
{
stage = pxr::UsdStage::Open( fileName );
}
if( !stage )
{
throw IECore::Exception( boost::str( boost::format( "USDScene : Failed to open USD stage : '%1%'" ) % fileName ) );
}
return stage;
break;
}
case IndexedIO::Write :
return pxr::UsdStage::CreateNew( fileName );
stage = pxr::UsdStage::CreateNew( fileName );
break;
default:
throw Exception( "Unsupported OpenMode" );
}

if( !stage )
{
throw IECore::Exception( boost::str( boost::format( "USDScene : Failed to open USD stage : '%1%'" ) % fileName ) );
}
return stage;
}

std::string m_fileName;
Expand Down
12 changes: 12 additions & 0 deletions contrib/IECoreUSD/test/IECoreUSD/USDSceneTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4313,5 +4313,17 @@ def testSetNameValidation( self ) :
with self.subTest( setName = setName ) :
self.assertEqual( root.readSet( setName ), IECore.PathMatcher( [ f"/set{setIndex}Member" ] ) )

def testWriteToOpenScene( self ) :

# Using posix-format filename, because Windows backslashes don't play nicely
# with `assertRaisesRegex()`.
fileName = ( pathlib.Path( self.temporaryDirectory() ) / "test.usda" ).as_posix()
IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Write )

reader = IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Read )

with self.assertRaisesRegex( RuntimeError, f"USDScene : Failed to open USD stage : '{fileName}'" ) :
IECoreScene.SceneInterface.create( fileName, IECore.IndexedIO.OpenMode.Write )

if __name__ == "__main__":
unittest.main()

0 comments on commit 313cd25

Please sign in to comment.