From f7ee415cdb4e6000636a55ff017c516d65ed64c1 Mon Sep 17 00:00:00 2001
From: Quincey Koziol <koziol@hdfgroup.org>
Date: Thu, 17 Mar 2005 21:56:01 -0500
Subject: [svn-r10231] Purpose:     Bug fix

Description:
    Opening an object in a group that is located in a file which has been
unmounted would cause a core dump. :-(

Solution:
    Re-arrangement internal code to compute internal "user" and "canonical"
names for the newly opened object in a safer way.

Platforms tested:
    FreeBSD 4.11 (sleipnir)
    Too minor to require h5committest
---
 src/H5Gstab.c  | 50 +++++++++++++++++++++++++++--------------------
 test/getname.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 90 insertions(+), 21 deletions(-)

diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index 383623d..36e2119 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -312,39 +312,37 @@ done:
 static herr_t 
 H5G_insert_name(H5G_entry_t *loc, H5G_entry_t *obj, const char *name)
 {
-    char *new_user_path;        /* Pointer to new user path */
-    char *new_canon_path;       /* Pointer to new canonical path */
     size_t  name_len;           /* Length of name to append */
-    size_t  user_path_len;      /* Length of location's user path name */
-    size_t  canon_path_len;     /* Length of location's canonical path name */
     herr_t  ret_value = SUCCEED;       
  
-    FUNC_ENTER_NOAPI(H5G_insert_name, FAIL);
+    FUNC_ENTER_NOAPI_NOINIT(H5G_insert_name);
 
     assert(loc);
     assert(obj);
     assert(name);
  
-    /* Only attempt to build a new name if the location's name exists */
-    if(loc->canon_path_r) {
-        const char *loc_user_path;      /* Pointer to raw string for user path */
-        const char *loc_canon_path;     /* Pointer to raw string for canonical path */
+    /* Reset the object's previous names, if they exist */
+    if(obj->user_path_r) {
+        H5RS_decr(obj->user_path_r);
+        obj->user_path_r=NULL;
+    } /* end if */
+    if(obj->canon_path_r) {
+        H5RS_decr(obj->canon_path_r);
+        obj->canon_path_r=NULL;
+    } /* end if */
+    obj->user_path_hidden=0;
 
-        /* Reset the object's previous names, if they exist */
-        if(obj->user_path_r) {
-            H5RS_decr(obj->user_path_r);
-            obj->user_path_r=NULL;
-        } /* end if */
-        if(obj->canon_path_r) {
-            H5RS_decr(obj->canon_path_r);
-            obj->canon_path_r=NULL;
-        } /* end if */
-        obj->user_path_hidden=0;
+    /* Get the length of the new name */
+    name_len = HDstrlen(name);
+
+    /* Modify the object's user path, if a user path exists in the location */
+    if(loc->user_path_r) {
+        const char *loc_user_path;      /* Pointer to raw string for user path */
+        size_t  user_path_len;      /* Length of location's user path name */
+        char *new_user_path;        /* Pointer to new user path */
 
         /* Get the length of the strings involved */
         user_path_len = H5RS_len(loc->user_path_r);
-        canon_path_len = H5RS_len(loc->canon_path_r);
-        name_len = HDstrlen(name);
 
         /* Modify the object's user path */
 
@@ -372,6 +370,16 @@ H5G_insert_name(H5G_entry_t *loc, H5G_entry_t *obj, const char *name)
         /* Give ownership of the user path to the entry */
         obj->user_path_r=H5RS_own(new_user_path);
         assert(obj->user_path_r);
+    } /* end if */
+
+    /* Modify the object's canonical path, if a canonical path exists in the location */
+    if(loc->canon_path_r) {
+        const char *loc_canon_path;     /* Pointer to raw string for canonical path */
+        size_t  canon_path_len;     /* Length of location's canonical path name */
+        char *new_canon_path;       /* Pointer to new canonical path */
+
+        /* Get the length of the strings involved */
+        canon_path_len = H5RS_len(loc->canon_path_r);
 
         /* Modify the object's canonical path */
 
diff --git a/test/getname.c b/test/getname.c
index 33b9141..4371018 100644
--- a/test/getname.c
+++ b/test/getname.c
@@ -2920,6 +2920,67 @@ PASSED();
  PASSED();
 
 /*-------------------------------------------------------------------------
+ * Test H5Iget_name with opening object in unmounted file
+ *-------------------------------------------------------------------------
+ */
+
+ TESTING("H5Iget_name with opening object in unmounted file");
+
+ /* Create file and group "/g39/g1/g2" in it */
+ file1_id = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
+
+ if ((group_id = H5Gcreate( file1_id, "/g41", 0 ))<0) goto out;
+ if ((group2_id = H5Gcreate( file1_id, "/g41/g1", 0 ))<0) goto out;
+ if ((group3_id = H5Gcreate( file1_id, "/g41/g1/g2", 0 ))<0) goto out;
+
+ /* Close */
+ H5Gclose( group_id );
+ H5Gclose( group2_id );
+ H5Gclose( group3_id );
+
+ /* Create second file and group "/g42/g1/g2" in it */
+ file2_id = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
+
+ if ((group_id = H5Gcreate( file2_id, "/g42", 0 ))<0) goto out;
+ if ((group2_id = H5Gcreate( file2_id, "/g42/g3", 0 ))<0) goto out;
+ if ((group3_id = H5Gcreate( file2_id, "/g42/g3/g4", 0 ))<0) goto out;
+
+ /* Close */
+ H5Gclose( group_id );
+ H5Gclose( group2_id );
+ H5Gclose( group3_id );
+
+ /* Mount second file under "/g41/g1" in the first file */
+ if (H5Fmount(file1_id, "/g41/g1", file2_id, H5P_DEFAULT)<0) goto out;
+
+ if ((group_id = H5Gopen( file1_id, "/g41/g1/g42/g3" ))<0) goto out;
+
+ /* Get name */
+ if (H5Iget_name( group_id, name, size )<0) goto out;
+
+ /* Verify */
+ if (check_name( name, "/g41/g1/g42/g3" )!=0) goto out;
+
+ /* Unmount file */
+ if (H5Funmount(file1_id, "/g41/g1")<0) goto out;
+
+ if ((group2_id = H5Gopen( group_id, "g4" ))<0) goto out;
+
+ /* Get name */
+ if (H5Iget_name( group2_id, name, size )<0) goto out;
+
+ /* Verify */
+ if (check_name( name, "" )!=0) goto out;
+
+ /* Close */
+ H5Gclose( group_id );
+ H5Gclose( group2_id );
+ H5Fclose( file1_id );
+ H5Fclose( file2_id );
+ 
+ PASSED();
+
+/*-------------------------------------------------------------------------
  * end tests 
  *-------------------------------------------------------------------------
  */
-- 
cgit v0.12