Repository: borgbackup/borg

Issue:
"borg create" throws ValueError on files with backslashes in name
```
$ wget -q https://github.com/borgbackup/borg/releases/download/2.0.0b6/borg-linux64
$ chmod a+x borg-linux64
$ ./borg-linux64 rcreate -e none --repo=r1
$ mkdir tmp && touch tmp/\\
$ ./borg-linux64 create --repo=r1 a1 tmp
Local Exception

Error:

ValueError: unexpected backslash(es) in path 'tmp/\\'

If reporting bugs, please include the following:

Traceback (most recent call last):
  File "borg/archiver/__init__.py", line 630, in main
  File "borg/archiver/__init__.py", line 536, in run
  File "borg/archiver/_common.py", line 157, in wrapper
  File "borg/archiver/create_cmd.py", line 282, in do_create
  File "borg/archiver/create_cmd.py", line 174, in create_inner
  File "borg/archiver/create_cmd.py", line 517, in _rec_walk
  File "borg/archiver/create_cmd.py", line 461, in _rec_walk
  File "borg/archiver/create_cmd.py", line 299, in _process_any
  File "borg/archive.py", line 1479, in process_file
  File "contextlib.py", line 137, in __enter__
  File "borg/archive.py", line 1375, in create_helper
  File "src/borg/item.pyx", line 158, in borg.item.PropDict.__cinit__
  File "src/borg/item.pyx", line 164, in borg.item.PropDict.update
  File "src/borg/item.pyx", line 232, in borg.item.PropDictProperty.__set__
  File "borg/helpers/fs.py", line 262, in assert_sanitized_path
  File "borg/helpers/fs.py", line 233, in make_path_safe
ValueError: unexpected backslash(es) in path 'tmp/\\'

Platform: Linux manx 6.3.0-6-generic #6-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun  2 12:05:05 UTC 2023 x86_64
Linux: Unknown Linux  
Borg: 2.0.0b6  Python: CPython 3.11.2 msgpack: 1.0.5 fuse: llfuse 1.4.4 [pyfuse3,llfuse]
PID: 132763  CWD: /home/ghakko/Desktop
sys.argv: ['./borg-linux64', 'create', '--repo=r1', 'a1', 'tmp']
SSH_ORIGINAL_COMMAND: None
```

2.0.0b6 macOS binary has the same issue.


Discussion:
hmm, why would anybody have a backslash in a path on linux or macOS?

that check was added mainly to avoid that a borg running on windows would ever create archives using backslashes as path separator (they should be normalized to slashes first).
Apple Mail sometimes stores mail attachments detached into separate files, and one of my users had such a file named "Library/Mail/V9/…/Data/2/1/4/Attachments/412627/1.1.2/C:\Users\Ben\Desktop\Table.jpg".

Backslashed names like these were fine in Borg 1.2.

I’m certainly not endorsing what Apple Mail does here, but shouldn’t Borg at least not crash out when encountering such files?
I encountered the same error, in my case with a backup of the data from my mailcow instance. Afaik the backslash is a legal character and should be allowed (in my case Ubuntu server). Can the newly implemented test (2.0.0.b5 worked) be restricted to Windows versions only? Otherwise it is a go/nogo for this fantastic backup tool as I cannot avoid mailcow using backslashes. Assume the same applies for apple mail. 
Hmm, didn't know that anybody uses backslash on linux / mac.

So, guess it is better to remove this and have a unit test just for windows that checks that windows path separator backslashes get translated to unix style path separator slashes.

https://github.com/borgbackup/borg/blob/2.0.0b6/src/borg/helpers/fs.py#LL232C1-L233C99

These 2 lines can be removed for a quick fix.
Hi, just FYI:

> Hmm, didn't know that anybody uses backslash on linux / mac.

It seems that at least Lennart Poettering is using backslashes on linux/mac :-P 

Because, I run in this issue on a linux machine during backup a lxd container snapshot.
There is/was a systemd file: `system-systemd\x2dcryptsetup.slice` 


And the mentioned quick fix worked. :+1: 

```
Creating archive at "ssh://henning.reich@localhost:22/~/test_repo"
Initializing cache transaction: Reading config                                                                                            
Initializing cache transaction: Reading chunks
Initializing cache transaction: Reading files

Local Exception.77 MB U 9338 N borg/rootfs/usr/lib/systemd/system/debug-shell.service                                                     

Error:

ValueError: unexpected backslash(es) in path 'borg/rootfs/usr/lib/systemd/system/system-systemd\\x2dcryptsetup.slice'

If reporting bugs, please include the following:

Traceback (most recent call last):
  File "borg/archiver/__init__.py", line 630, in main
  File "borg/archiver/__init__.py", line 536, in run
  File "borg/archiver/_common.py", line 157, in wrapper
  File "borg/archiver/create_cmd.py", line 282, in do_create
  File "borg/archiver/create_cmd.py", line 174, in create_inner
  File "borg/archiver/create_cmd.py", line 517, in _rec_walk
  File "borg/archiver/create_cmd.py", line 517, in _rec_walk
  File "borg/archiver/create_cmd.py", line 517, in _rec_walk
  [Previous line repeated 3 more times]
  File "borg/archiver/create_cmd.py", line 461, in _rec_walk
  File "borg/archiver/create_cmd.py", line 299, in _process_any
  File "borg/archive.py", line 1479, in process_file
  File "contextlib.py", line 137, in __enter__
  File "borg/archive.py", line 1375, in create_helper
  File "src/borg/item.pyx", line 158, in borg.item.PropDict.__cinit__
  File "src/borg/item.pyx", line 164, in borg.item.PropDict.update
  File "src/borg/item.pyx", line 232, in borg.item.PropDictProperty.__set__
  File "borg/helpers/fs.py", line 262, in assert_sanitized_path
  File "borg/helpers/fs.py", line 233, in make_path_safe
ValueError: unexpected backslash(es) in path 'borg/rootfs/usr/lib/systemd/system/system-systemd\\x2dcryptsetup.slice'

Platform: Linux HP-EliteBook 5.19.0-43-generic #44~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon May 22 13:39:36 UTC 2 x86_64
Linux: Unknown Linux  
Borg: 2.0.0b6  Python: CPython 3.11.2 msgpack: 1.0.5 fuse: llfuse 1.4.4 [pyfuse3,llfuse]
PID: 875161  CWD: /var/snap/lxd/common/lxd/storage-pools/default/containers-snapshots/test
sys.argv: ['/home/henning.reich/git/lxborg/borg2b6', 'create', '-v', '-s', '--progress', '--compression=auto,zstd', 'test_2023-06-15_13:51:39', 'borg']
SSH_ORIGINAL_COMMAND: None
```


Linux path names are just bytes. They can contain anything except the path separator (`/`) and `null`. 

Resolving patch:
diff --git a/src/borg/helpers/fs.py b/src/borg/helpers/fs.py
--- a/src/borg/helpers/fs.py
+++ b/src/borg/helpers/fs.py
@@ -229,8 +229,6 @@ def make_path_safe(path):
     `path` contain any '..' elements.
     """
     path = path.lstrip("/")
-    if "\\" in path:  # borg always wants slashes, never backslashes.
-        raise ValueError(f"unexpected backslash(es) in path {path!r}")
     if path.startswith("../") or "/../" in path or path.endswith("/..") or path == "..":
         raise ValueError(f"unexpected '..' element in path {path!r}")
     path = os.path.normpath(path)


Test patch: