From ab77b216d1fd1cc404ba6006755dccb68c5e9adf Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Tue, 28 Apr 2020 17:32:46 -0700 Subject: [PATCH] fix: remove restrictions on windows for NAME_MAX (#9469) Fixes #9393 --- cmd/posix.go | 31 +++++++++++++------ cmd/posix_test.go | 29 ++++++++++++++++- .../{root-disk-unix.go => root_disk_unix.go} | 0 ...t-disk-windows.go => root_disk_windows.go} | 0 4 files changed, 49 insertions(+), 11 deletions(-) rename pkg/disk/{root-disk-unix.go => root_disk_unix.go} (100%) rename pkg/disk/{root-disk-windows.go => root_disk_windows.go} (100%) diff --git a/cmd/posix.go b/cmd/posix.go index 89606b840..5353c8440 100644 --- a/cmd/posix.go +++ b/cmd/posix.go @@ -108,20 +108,31 @@ func checkPathLength(pathName string) error { return errFileNameTooLong } - if runtime.GOOS == "windows" { - // Convert any '\' to '/'. - pathName = filepath.ToSlash(pathName) + // Disallow more than 1024 characters on windows, there + // are no known name_max limits on Windows. + if runtime.GOOS == "windows" && len(pathName) > 1024 { + return nil } - // Check each path segment length is > 255 - for len(pathName) > 0 && pathName != "." && pathName != SlashSeparator { - dir, file := slashpath.Dir(pathName), slashpath.Base(pathName) + // On Unix we reject paths if they are just '.', '..' or '/' + if pathName == "." || pathName == ".." || pathName == slashSeparator { + return errFileAccessDenied + } - if len(file) > 255 { - return errFileNameTooLong + // Check each path segment length is > 255 on all Unix + // platforms, look for this value as NAME_MAX in + // /usr/include/linux/limits.h + var count int64 + for _, p := range pathName { + switch p { + case '/': + count = 0 // Reset + default: + count++ + if count > 255 { + return errFileNameTooLong + } } - - pathName = dir } // Success. return nil } diff --git a/cmd/posix_test.go b/cmd/posix_test.go index c49e04cdf..9d0ae35e5 100644 --- a/cmd/posix_test.go +++ b/cmd/posix_test.go @@ -1,5 +1,5 @@ /* - * MinIO Cloud Storage, (C) 2016, 2017 MinIO, Inc. + * MinIO Cloud Storage, (C) 2016-2020 MinIO, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,33 @@ import ( "github.com/minio/minio/pkg/disk" ) +func TestCheckPathLength(t *testing.T) { + // Check path length restrictions are not same on windows/darwin + if runtime.GOOS == "windows" || runtime.GOOS == "darwin" { + t.Skip() + } + + testCases := []struct { + path string + expectedErr error + }{ + {".", errFileAccessDenied}, + {"/", errFileAccessDenied}, + {"..", errFileAccessDenied}, + {"data/G_792/srv-tse/c/users/denis/documents/gestion!20locative/heritier/propri!E9taire/20190101_a2.03!20-!20m.!20heritier!20re!B4mi!20-!20proce!60s-verbal!20de!20livraison!20et!20de!20remise!20des!20cle!B4s!20acque!B4reurs!20-!204-!20livraison!20-!20lp!20promotion!20toulouse!20-!20encre!20et!20plume!20-!205!20de!B4c.!202019!20a!60!2012-49.pdf.ecc", errFileNameTooLong}, + {"data/G_792/srv-tse/c/users/denis/documents/gestionlocative.txt", nil}, + } + + for _, testCase := range testCases { + gotErr := checkPathLength(testCase.path) + t.Run("", func(t *testing.T) { + if gotErr != testCase.expectedErr { + t.Errorf("Expected %s, got %s", testCase.expectedErr, gotErr) + } + }) + } +} + // Tests validate volume name. func TestIsValidVolname(t *testing.T) { testCases := []struct { diff --git a/pkg/disk/root-disk-unix.go b/pkg/disk/root_disk_unix.go similarity index 100% rename from pkg/disk/root-disk-unix.go rename to pkg/disk/root_disk_unix.go diff --git a/pkg/disk/root-disk-windows.go b/pkg/disk/root_disk_windows.go similarity index 100% rename from pkg/disk/root-disk-windows.go rename to pkg/disk/root_disk_windows.go