Python API
---------- Bugfix #6543: Blender.Library.Load() could segfault if called more than once with a library of different endian type. In the process discovered an invalid memory reference in other another function calling library_append(). Thanks to Brecht for the pointers on tracking this old bug down.
This commit is contained in:
@@ -238,7 +238,7 @@ char *BLO_gethome(void);
|
||||
int BLO_has_bfile_extension(char *str);
|
||||
void BLO_library_append(struct SpaceFile *sfile, char *dir, int idcode);
|
||||
void BLO_library_append_(BlendHandle **libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode);
|
||||
void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcode, short flag, struct Scene *scene);
|
||||
void BLO_script_library_append(BlendHandle **bh, char *dir, char *name, int idcode, short flag, struct Scene *scene);
|
||||
|
||||
BlendFileData* blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r);
|
||||
|
||||
|
||||
@@ -8578,38 +8578,38 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
|
||||
/* common routine to append/link something from a library */
|
||||
|
||||
static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
|
||||
int totsel, FileData *fd, struct direntry* filelist, int totfile, short flag)
|
||||
int totsel, FileData **fd, struct direntry* filelist, int totfile, short flag)
|
||||
{
|
||||
Main *mainl;
|
||||
Library *curlib;
|
||||
|
||||
/* make mains */
|
||||
blo_split_main(&fd->mainlist, G.main);
|
||||
blo_split_main(&(*fd)->mainlist, G.main);
|
||||
|
||||
/* which one do we need? */
|
||||
mainl = blo_find_main(fd, &fd->mainlist, dir, G.sce);
|
||||
mainl = blo_find_main(*fd, &(*fd)->mainlist, dir, G.sce);
|
||||
|
||||
mainl->versionfile= fd->fileversion; /* needed for do_version */
|
||||
mainl->versionfile= (*fd)->fileversion; /* needed for do_version */
|
||||
|
||||
curlib= mainl->curlib;
|
||||
|
||||
if(totsel==0) {
|
||||
append_named_part(fd, mainl, scene, file, idcode, flag);
|
||||
append_named_part(*fd, mainl, scene, file, idcode, flag);
|
||||
}
|
||||
else {
|
||||
int a;
|
||||
for(a=0; a<totfile; a++) {
|
||||
if(filelist[a].flags & ACTIVE) {
|
||||
append_named_part(fd, mainl, scene, filelist[a].relname, idcode, flag);
|
||||
append_named_part(*fd, mainl, scene, filelist[a].relname, idcode, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* make main consistant */
|
||||
expand_main(fd, mainl);
|
||||
expand_main(*fd, mainl);
|
||||
|
||||
/* do this when expand found other libs */
|
||||
read_libraries(fd, &fd->mainlist);
|
||||
read_libraries(*fd, &(*fd)->mainlist);
|
||||
|
||||
if(flag & FILE_STRINGCODE) {
|
||||
|
||||
@@ -8620,10 +8620,10 @@ static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
|
||||
BLI_makestringcode(G.sce, mainl->curlib->name);
|
||||
}
|
||||
|
||||
blo_join_main(&fd->mainlist);
|
||||
G.main= fd->mainlist.first;
|
||||
blo_join_main(&(*fd)->mainlist);
|
||||
G.main= (*fd)->mainlist.first;
|
||||
|
||||
lib_link_all(fd, G.main);
|
||||
lib_link_all(*fd, G.main);
|
||||
lib_verify_nodetree(G.main, 0);
|
||||
fix_relpaths_library(G.sce, G.main); /* make all relative paths, relative to the open blend file */
|
||||
|
||||
@@ -8642,8 +8642,9 @@ static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
|
||||
/* 20041208: put back. It only linked direct, not indirect objects (ton) */
|
||||
|
||||
/* patch to prevent switch_endian happens twice */
|
||||
if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
||||
blo_freefiledata( fd );
|
||||
if((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
||||
blo_freefiledata( *fd );
|
||||
*fd = NULL;
|
||||
}
|
||||
|
||||
return curlib;
|
||||
@@ -8654,11 +8655,11 @@ static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
|
||||
/* append to G.scene */
|
||||
/* this should probably be moved into the Python code anyway */
|
||||
|
||||
void BLO_script_library_append(BlendHandle *bh, char *dir, char *name,
|
||||
void BLO_script_library_append(BlendHandle **bh, char *dir, char *name,
|
||||
int idcode, short flag, Scene *scene )
|
||||
{
|
||||
/* try to append the requested object */
|
||||
library_append( scene, name, dir, idcode, 0, (FileData *)bh, NULL, 0, flag );
|
||||
library_append( scene, name, dir, idcode, 0, (FileData **)bh, NULL, 0, flag );
|
||||
|
||||
/* do we need to do this? */
|
||||
DAG_scene_sort(G.scene);
|
||||
@@ -8674,6 +8675,7 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
|
||||
void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode)
|
||||
{
|
||||
FileData *fd= (FileData*) (*libfiledata);
|
||||
int lastflags = fd->flags;
|
||||
Library *curlib;
|
||||
Base *centerbase;
|
||||
Object *ob;
|
||||
@@ -8706,12 +8708,7 @@ void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, i
|
||||
|
||||
if(flag & FILE_AUTOSELECT) scene_deselect_all(G.scene);
|
||||
|
||||
curlib = library_append( G.scene, file, dir, idcode, totsel, fd, filelist, totfile,flag );
|
||||
|
||||
/* patch to prevent switch_endian happens twice */
|
||||
if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
||||
(*libfiledata)= 0;
|
||||
}
|
||||
curlib = library_append( G.scene, file, dir, idcode, totsel, (FileData**) libfiledata, filelist, totfile,flag );
|
||||
|
||||
/* when not linking (appending)... */
|
||||
if((flag & FILE_LINK)==0) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* $Id: Library.c 10943 2007-06-16 12:24:41Z campbellbarton $
|
||||
* $Id$
|
||||
*
|
||||
* Blender.Library BPython module implementation.
|
||||
* This submodule has functions to append data from .blend files.
|
||||
@@ -175,7 +175,7 @@ static PyObject *M_Library_Open( PyObject * self, PyObject * value )
|
||||
BLI_strncpy(filename, G.sce, sizeof(filename));
|
||||
bpy_openlib = BLO_blendhandle_from_file( fname1 );
|
||||
BLI_strncpy(G.sce, filename, sizeof(filename));
|
||||
|
||||
|
||||
if( !bpy_openlib )
|
||||
return EXPP_ReturnPyObjError( PyExc_IOError, "file not found" );
|
||||
|
||||
@@ -344,6 +344,7 @@ static PyObject *oldM_Library_Load( PyObject * self, PyObject * args )
|
||||
int blocktype = 0;
|
||||
int linked = 0;
|
||||
|
||||
|
||||
if( !bpy_openlib ) {
|
||||
return EXPP_ReturnPyObjError( PyExc_IOError,
|
||||
"no library file: you need to open one, first." );
|
||||
@@ -359,12 +360,19 @@ static PyObject *oldM_Library_Load( PyObject * self, PyObject * args )
|
||||
if( !blocktype )
|
||||
return EXPP_ReturnPyObjError( PyExc_NameError,
|
||||
"no such Blender datablock type" );
|
||||
|
||||
|
||||
if (linked)
|
||||
BLO_script_library_append( bpy_openlib, bpy_openlibname, name, blocktype, FILE_LINK, G.scene);
|
||||
BLO_script_library_append( &bpy_openlib, bpy_openlibname, name, blocktype, FILE_LINK, G.scene);
|
||||
else
|
||||
BLO_script_library_append( bpy_openlib, bpy_openlibname, name, blocktype, 0, G.scene);
|
||||
|
||||
BLO_script_library_append( &bpy_openlib, bpy_openlibname, name, blocktype, 0, G.scene);
|
||||
|
||||
/*
|
||||
NOTE: BLO_script_library_append() can close the library if there is
|
||||
an endian issue. if this happened, reopen for the next call.
|
||||
*/
|
||||
if ( !bpy_openlib )
|
||||
bpy_openlib = BLO_blendhandle_from_file( bpy_openlibname );
|
||||
|
||||
if( update ) {
|
||||
M_Library_Update( self );
|
||||
Py_DECREF( Py_None ); /* incref'ed by above function */
|
||||
@@ -610,7 +618,7 @@ PyObject *LibraryData_importLibData( BPy_LibraryData *self, char *name,
|
||||
}
|
||||
|
||||
/* import from the libary */
|
||||
BLO_script_library_append( openlib, longFilename, name, self->type, mode,
|
||||
BLO_script_library_append( &openlib, longFilename, name, self->type, mode,
|
||||
scene );
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user