mirror of
https://github.com/rclone/rclone.git
synced 2025-12-10 21:33:27 +00:00
config: fix problem reading pasted tokens over 4095 bytes
Before this change we were reading input from stdin using the terminal
in the default line mode which has a limit of 4095 characters.
The typical culprit was onedrive tokens (which are very long) giving the error
Couldn't decode response: invalid character 'e' looking for beginning of value
This change swaps over to use the github.com/peterh/liner read line
library which does not have that limitation and also enables more
sensible cursor editing.
Fixes #8688 #8323 #5835
This commit is contained in:
@@ -17,7 +17,7 @@ import (
|
||||
func ReadPassword() string {
|
||||
stdin := int(os.Stdin.Fd())
|
||||
if !terminal.IsTerminal(stdin) {
|
||||
return ReadLine()
|
||||
return ReadLine("")
|
||||
}
|
||||
line, err := terminal.ReadPassword(stdin)
|
||||
_, _ = fmt.Fprintln(os.Stderr)
|
||||
|
||||
@@ -7,5 +7,5 @@ package config
|
||||
|
||||
// ReadPassword reads a password with echoing it to the terminal.
|
||||
func ReadPassword() string {
|
||||
return ReadLine()
|
||||
return ReadLine("")
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -15,6 +14,7 @@ import (
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/peterh/liner"
|
||||
"github.com/rclone/rclone/fs"
|
||||
"github.com/rclone/rclone/fs/config/configmap"
|
||||
"github.com/rclone/rclone/fs/config/configstruct"
|
||||
@@ -25,12 +25,22 @@ import (
|
||||
"golang.org/x/text/unicode/norm"
|
||||
)
|
||||
|
||||
// ReadLine reads some input
|
||||
var ReadLine = func() string {
|
||||
buf := bufio.NewReader(os.Stdin)
|
||||
line, err := buf.ReadString('\n')
|
||||
if err != nil && (line == "" || err != io.EOF) {
|
||||
fs.Fatalf(nil, "Failed to read line: %v", err)
|
||||
// ReadLine reads an unlimited length line from stdin with a prompt.
|
||||
var ReadLine = func(prompt string) string {
|
||||
l := liner.NewLiner()
|
||||
defer func() {
|
||||
_ = l.Close()
|
||||
}()
|
||||
l.SetMultiLineMode(true)
|
||||
l.SetCtrlCAborts(true)
|
||||
|
||||
line, err := l.Prompt(prompt)
|
||||
if err == io.EOF {
|
||||
return ""
|
||||
}
|
||||
if err != nil {
|
||||
_ = l.Close()
|
||||
fs.Fatalf(nil, "Failed to read: %v", err)
|
||||
}
|
||||
return strings.TrimSpace(line)
|
||||
}
|
||||
@@ -39,8 +49,7 @@ var ReadLine = func() string {
|
||||
func ReadNonEmptyLine(prompt string) string {
|
||||
result := ""
|
||||
for result == "" {
|
||||
fmt.Print(prompt)
|
||||
result = strings.TrimSpace(ReadLine())
|
||||
result = strings.TrimSpace(ReadLine(prompt))
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -63,8 +72,7 @@ func CommandDefault(commands []string, defaultIndex int) byte {
|
||||
optString := strings.Join(opts, "")
|
||||
optHelp := strings.Join(opts, "/")
|
||||
for {
|
||||
fmt.Printf("%s> ", optHelp)
|
||||
result := strings.ToLower(ReadLine())
|
||||
result := strings.ToLower(ReadLine(fmt.Sprintf("%s> ", optHelp)))
|
||||
if len(result) == 0 {
|
||||
if defaultIndex >= 0 {
|
||||
return optString[defaultIndex]
|
||||
@@ -146,8 +154,7 @@ func Choose(what string, kind string, choices, help []string, defaultValue strin
|
||||
terminal.WriteString(terminal.Reset)
|
||||
}
|
||||
for {
|
||||
fmt.Printf("%s> ", what)
|
||||
result := ReadLine()
|
||||
result := ReadLine(fmt.Sprintf("%s> ", what))
|
||||
i, err := strconv.Atoi(result)
|
||||
if err != nil {
|
||||
if slices.Contains(choices, result) {
|
||||
@@ -194,8 +201,7 @@ func Enter(what string, kind string, defaultValue string, required bool) string
|
||||
fmt.Println()
|
||||
}
|
||||
for {
|
||||
fmt.Printf("%s> ", what)
|
||||
result := ReadLine()
|
||||
result := ReadLine(fmt.Sprintf("%s> ", what))
|
||||
if !required || result != "" {
|
||||
return result
|
||||
}
|
||||
@@ -254,8 +260,7 @@ func ChoosePassword(defaultValue string, required bool) string {
|
||||
// inclusive prompting them with what.
|
||||
func ChooseNumber(what string, min, max int) int {
|
||||
for {
|
||||
fmt.Printf("%s> ", what)
|
||||
result := ReadLine()
|
||||
result := ReadLine(fmt.Sprintf("%s> ", what))
|
||||
i, err := strconv.Atoi(result)
|
||||
if err != nil {
|
||||
fmt.Printf("Bad number: %v\n", err)
|
||||
@@ -526,8 +531,7 @@ func ChooseOption(o *fs.Option, name string) string {
|
||||
func NewRemoteName() (name string) {
|
||||
for {
|
||||
fmt.Println("Enter name for new remote.")
|
||||
fmt.Printf("name> ")
|
||||
name = ReadLine()
|
||||
name = ReadLine("name> ")
|
||||
if LoadedData().HasSection(name) {
|
||||
fmt.Printf("Remote %q already exists.\n", name)
|
||||
continue
|
||||
|
||||
@@ -85,9 +85,9 @@ func testConfigFile(t *testing.T, options []fs.Option, configFileName string) fu
|
||||
|
||||
// makeReadLine makes a simple readLine which returns a fixed list of
|
||||
// strings
|
||||
func makeReadLine(answers []string) func() string {
|
||||
func makeReadLine(answers []string) func(string) string {
|
||||
i := 0
|
||||
return func() string {
|
||||
return func(string) string {
|
||||
i++
|
||||
return answers[i-1]
|
||||
}
|
||||
|
||||
1
go.mod
1
go.mod
@@ -56,6 +56,7 @@ require (
|
||||
github.com/ncw/swift/v2 v2.0.4
|
||||
github.com/oracle/oci-go-sdk/v65 v65.98.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/peterh/liner v1.2.2
|
||||
github.com/pkg/sftp v1.13.9
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
|
||||
github.com/prometheus/client_golang v1.23.0
|
||||
|
||||
4
go.sum
4
go.sum
@@ -454,6 +454,7 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI=
|
||||
@@ -500,6 +501,8 @@ github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14 h1:XeOYlK9W1uCmhjJSsY78Mcuh7MVkNjTzmHx1yBzizSU=
|
||||
github.com/pengsrc/go-shared v0.2.1-0.20190131101655-1999055a4a14/go.mod h1:jVblp62SafmidSkvWrXyxAme3gaTfEtWwRPGz5cpvHg=
|
||||
github.com/peterh/liner v1.2.2 h1:aJ4AOodmL+JxOZZEL2u9iJf8omNRpqHc/EbrK+3mAXw=
|
||||
github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI=
|
||||
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
|
||||
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
|
||||
@@ -845,6 +848,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220408201424-a24fb2fb8a0f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
||||
Reference in New Issue
Block a user