1
0
mirror of https://github.com/minio/mc.git synced 2025-04-18 10:04:03 +03:00
mc/cmd/cp-main_contrib.go
2025-03-28 01:05:40 -07:00

139 lines
2.7 KiB
Go

// MinIO Object Storage (c) 2021 MinIO, Inc.
//
// Copyright (c) 2015-2021 MinIO, Inc.
//
// This file is part of MinIO Object Storage stack
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package cmd
import (
"fmt"
"net/http"
"strings"
"github.com/minio/mc/pkg/probe"
)
// validate the passed metadataString and populate the map
func getMetaDataEntry(metadataString string) (map[string]string, *probe.Error) {
metaDataMap := make(map[string]string)
r := strings.NewReader(metadataString)
type pToken int
const (
KEY pToken = iota
VALUE
)
type pState int
const (
NORMAL pState = iota
QSTRING
DQSTRING
)
var key, value strings.Builder
writeRune := func(ch rune, pt pToken) {
switch pt {
case KEY:
key.WriteRune(ch)
case VALUE:
value.WriteRune(ch)
default:
panic("Invalid parser token type")
}
}
ps := NORMAL
pt := KEY
p := 0
for ; ; p++ {
ch, _, e := r.ReadRune()
if e != nil {
// eof
if ps == QSTRING || ps == DQSTRING || pt == KEY {
return nil, probe.NewError(ErrInvalidMetadata)
}
metaDataMap[http.CanonicalHeaderKey(key.String())] = value.String()
return metaDataMap, nil
}
if ch == '"' {
switch ps {
case DQSTRING:
ps = NORMAL
case QSTRING:
writeRune(ch, pt)
case NORMAL:
ps = DQSTRING
default:
break
}
continue
}
if ch == '\'' {
switch ps {
case QSTRING:
ps = NORMAL
case DQSTRING:
writeRune(ch, pt)
case NORMAL:
ps = QSTRING
default:
break
}
continue
}
if ch == '=' {
if ps == QSTRING || ps == DQSTRING {
writeRune(ch, pt)
} else if pt == KEY {
pt = VALUE
} else if pt == VALUE {
writeRune(ch, pt)
} else {
break
}
continue
}
if ch == ';' {
if ps == QSTRING || ps == DQSTRING {
writeRune(ch, pt)
} else if pt == KEY {
return nil, probe.NewError(ErrInvalidMetadata)
} else if pt == VALUE {
metaDataMap[http.CanonicalHeaderKey(key.String())] = value.String()
key.Reset()
value.Reset()
pt = KEY
} else {
break
}
continue
}
writeRune(ch, pt)
}
fatalErr := fmt.Sprintf("Invalid parser state at index: %d", p)
panic(fatalErr)
}