github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/cmd/object-api-input-checks.go (about)

     1  // Copyright (c) 2015-2021 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package cmd
    19  
    20  import (
    21  	"context"
    22  	"encoding/base64"
    23  	"runtime"
    24  	"strings"
    25  
    26  	"github.com/minio/minio-go/v7/pkg/s3utils"
    27  	"github.com/minio/minio/internal/logger"
    28  )
    29  
    30  // Checks on CopyObject arguments, bucket and object.
    31  func checkCopyObjArgs(ctx context.Context, bucket, object string) error {
    32  	return checkBucketAndObjectNames(ctx, bucket, object)
    33  }
    34  
    35  // Checks on GetObject arguments, bucket and object.
    36  func checkGetObjArgs(ctx context.Context, bucket, object string) error {
    37  	return checkBucketAndObjectNames(ctx, bucket, object)
    38  }
    39  
    40  // Checks on DeleteObject arguments, bucket and object.
    41  func checkDelObjArgs(ctx context.Context, bucket, object string) error {
    42  	return checkBucketAndObjectNames(ctx, bucket, object)
    43  }
    44  
    45  // Checks bucket and object name validity, returns nil if both are valid.
    46  func checkBucketAndObjectNames(ctx context.Context, bucket, object string) error {
    47  	// Verify if bucket is valid.
    48  	if !isMinioMetaBucketName(bucket) && s3utils.CheckValidBucketNameStrict(bucket) != nil {
    49  		return BucketNameInvalid{Bucket: bucket}
    50  	}
    51  	// Verify if object is valid.
    52  	if len(object) == 0 {
    53  		return ObjectNameInvalid{Bucket: bucket, Object: object}
    54  	}
    55  	if !IsValidObjectPrefix(object) {
    56  		return ObjectNameInvalid{Bucket: bucket, Object: object}
    57  	}
    58  	if runtime.GOOS == globalWindowsOSName && strings.Contains(object, "\\") {
    59  		// Objects cannot be contain \ in Windows and is listed as `Characters to Avoid`.
    60  		return ObjectNameInvalid{Bucket: bucket, Object: object}
    61  	}
    62  	return nil
    63  }
    64  
    65  // Checks for all ListObjects arguments validity.
    66  func checkListObjsArgs(ctx context.Context, bucket, prefix, marker string) error {
    67  	// Verify if bucket is valid.
    68  	if !isMinioMetaBucketName(bucket) && s3utils.CheckValidBucketNameStrict(bucket) != nil {
    69  		return BucketNameInvalid{Bucket: bucket}
    70  	}
    71  
    72  	// Validates object prefix validity after bucket exists.
    73  	if !IsValidObjectPrefix(prefix) {
    74  		logger.LogIf(ctx, ObjectNameInvalid{
    75  			Bucket: bucket,
    76  			Object: prefix,
    77  		})
    78  		return ObjectNameInvalid{
    79  			Bucket: bucket,
    80  			Object: prefix,
    81  		}
    82  	}
    83  	return nil
    84  }
    85  
    86  // Checks for all ListMultipartUploads arguments validity.
    87  func checkListMultipartArgs(ctx context.Context, bucket, prefix, keyMarker, uploadIDMarker, delimiter string) error {
    88  	if err := checkListObjsArgs(ctx, bucket, prefix, keyMarker); err != nil {
    89  		return err
    90  	}
    91  	if uploadIDMarker != "" {
    92  		if HasSuffix(keyMarker, SlashSeparator) {
    93  			logger.LogIf(ctx, InvalidUploadIDKeyCombination{
    94  				UploadIDMarker: uploadIDMarker,
    95  				KeyMarker:      keyMarker,
    96  			})
    97  			return InvalidUploadIDKeyCombination{
    98  				UploadIDMarker: uploadIDMarker,
    99  				KeyMarker:      keyMarker,
   100  			}
   101  		}
   102  		_, err := base64.RawURLEncoding.DecodeString(uploadIDMarker)
   103  		if err != nil {
   104  			logger.LogIf(ctx, err)
   105  			return MalformedUploadID{
   106  				UploadID: uploadIDMarker,
   107  			}
   108  		}
   109  	}
   110  	return nil
   111  }
   112  
   113  // Checks for NewMultipartUpload arguments validity, also validates if bucket exists.
   114  func checkNewMultipartArgs(ctx context.Context, bucket, object string) error {
   115  	return checkObjectArgs(ctx, bucket, object)
   116  }
   117  
   118  func checkMultipartObjectArgs(ctx context.Context, bucket, object, uploadID string) error {
   119  	_, err := base64.RawURLEncoding.DecodeString(uploadID)
   120  	if err != nil {
   121  		return MalformedUploadID{
   122  			UploadID: uploadID,
   123  		}
   124  	}
   125  	return checkObjectArgs(ctx, bucket, object)
   126  }
   127  
   128  // Checks for PutObjectPart arguments validity, also validates if bucket exists.
   129  func checkPutObjectPartArgs(ctx context.Context, bucket, object, uploadID string) error {
   130  	return checkMultipartObjectArgs(ctx, bucket, object, uploadID)
   131  }
   132  
   133  // Checks for ListParts arguments validity, also validates if bucket exists.
   134  func checkListPartsArgs(ctx context.Context, bucket, object, uploadID string) error {
   135  	return checkMultipartObjectArgs(ctx, bucket, object, uploadID)
   136  }
   137  
   138  // Checks for CompleteMultipartUpload arguments validity, also validates if bucket exists.
   139  func checkCompleteMultipartArgs(ctx context.Context, bucket, object, uploadID string) error {
   140  	return checkMultipartObjectArgs(ctx, bucket, object, uploadID)
   141  }
   142  
   143  // Checks for AbortMultipartUpload arguments validity, also validates if bucket exists.
   144  func checkAbortMultipartArgs(ctx context.Context, bucket, object, uploadID string) error {
   145  	return checkMultipartObjectArgs(ctx, bucket, object, uploadID)
   146  }
   147  
   148  // Checks Object arguments validity.
   149  func checkObjectArgs(ctx context.Context, bucket, object string) error {
   150  	// Verify if bucket is valid.
   151  	if !isMinioMetaBucketName(bucket) && s3utils.CheckValidBucketNameStrict(bucket) != nil {
   152  		return BucketNameInvalid{Bucket: bucket}
   153  	}
   154  
   155  	if err := checkObjectNameForLengthAndSlash(bucket, object); err != nil {
   156  		return err
   157  	}
   158  
   159  	// Validates object name validity after bucket exists.
   160  	if !IsValidObjectName(object) {
   161  		return ObjectNameInvalid{
   162  			Bucket: bucket,
   163  			Object: object,
   164  		}
   165  	}
   166  
   167  	return nil
   168  }
   169  
   170  // Checks for PutObject arguments validity.
   171  func checkPutObjectArgs(ctx context.Context, bucket, object string) error {
   172  	// Verify if bucket is valid.
   173  	if !isMinioMetaBucketName(bucket) && s3utils.CheckValidBucketNameStrict(bucket) != nil {
   174  		return BucketNameInvalid{Bucket: bucket}
   175  	}
   176  
   177  	if err := checkObjectNameForLengthAndSlash(bucket, object); err != nil {
   178  		return err
   179  	}
   180  	if len(object) == 0 ||
   181  		!IsValidObjectPrefix(object) {
   182  		return ObjectNameInvalid{
   183  			Bucket: bucket,
   184  			Object: object,
   185  		}
   186  	}
   187  	return nil
   188  }