Problem with ^A in Filename

Message ID 44423880.7030404@cadsoft.de
State New
Headers

Commit Message

Klaus Schmidinger April 16, 2006, 12:28 p.m. UTC
  Udo Richter wrote:
> Klaus Schmidinger wrote:
> 
>> Patrick Fischer wrote:
>>
>>> @Ripley's unglaubliche Welt
>>> will be saved as (only shown if I pipe "ll . > out.txt" and look at 
>>> the file or by using xterm)
>>> @Ripley^As_unglaubliche_Welt
>>
>>
>> The single quote character is mapped to 0x01 so that in shell script
>> it is guaranteed that no recording name contains such a character, and
>> you can always be sure that enclosing a recording name in single quotes
>> will work.
> 
> 
> This is only true in classic mode. In VFAT-mode, unsafe characters like 
> this are mapped to literal ascii codes, in this case '#27'.
> 
> Using ASCII control chars (0x01 alias SOH for ', 0x02 alias STX for /) 
> in file names doesn't sound like a good idea to me anyway. Wouldn't it 
> be better to use '#27' and '#2F' (and consequently '#23' for #) in 
> non-VFAT mode too?
> 
> Cheers,
> 
> Udo

I've now made it so that in "normal" mode (non-VFAT) the single quote
is not mapped any more (IIRC I thought that this might be necessary
for external commands, but with strescape() and "..." this works just
fine). The '/' and '~' are swapped between internal and external
representation, so that no more "control" characters are used.

For backwards compatibility 0x01, 0x02 and 0x03 are still recognized.

Please give the attached patch a try.

Klaus
  

Patch

--- recording.c	2006/04/09 13:49:51	1.144
+++ recording.c	2006/04/16 12:03:31
@@ -386,92 +386,75 @@ 
 
 #define RESUME_NOT_INITIALIZED (-2)
 
-struct tCharExchange { char a; char b; };
-tCharExchange CharExchange[] = {
-  { '~',  '/'    },
-  { ' ',  '_'    },
-  { '\'', '\x01' },
-  { '/',  '\x02' },
-  { 0, 0 }
-  };
-
 char *ExchangeChars(char *s, bool ToFileSystem)
 {
   char *p = s;
   while (*p) {
-        if (VfatFileSystem) {
-           // The VFAT file system can't handle all characters, so we
-           // have to take extra efforts to encode/decode them:
-           if (ToFileSystem) {
-              switch (*p) {
-                     // characters that can be used "as is":
-                     case '!':
-                     case '@':
-                     case '$':
-                     case '%':
-                     case '&':
-                     case '(':
-                     case ')':
-                     case '+':
-                     case ',':
-                     case '-':
-                     case ';':
-                     case '=':
-                     case '0' ... '9':
-                     case 'a' ... 'z':
-                     case 'A' ... 'Z':
-                     case 'ä': case 'Ä':
-                     case 'ö': case 'Ö':
-                     case 'ü': case 'Ü':
-                     case 'ß':
-                          break;
-                     // characters that can be mapped to other characters:
-                     case ' ': *p = '_'; break;
-                     case '~': *p = '/'; break;
-                     // characters that have to be encoded:
-                     default:
-                       if (*p != '.' || !*(p + 1) || *(p + 1) == '~') { // Windows can't handle '.' at the end of directory names
-                          int l = p - s;
-                          s = (char *)realloc(s, strlen(s) + 10);
-                          p = s + l;
-                          char buf[4];
-                          sprintf(buf, "#%02X", (unsigned char)*p);
-                          memmove(p + 2, p, strlen(p) + 1);
-                          strncpy(p, buf, 3);
-                          p += 2;
-                          }
-                     }
-              }
-           else {
-              switch (*p) {
-                // mapped characters:
-                case '_': *p = ' '; break;
-                case '/': *p = '~'; break;
-                // encodes characters:
-                case '#': {
-                     if (strlen(p) > 2) {
-                        char buf[3];
-                        sprintf(buf, "%c%c", *(p + 1), *(p + 2));
-                        unsigned char c = strtol(buf, NULL, 16);
-                        *p = c;
-                        memmove(p + 1, p + 3, strlen(p) - 2);
-                        }
-                     }
-                     break;
-                // backwards compatibility:
-                case '\x01': *p = '\''; break;
-                case '\x02': *p = '/';  break;
-                case '\x03': *p = ':';  break;
-                }
-              }
+        if (ToFileSystem) {
+           switch (*p) {
+             // characters that can be used "as is":
+             case '!':
+             case '@':
+             case '$':
+             case '%':
+             case '&':
+             case '(':
+             case ')':
+             case '+':
+             case ',':
+             case '-':
+             case ';':
+             case '=':
+             case '0' ... '9':
+             case 'a' ... 'z':
+             case 'A' ... 'Z':
+             case 'ä': case 'Ä':
+             case 'ö': case 'Ö':
+             case 'ü': case 'Ü':
+             case 'ß':
+                  break;
+             // characters that can be mapped to other characters:
+             case ' ': *p = '_'; break;
+             case '~': *p = '/'; break;
+             case '/': *p = '~'; break;
+             // characters that have to be encoded:
+             default:
+               // The VFAT file system can't handle all characters, so we
+               // have to take extra efforts to encode them.
+               if (VfatFileSystem && (*p != '.' || !*(p + 1) || *(p + 1) == '~')) { // Windows can't handle '.' at the end of directory names
+                  int l = p - s;
+                  s = (char *)realloc(s, strlen(s) + 10);
+                  p = s + l;
+                  char buf[4];
+                  sprintf(buf, "#%02X", (unsigned char)*p);
+                  memmove(p + 2, p, strlen(p) + 1);
+                  strncpy(p, buf, 3);
+                  p += 2;
+                  }
+             }
            }
         else {
-           for (struct tCharExchange *ce = CharExchange; ce->a && ce->b; ce++) {
-               if (*p == (ToFileSystem ? ce->a : ce->b)) {
-                  *p = ToFileSystem ? ce->b : ce->a;
-                  break;
+           switch (*p) {
+             // mapped characters:
+             case '_': *p = ' '; break;
+             case '/': *p = '~'; break;
+             case '~': *p = '/'; break;
+             // encoded characters:
+             case '#': {
+                  if (VfatFileSystem && strlen(p) > 2) {
+                     char buf[3];
+                     sprintf(buf, "%c%c", *(p + 1), *(p + 2));
+                     unsigned char c = strtol(buf, NULL, 16);
+                     *p = c;
+                     memmove(p + 1, p + 3, strlen(p) - 2);
+                     }
                   }
-               }
+                  break;
+             // backwards compatibility:
+             case '\x01': *p = '\''; break;
+             case '\x02': *p = '/';  break;
+             case '\x03': *p = ':';  break;
+             }
            }
         p++;
         }
--- menu.c	2006/04/16 10:09:21	1.433
+++ menu.c	2006/04/16 12:20:46
@@ -2036,7 +2036,7 @@ 
      cRecording *recording = GetRecording(ri);
      if (recording) {
         char *parameter = NULL;
-        asprintf(&parameter, "'%s'", recording->FileName());
+        asprintf(&parameter, "\"%s\"", *strescape(recording->FileName(), "\"$"));
         cMenuCommands *menu;
         eOSState state = AddSubMenu(menu = new cMenuCommands(tr("Recording commands"), &RecordingCommands, parameter));
         free(parameter);