* include/grub/charset.h (GRUB_MAX_UTF8_PER_UTF16): New const.
* grub-core/fs/hfsplus.c (grub_hfsplus_catkey_internal): Change to UTF-16-BE. All users updated. (grub_hfsplus_cmp_catkey): Fix unicode handling. (grub_hfsplus_iterate_dir): Likewise. (grub_hfsplus_label): Likewise.
This commit is contained in:
		
							parent
							
								
									48d6e45653
								
							
						
					
					
						commit
						1bc8f60db7
					
				
					 3 changed files with 43 additions and 61 deletions
				
			
		|  | @ -181,7 +181,8 @@ enum grub_hfsplus_filetype | |||
| struct grub_hfsplus_catkey_internal | ||||
| { | ||||
|   grub_uint32_t parent; | ||||
|   const char *name; | ||||
|   const grub_uint16_t *name; | ||||
|   grub_size_t namelen; | ||||
| }; | ||||
| 
 | ||||
| /* Internal representation of an extent overflow key.  */ | ||||
|  | @ -519,8 +520,6 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya, | |||
| { | ||||
|   struct grub_hfsplus_catkey *catkey_a = &keya->catkey; | ||||
|   struct grub_hfsplus_catkey_internal *catkey_b = &keyb->catkey; | ||||
|   char *filename; | ||||
|   int i; | ||||
|   int diff; | ||||
| 
 | ||||
|   /* Safe unsigned comparison */ | ||||
|  | @ -530,26 +529,13 @@ grub_hfsplus_cmp_catkey (struct grub_hfsplus_key *keya, | |||
|   if (aparent < catkey_b->parent) | ||||
|     return -1; | ||||
| 
 | ||||
|   /* Change the filename in keya so the endianness is correct.  */ | ||||
|   for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++) | ||||
|     catkey_a->name[i] = grub_be_to_cpu16 (catkey_a->name[i]); | ||||
|   diff = grub_memcmp (catkey_a->name, catkey_b->name, | ||||
| 		      grub_min (grub_be_to_cpu16 (catkey_a->namelen), | ||||
| 				catkey_b->namelen) | ||||
| 		      * sizeof (catkey_a->name[0])); | ||||
|   if (diff == 0) | ||||
|     diff = grub_be_to_cpu16 (catkey_a->namelen) - catkey_b->namelen; | ||||
| 
 | ||||
|   filename = grub_malloc (grub_be_to_cpu16 (catkey_a->namelen) + 1); | ||||
| 
 | ||||
|   if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey_a->name, | ||||
| 			    grub_be_to_cpu16 (catkey_a->namelen))) | ||||
|     return -1; /* XXX: This error never occurs, but in case it happens
 | ||||
| 		  just skip this entry.  */ | ||||
| 
 | ||||
|   diff = grub_strncmp (filename, catkey_b->name, | ||||
| 		       grub_be_to_cpu16 (catkey_a->namelen)); | ||||
| 
 | ||||
|   grub_free (filename); | ||||
| 
 | ||||
|   /* The endianness was changed to host format, change it back to
 | ||||
|      whatever it was.  */ | ||||
|   for (i = 0; i < grub_be_to_cpu16 (catkey_a->namelen); i++) | ||||
|     catkey_a->name[i] = grub_cpu_to_be16 (catkey_a->name[i]); | ||||
|   return diff; | ||||
| } | ||||
| 
 | ||||
|  | @ -792,6 +778,11 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, | |||
|       if (type == GRUB_FSHELP_UNKNOWN) | ||||
| 	return 0; | ||||
| 
 | ||||
|       filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) | ||||
| 			      * GRUB_MAX_UTF8_PER_UTF16 + 1); | ||||
|       if (! filename) | ||||
| 	return 0; | ||||
| 
 | ||||
|       /* Make sure the byte order of the UTF16 string is correct.  */ | ||||
|       for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) | ||||
| 	{ | ||||
|  | @ -802,18 +793,8 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, | |||
| 	    return 0; | ||||
| 	} | ||||
| 
 | ||||
|       filename = grub_malloc (grub_be_to_cpu16 (catkey->namelen) + 1); | ||||
|       if (! filename) | ||||
| 	return 0; | ||||
| 
 | ||||
|       if (! grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name, | ||||
| 				grub_be_to_cpu16 (catkey->namelen))) | ||||
| 	{ | ||||
| 	  grub_free (filename); | ||||
| 	  return 0; | ||||
| 	} | ||||
| 
 | ||||
|       filename[grub_be_to_cpu16 (catkey->namelen)] = '\0'; | ||||
|       *grub_utf16_to_utf8 ((grub_uint8_t *) filename, catkey->name, | ||||
| 			   grub_be_to_cpu16 (catkey->namelen)) = '\0'; | ||||
| 
 | ||||
|       /* Restore the byte order to what it was previously.  */ | ||||
|       for (i = 0; i < grub_be_to_cpu16 (catkey->namelen); i++) | ||||
|  | @ -823,22 +804,18 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, | |||
|       if (! dir->data->case_sensitive) | ||||
| 	type |= GRUB_FSHELP_CASE_INSENSITIVE; | ||||
| 
 | ||||
|       /* Only accept valid nodes.  */ | ||||
|       if (grub_strlen (filename) == grub_be_to_cpu16 (catkey->namelen)) | ||||
| 	{ | ||||
| 	  /* A valid node is found; setup the node and call the
 | ||||
| 	     callback function.  */ | ||||
| 	  node = grub_malloc (sizeof (*node)); | ||||
| 	  node->data = dir->data; | ||||
|       /* A valid node is found; setup the node and call the
 | ||||
| 	 callback function.  */ | ||||
|       node = grub_malloc (sizeof (*node)); | ||||
|       node->data = dir->data; | ||||
| 
 | ||||
| 	  grub_memcpy (node->extents, fileinfo->data.extents, | ||||
| 		       sizeof (node->extents)); | ||||
| 	  node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800; | ||||
| 	  node->size = grub_be_to_cpu64 (fileinfo->data.size); | ||||
| 	  node->fileid = grub_be_to_cpu32 (fileinfo->fileid); | ||||
|       grub_memcpy (node->extents, fileinfo->data.extents, | ||||
| 		   sizeof (node->extents)); | ||||
|       node->mtime = grub_be_to_cpu32 (fileinfo->mtime) - 2082844800; | ||||
|       node->size = grub_be_to_cpu64 (fileinfo->data.size); | ||||
|       node->fileid = grub_be_to_cpu32 (fileinfo->fileid); | ||||
| 
 | ||||
| 	  ret = hook (filename, type, node); | ||||
| 	} | ||||
|       ret = hook (filename, type, node); | ||||
| 
 | ||||
|       grub_free (filename); | ||||
| 
 | ||||
|  | @ -851,7 +828,8 @@ grub_hfsplus_iterate_dir (grub_fshelp_node_t dir, | |||
| 
 | ||||
|   /* Create a key that points to the first entry in the directory.  */ | ||||
|   intern.catkey.parent = dir->fileid; | ||||
|   intern.catkey.name = ""; | ||||
|   intern.catkey.name = 0; | ||||
|   intern.catkey.namelen = 0; | ||||
| 
 | ||||
|   /* First lookup the first entry.  */ | ||||
|   if (grub_hfsplus_btree_search (&dir->data->catalog_tree, &intern, | ||||
|  | @ -999,7 +977,8 @@ grub_hfsplus_label (grub_device_t device, char **label) | |||
| 
 | ||||
|   /* Create a key that points to the label.  */ | ||||
|   intern.catkey.parent = 1; | ||||
|   intern.catkey.name = ""; | ||||
|   intern.catkey.name = 0; | ||||
|   intern.catkey.namelen = 0; | ||||
| 
 | ||||
|   /* First lookup the first entry.  */ | ||||
|   if (grub_hfsplus_btree_search (&data->catalog_tree, &intern, | ||||
|  | @ -1022,20 +1001,12 @@ grub_hfsplus_label (grub_device_t device, char **label) | |||
| 	return 0; | ||||
|     } | ||||
| 
 | ||||
|   *label = grub_malloc (label_len + 1); | ||||
|   *label = grub_malloc (label_len * GRUB_MAX_UTF8_PER_UTF16 + 1); | ||||
|   if (! *label) | ||||
|     return grub_errno; | ||||
| 
 | ||||
|   if (! grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name, | ||||
| 			    label_len)) | ||||
|     { | ||||
|       grub_free (node); | ||||
|       grub_free (*label); | ||||
|       grub_free (data); | ||||
|       *label = 0; | ||||
|       return grub_errno; | ||||
|     } | ||||
|   (*label)[label_len] = '\0'; | ||||
|   *grub_utf16_to_utf8 ((grub_uint8_t *) (*label), catkey->name, | ||||
| 		       label_len) = '\0'; | ||||
| 
 | ||||
|   grub_free (node); | ||||
|   grub_free (data); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue