GothenburgBitFactory / taskserver

Taskserver - Taskwarrior Synchronisation Server
Other
214 stars 38 forks source link

Taskserver inserts null byte when trailing slash is outbound #173

Closed bradyt closed 2 months ago

bradyt commented 3 years ago

I discovered this issue when sending a task description hello\ from a third party mobile client to a Taskserver.

Tangentially, I noticed task 2.5.3 (from macOS Homebrew) barfs on task add hello\\, with broken or missing lines in ~/.task/*.data. Building from current task 2.6.0 fixed this issue, task add hello\\ works fine there.

But the issue I don't see a solution for, is when syncing this data to taskd, whether on stable 1.1.0, or building from source at 1.2.0.

It looks like "description":"hello\\" will land successfully into $TASKDDATA/orgs/<org>/users/<user key>/tx.data.

But when a client attempts to synchronize where the updates will include this task update, it seems like Taskserver inserts a null byte, so that it sends a task update like "description":"hello\\\\\x00", (I'm adding escapes as I see them when a string comparison finally reveals the null byte). So in "pseudocode", I think it's sending it as something like "description":"hello\\^@" or "description":"hello\\␀".

In the Taskserver logs, it looks like this:

s: INFO Sending 'XXXXcode: 200
status: Ok

{"description":"hello\\' (213 bytes)

In Taskwarrior, with task rc.debug.tls=2 sync, we see the following:

c: INFO Receiving 'XXXXcode: 200
status: Ok

{"description":"hello\\' (213 bytes)
Configuration override rc.debug.tls=2
Unrecognized Taskwarrior file format or blank line in data.

Note that third party clients do see the full string with null byte in the middle, from the payload in the message response. Maybe taskd api would give a cleaner reproduce, but I haven't tried that tool yet.

If you have feedback on how third party clients might add a quick fix for this, please let me know. I'm considering maybe just validating data where input is rejected if there is an ~unmatched~ trailing slash like in hello\.

bradyt commented 2 years ago

I don't know if people need a minimal reproduce for this. This is reproducible for task 2.6.1 and taskd 1.1.0.

RUN task add foo\\

RUN taskdctl start && sleep 3 && task sync

RUN rm ~/.task/*.data

RUN taskdctl start && sleep 3 && task sync
 => ERROR [20/22] RUN taskdctl start && sleep 3 && task sync                                                                                                          3.4s 
------                                                                                                                                                                     
 > [20/22] RUN taskdctl start && sleep 3 && task sync:
#24 0.265 /usr/local/bin/taskdctl start: daemon started
#24 3.345 Unrecognized Taskwarrior file format or blank line in data.
------
executor failed running [/bin/sh -c taskdctl start && sleep 3 && task sync]: exit code: 2
make: *** [run] Error 1
bradyt commented 2 years ago

And here is a commit with Dockerfile, PEM files, for minimal reproduce: https://github.com/bradyt/docker-taskwarrior/tree/fe7a40b8dea08deb90d06bf20a882ba0360f9640.

tbabej commented 2 years ago

Thanks @bradyt , that is definitely helpful. We'll fix this for the 1.2. release.

lauft commented 2 months ago

[!IMPORTANT] Taskserver is only compatible with Taskwarrior 2.x, and is no longer actively developed. See man task-sync for task synchronization with Taskwarrior 3