From 584137b32b4deed2c20022628baaee6b38570fa5 Mon Sep 17 00:00:00 2001 From: Albert Young Date: Tue, 29 Sep 2015 23:02:43 -0500 Subject: [PATCH] Remove prohibited characters from FAT16/32 labels (#755608) GParted waits forever when attempting to set a FAT16/32 file system label which contains prohibited characters [1][2]. This is because mlabel asks a question and is waiting for input. Force cancelling the operation doesn't work either as GParted sends signal 2 (interrupt i.e. [Ctrl-C]) but mtools commands specifically ignores this and a number of other signals. Have to kill mlabel with signal 9 (kill) to regain control of GParted. Mlabel command with prohibited characters in the label: # export MTOOLS_SKIP_CHECK=1 # mlabel ::"MYLABEL/ " -i /dev/sdb10 Long file name "MYLABEL/ " contains illegal character(s). a)utorename A)utorename-all r)ename R)ename-all s)kip S)kip-all q)uit (aArRsSq): Remove prohibited characters from FAT16/32 file systems labels when creating and labelling them. Also upper case the label to meet label requirements [1][2]. This silently corrects the label and the actual label applied will be displayed when GParted refreshes after applying the operation. [1] Microsoft TechNet: Label https://technet.microsoft.com/en-us/library/bb490925.aspx [2] Replicated in Wikikedia: label (command) https://en.wikipedia.org/wiki/Label_%28command%29 Bug 755608 - Labeling fat16/fat32 partitions hangs if certain characters included in label --- include/fat16.h | 2 +- src/fat16.cc | 24 +++++++++++++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/include/fat16.h b/include/fat16.h index 4285cd36..2c5db2dd 100644 --- a/include/fat16.h +++ b/include/fat16.h @@ -43,7 +43,7 @@ public: private: static const Glib::ustring Change_UUID_Warning [] ; - const Glib::ustring pad_label( const Glib::ustring &label ) const ; + const Glib::ustring sanitize_label( const Glib::ustring & label ) const; }; } //GParted diff --git a/src/fat16.cc b/src/fat16.cc index e203422d..7f449c09 100644 --- a/src/fat16.cc +++ b/src/fat16.cc @@ -193,7 +193,8 @@ bool fat16::write_label( const Partition & partition, OperationDetail & operatio if ( partition.get_filesystem_label().empty() ) cmd = "mlabel -c :: -i " + partition.get_path(); else - cmd = "mlabel ::\"" + pad_label( partition.get_filesystem_label() ) + "\" -i " + partition.get_path(); + cmd = "mlabel ::\"" + sanitize_label( partition.get_filesystem_label() ) + "\" -i " + + partition.get_path(); return ! execute_command( cmd, operationdetail, EXEC_CHECK_STATUS ); } @@ -229,7 +230,7 @@ bool fat16::create( const Partition & new_partition, OperationDetail & operation { Glib::ustring fat_size = specific_type == FS_FAT16 ? "16" : "32" ; return ! execute_command( create_cmd + " -F" + fat_size + " -v -I -n \"" + - pad_label( new_partition.get_filesystem_label() ) + "\" " + + sanitize_label( new_partition.get_filesystem_label() ) + "\" " + new_partition.get_path(), operationdetail, EXEC_CHECK_STATUS|EXEC_CANCEL_SAFE ); @@ -246,11 +247,24 @@ bool fat16::check_repair( const Partition & partition, OperationDetail & operati //Private methods -//Pad fat label with spaces to prevent mlabel writing corrupted labels. See bug #700228 -const Glib::ustring fat16::pad_label( const Glib::ustring &label ) const +const Glib::ustring fat16::sanitize_label( const Glib::ustring &label ) const { - Glib::ustring new_label = label ; + Glib::ustring uppercase_label = label.uppercase(); + Glib::ustring new_label; + + // Copy uppercase label excluding prohibited characters. + // [1] Microsoft TechNet: Label + // https://technet.microsoft.com/en-us/library/bb490925.aspx + // [2] Replicated in Wikikedia: label (command) + // https://en.wikipedia.org/wiki/Label_%28command%29 + Glib::ustring prohibited_chars( "*?.,;:/\\|+=<>[]" ); + for ( unsigned int i = 0 ; i < label.size() ; i ++ ) + if ( prohibited_chars.find( uppercase_label[i] ) == Glib::ustring::npos ) + new_label.push_back( uppercase_label[i] ); + + // Pad with spaces to prevent mlabel writing corrupted labels. See bug #700228. new_label .resize( Utils::get_filesystem_label_maxlength( specific_type ), ' ' ) ; + return new_label ; }