google / adb-sync

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Colon not supported in folder name

tyrossel opened this issue · comments

It is not possible to create a folder with a colon : in its name on Android :

mkdir: '/sdcard/Music/Brian Tyler/Assassin's Creed 4: Black Flag (Original Game Soundtrack)': Invalid argument
INFO:root:Total: 0 KB/s (0 bytes in 58.417s)
Traceback (most recent call last):
  File "adb-sync", line 883, in <module>
    main()
  File "adb-sync", line 877, in main
    syncer.PerformCopies()
  File "adb-sync", line 634, in PerformCopies
    self.dst_fs[i].makedirs(dst_name)
  File "adb-sync", line 300, in makedirs
    raise OSError('mkdir failed')
OSError: mkdir failed

Maybe replace it with a _ ?

I would prefer not introducing any kind of replacing as otherwise syncing back and forth would create duplicates.

If anything we would need either a bijective encoding, or - if activated by a special flag - an injective one (e.g. replacing invalid characters by escapes like =3A for a colon).

Not sure if I'll get to coding this, but it can be fixed by replacing the colon in the android folder name with a Modified Letter Colon which is fairly similar to a regular colon. Essentially, as @divVerent said, this could be used to encode it both ways while maintaining the look of the colon on android.

Just to check, has anyone done a root cause analysis on this? Most Unix filesystems have no problem with colon characters (on Mac, maybe, but that's worked around) so I am intrigued by what is causing this?

Edit: good heavens, there are several possible issues here:

    if subprocess.call(
        self.adb +
        [b'shell', b'mkdir -p %s' % (self.QuoteArgument(path),)]) != 0:
      raise OSError('mkdir failed')

For others on Windows who want to still be able to copy the files with invalid characters, this is the workaround I currently use.

Replace the dst_name = self.dst[i] + name line in the PerformCopies function with: dst_name = self.dst[i] + re.sub(b'[^\w\-_\.\(\) \\/]', b'_', name)

If you merely want the files with invalid names to be ignored, see here to have it just skip over files that have errors (you just add a try-catch in the loop): #29 (comment)

I'm hit by this as well - and I'm using adb-sync on Linux. The problem seems to be with the underlying adb implementation because I can't adb push files with colon in their names either. This EPERM seems to be a new behavior on Andorid 10 or 11.

It's actually a new restriction when using the FUSE backed emulated storage and the code is in MediaProvider:

    public int insertFileIfNecessaryForFuse(@NonNull String path, int uid) {
...
            if (!path.equals(getAbsoluteSanitizedPath(path))) {
                Log.e(TAG, "File name contains invalid characters");
                return OsConstants.EPERM;
            }

Since it's a limitation in the system (and to be fair, colon is indeed an invalid character for a FAT file system), I don't think adb-sync can do anything here.

EDIT:

You can edit PerformCopies and put in dst_name = self.dst[i] + re.sub(b'["*:<>?\\\\|]', b'_', name)

commented

This used to work on Android 10 (for me) and I see absolutely no reason why ":" cannot be a valid character on modern filesystems.

This is not only caused by colons, but is also by asterisks and double quotes.