mirror of
https://github.com/minio/minio
synced 2024-11-05 17:34:01 +00:00
parent
bba562235b
commit
97f2bc26b9
6 changed files with 91 additions and 12 deletions
|
@ -139,6 +139,7 @@ const (
|
|||
ErrSlowDown
|
||||
ErrInvalidPrefixMarker
|
||||
ErrBadRequest
|
||||
ErrKeyTooLongError
|
||||
// Add new error codes here.
|
||||
|
||||
// SSE-S3 related API errors
|
||||
|
@ -187,6 +188,7 @@ const (
|
|||
ErrRequestBodyParse
|
||||
ErrObjectExistsAsDirectory
|
||||
ErrInvalidObjectName
|
||||
ErrInvalidObjectNamePrefixSlash
|
||||
ErrInvalidResourceName
|
||||
ErrServerNotInitialized
|
||||
ErrOperationTimedOut
|
||||
|
@ -682,6 +684,11 @@ var errorCodes = errorCodeMap{
|
|||
Description: "400 BadRequest",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
},
|
||||
ErrKeyTooLongError: {
|
||||
Code: "KeyTooLongError",
|
||||
Description: "Your key is too long",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
},
|
||||
|
||||
// FIXME: Actual XML error response also contains the header which missed in list of signed header parameters.
|
||||
ErrUnsignedHeaders: {
|
||||
|
@ -885,6 +892,11 @@ var errorCodes = errorCodeMap{
|
|||
Description: "Object name contains unsupported characters.",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
},
|
||||
ErrInvalidObjectNamePrefixSlash: {
|
||||
Code: "XMinioInvalidObjectName",
|
||||
Description: "Object name contains a leading slash.",
|
||||
HTTPStatusCode: http.StatusBadRequest,
|
||||
},
|
||||
ErrInvalidResourceName: {
|
||||
Code: "XMinioInvalidResourceName",
|
||||
Description: "Resource name contains bad components such as \"..\" or \".\".",
|
||||
|
@ -1579,6 +1591,8 @@ func toAPIErrorCode(ctx context.Context, err error) (apiErr APIErrorCode) {
|
|||
apiErr = ErrMethodNotAllowed
|
||||
case ObjectNameInvalid:
|
||||
apiErr = ErrInvalidObjectName
|
||||
case ObjectNamePrefixAsSlash:
|
||||
apiErr = ErrInvalidObjectNamePrefixSlash
|
||||
case InvalidUploadID:
|
||||
apiErr = ErrNoSuchUpload
|
||||
case InvalidPart:
|
||||
|
@ -1639,6 +1653,8 @@ func toAPIErrorCode(ctx context.Context, err error) (apiErr APIErrorCode) {
|
|||
apiErr = ErrBackendDown
|
||||
case crypto.Error:
|
||||
apiErr = ErrObjectTampered
|
||||
case ObjectNameTooLong:
|
||||
apiErr = ErrKeyTooLongError
|
||||
default:
|
||||
var ie, iw int
|
||||
// This work-around is to handle the issue golang/go#30648
|
||||
|
|
|
@ -269,11 +269,27 @@ func (e BucketNameInvalid) Error() string {
|
|||
// ObjectNameInvalid - object name provided is invalid.
|
||||
type ObjectNameInvalid GenericError
|
||||
|
||||
// ObjectNameTooLong - object name too long.
|
||||
type ObjectNameTooLong GenericError
|
||||
|
||||
// ObjectNamePrefixAsSlash - object name has a slash as prefix.
|
||||
type ObjectNamePrefixAsSlash GenericError
|
||||
|
||||
// Return string an error formatted as the given text.
|
||||
func (e ObjectNameInvalid) Error() string {
|
||||
return "Object name invalid: " + e.Bucket + "#" + e.Object
|
||||
}
|
||||
|
||||
// Return string an error formatted as the given text.
|
||||
func (e ObjectNameTooLong) Error() string {
|
||||
return "Object name too long: " + e.Bucket + "#" + e.Object
|
||||
}
|
||||
|
||||
// Return string an error formatted as the given text.
|
||||
func (e ObjectNamePrefixAsSlash) Error() string {
|
||||
return "Object name contains forward slash as pefix: " + e.Bucket + "#" + e.Object
|
||||
}
|
||||
|
||||
// AllAccessDisabled All access to this object has been disabled
|
||||
type AllAccessDisabled GenericError
|
||||
|
||||
|
|
|
@ -166,18 +166,18 @@ func checkObjectArgs(ctx context.Context, bucket, object string, obj ObjectLayer
|
|||
if err := checkBucketExist(ctx, bucket, obj); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := checkObjectNameForLengthAndSlash(bucket, object); err != nil {
|
||||
return err
|
||||
}
|
||||
// Validates object name validity after bucket exists.
|
||||
if !IsValidObjectName(object) {
|
||||
logger.LogIf(ctx, ObjectNameInvalid{
|
||||
Bucket: bucket,
|
||||
Object: object,
|
||||
})
|
||||
|
||||
return ObjectNameInvalid{
|
||||
Bucket: bucket,
|
||||
Object: object,
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -192,8 +192,10 @@ func checkPutObjectArgs(ctx context.Context, bucket, object string, obj ObjectLa
|
|||
return err
|
||||
}
|
||||
|
||||
if err := checkObjectNameForLengthAndSlash(bucket, object); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(object) == 0 ||
|
||||
hasPrefix(object, slashSeparator) ||
|
||||
(hasSuffix(object, slashSeparator) && size != 0) ||
|
||||
!IsValidObjectPrefix(object) {
|
||||
return ObjectNameInvalid{
|
||||
|
|
|
@ -136,7 +136,7 @@ func IsValidObjectName(object string) bool {
|
|||
if len(object) == 0 {
|
||||
return false
|
||||
}
|
||||
if hasSuffix(object, slashSeparator) || hasPrefix(object, slashSeparator) {
|
||||
if hasSuffix(object, slashSeparator) {
|
||||
return false
|
||||
}
|
||||
return IsValidObjectPrefix(object)
|
||||
|
@ -148,9 +148,6 @@ func IsValidObjectPrefix(object string) bool {
|
|||
if hasBadPathComponent(object) {
|
||||
return false
|
||||
}
|
||||
if len(object) > 1024 {
|
||||
return false
|
||||
}
|
||||
if !utf8.ValidString(object) {
|
||||
return false
|
||||
}
|
||||
|
@ -161,6 +158,25 @@ func IsValidObjectPrefix(object string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// checkObjectNameForLengthAndSlash -check for the validity of object name length and prefis as slash
|
||||
func checkObjectNameForLengthAndSlash(bucket, object string) error {
|
||||
// Check for the length of object name
|
||||
if len(object) > 1024 {
|
||||
return ObjectNameTooLong{
|
||||
Bucket: bucket,
|
||||
Object: object,
|
||||
}
|
||||
}
|
||||
// Check for slash as prefix in object name
|
||||
if hasPrefix(object, slashSeparator) {
|
||||
return ObjectNamePrefixAsSlash{
|
||||
Bucket: bucket,
|
||||
Object: object,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Slash separator.
|
||||
const slashSeparator = "/"
|
||||
|
||||
|
|
|
@ -113,7 +113,6 @@ func TestIsValidObjectName(t *testing.T) {
|
|||
// passing invalid object names.
|
||||
{"", false},
|
||||
{"a/b/c/", false},
|
||||
{"/a/b/c", false},
|
||||
{"../../etc", false},
|
||||
{"../../", false},
|
||||
{"/../../etc", false},
|
||||
|
|
|
@ -1354,7 +1354,37 @@ func (s *TestSuiteCommon) TestPutObjectLongName(c *check) {
|
|||
response, err = client.Do(request)
|
||||
c.Assert(err, nil)
|
||||
c.Assert(response.StatusCode, http.StatusOK)
|
||||
// make long object name.
|
||||
|
||||
//make long object name.
|
||||
longObjName = fmt.Sprintf("%0255d/%0255d/%0255d/%0255d/%0255d", 1, 1, 1, 1, 1)
|
||||
if IsDocker() || IsKubernetes() {
|
||||
longObjName = fmt.Sprintf("%0242d/%0242d/%0242d/%0242d/%0242d", 1, 1, 1, 1, 1)
|
||||
}
|
||||
// create new HTTP request to insert the object.
|
||||
buffer = bytes.NewReader([]byte("hello world"))
|
||||
request, err = newTestSignedRequest("PUT", getPutObjectURL(s.endPoint, bucketName, longObjName),
|
||||
int64(buffer.Len()), buffer, s.accessKey, s.secretKey, s.signer)
|
||||
c.Assert(err, nil)
|
||||
// execute the HTTP request.
|
||||
response, err = client.Do(request)
|
||||
c.Assert(err, nil)
|
||||
c.Assert(response.StatusCode, http.StatusBadRequest)
|
||||
verifyError(c, response, "KeyTooLongError", "Your key is too long", http.StatusBadRequest)
|
||||
|
||||
// make object name with prefix as slash
|
||||
longObjName = fmt.Sprintf("/%0255d/%0255d", 1, 1)
|
||||
buffer = bytes.NewReader([]byte("hello world"))
|
||||
// create new HTTP request to insert the object.
|
||||
request, err = newTestSignedRequest("PUT", getPutObjectURL(s.endPoint, bucketName, longObjName),
|
||||
int64(buffer.Len()), buffer, s.accessKey, s.secretKey, s.signer)
|
||||
c.Assert(err, nil)
|
||||
// execute the HTTP request.
|
||||
response, err = client.Do(request)
|
||||
c.Assert(err, nil)
|
||||
c.Assert(response.StatusCode, http.StatusBadRequest)
|
||||
verifyError(c, response, "XMinioInvalidObjectName", "Object name contains a leading slash.", http.StatusBadRequest)
|
||||
|
||||
//make object name as unsuported
|
||||
longObjName = fmt.Sprintf("%0256d", 1)
|
||||
buffer = bytes.NewReader([]byte("hello world"))
|
||||
request, err = newTestSignedRequest("PUT", getPutObjectURL(s.endPoint, bucketName, longObjName),
|
||||
|
|
Loading…
Reference in a new issue