Skip to content

rc: fix sizes and durations passed as numbers in flat parameters - #9985

Open
r0h1tb wants to merge 1 commit into
rclone:masterfrom
r0h1tb:fix/rc-flat-size-number
Open

r0h1tb wants to merge 1 commit into
rclone:masterfrom
r0h1tb:fix/rc-flat-size-number

Conversation

@r0h1tb

@r0h1tb r0h1tb commented Sep 26, 2026

Copy link
Copy Markdown
Contributor

What does this change do?

The rc docs say a size can be passed flat as a number of bytes:

"buffer_size": "42M"
"buffer_size": 44040192

but the second form sets a 42 GiB buffer. configstruct.SetAny turns every flat value into a string and parses it like a command line flag, so a number is read as KiB for a size and as seconds for a duration. The nested _config / vfsOpt form goes through UnmarshalJSON and reads the same numbers as bytes and nanoseconds, which is what the data types section describes.

$ rclone rc --loopback options/local --json '{"buffer_size": 44040192, "timeout": 5000000000}'
master:   "BufferSize": 45097156608, "Timeout": 5000000000000000000
this PR:  "BufferSize": 44040192,    "Timeout": 5000000000

Plain int options were affected too: integers of a million or more come out of fmt.Sprint as 1e+06 and fail to parse.

This decodes numbers as JSON into the field's type, so flat and nested values mean the same thing. Strings still go through the command line parser, so rclone rc ... buffer_size=42M timeout=30s behaves exactly as before, and a number that doesn't decode falls back to the old path.

One behaviour change to be aware of: a duration passed flat as a number was seconds and is now nanoseconds, matching _config and the docs. "timeout": "30s" is unaffected.

Side note: setIfSameType can't match when called from SetAny, since it compares against the type of the any variable rather than the value inside it. I haven't touched it here.

Tests: new TestParseOptions/FlatNumbers subtest. On master it fails with Size:45097156608, Duration:5000000000000000000 and parsing "1e+06" as int failed. make quicktest matches master (cmd/gitannex fails on both, no git-annex here), and golangci-lint run on the changed packages reports 0 issues.

Linked issue

None, the docs already describe the intended behaviour.

Checklist

  • This change is trivial OR it has been discussed and agreed in the linked issue.
  • I have read the contribution guidelines.
  • (If I used AI tools to help write this code) I have read and understood the AI-assisted contributions guidance, and I have tested and take ownership of this change myself.
  • I have added tests for all changes in this PR if appropriate.
  • I have added documentation for the changes if appropriate.
  • All commit messages are in house style.
  • This Pull Request is ready for review.

Options passed flat at the top level of an rc call were turned into a
string and parsed like a command line flag, so a number meant KiB for a
size and seconds for a duration. The nested form and the rc docs read a
number as bytes and nanoseconds, so the documented example

    "buffer_size": 44040192

set a 42 GiB buffer rather than 42 MiB. Integers of a million or more
also came out as "1e+06" and were rejected by int options.

Decode numbers as JSON so they mean the same as in the nested form.
Strings are parsed as before.
@r0h1tb
r0h1tb requested a review from ncw as a code owner September 26, 2026 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant