Do not panic on empty quoted string argument
<!--
Please make sure you've read and understood our contributing guidelines;
https://github.com/moby/moby/blob/master/CONTRIBUTING.md

** Make sure all your commits include a signature generated with `git commit -s` **

For additional information on our contributing process, read our contributing
guide https://docs.docker.com/opensource/code/

If this is a bug fix, make sure your description includes "fixes #xxxx", or
"closes #xxxx"

Please provide the following information:
-->

**- What I did**

Fix the handling of empty or single characters command line arguments such as
--tlscacert="" or --tlscacert="'"

**- How I did it**

Ensure the argument is at least 2 characters.

**- How to verify it**

Added a unit test to handle both cases

**- Description for the changelog**
<!--
Write a short (one line) summary that describes the changes in this
pull request for inclusion in the changelog:
-->

Currently, calling `dockerd --tlscacert=""` make Docker to panic.

**- A picture of a cute animal (not mandatory but encouraged)**


opts/quotedstring_test.go
package opts // import "github.com/docker/docker/opts"

import (
	"testing"

	"gotest.tools/v3/assert"
	is "gotest.tools/v3/assert/cmp"
)

func TestQuotedStringSetWithQuotes(t *testing.T) {
	value := ""
	qs := NewQuotedString(&value)
	assert.Check(t, qs.Set(`"something"`))
	assert.Check(t, is.Equal("something", qs.String()))
	assert.Check(t, is.Equal("something", value))
}

func TestQuotedStringSetWithMismatchedQuotes(t *testing.T) {
	value := ""
	qs := NewQuotedString(&value)
	assert.Check(t, qs.Set(`"something'`))
	assert.Check(t, is.Equal(`"something'`, qs.String()))
}

func TestQuotedStringSetWithNoQuotes(t *testing.T) {
	value := ""
	qs := NewQuotedString(&value)
	assert.Check(t, qs.Set("something"))
	assert.Check(t, is.Equal("something", qs.String()))
}

package opts // import "github.com/docker/docker/opts"

import (
	"testing"

	"gotest.tools/v3/assert"
	is "gotest.tools/v3/assert/cmp"
)

func TestQuotedStringSetWithQuotes(t *testing.T) {
	value := ""
	qs := NewQuotedString(&value)
	assert.Check(t, qs.Set(`"something"`))
	assert.Check(t, is.Equal("something", qs.String()))
	assert.Check(t, is.Equal("something", value))
}

func TestQuotedStringSetWithMismatchedQuotes(t *testing.T) {
	qs := NewQuotedString(new(string))
	assert.Check(t, qs.Set(`"something'`))
	assert.Check(t, is.Equal(`"something'`, qs.String()))
}

func TestQuotedStringSetWithNoQuotes(t *testing.T) {
	qs := NewQuotedString(new(string))
	assert.Check(t, qs.Set("something"))
	assert.Check(t, is.Equal("something", qs.String()))
}

func TestQuotedStringEmptyOrSingleCharString(t *testing.T) {
	qs := NewQuotedString(new(string))
	assert.Check(t, qs.Set(""))
	assert.Check(t, qs.Set("'"))
}

Orthogonal to this PR, but I just noticed that `QuotedString` only performs the quote stripping when using `Set()`, but `NewQuotedString()` does not do the same, so theoretically, if `value` was a string with quotes, nothing would happen, and `.String()` would return the quoted value as-is. https://github.com/moby/moby/blob/7b9275c0da707b030e62c96b679a976f31f929d3/opts/quotedstring.go#L34-L37


I _think_ that was an oversight (at least, I can't come up with good reasons to have it not do the same). Anyway, I think it's fine to fix that separately