private async Task <PackageValidationResult> CheckReadmeMetadataAsync(PackageArchiveReader nuGetPackage, User user) { var nuspecReader = GetNuspecReader(nuGetPackage); var readmeElement = nuspecReader.ReadmeElement; if (readmeElement == null) { return(null); } var embeddedReadmeEnabled = _featureFlagService.AreEmbeddedReadmesEnabled(user); if (!embeddedReadmeEnabled) { return(PackageValidationResult.Invalid(Strings.UploadPackage_EmbeddedReadmeNotAccepted)); } if (HasChildElements(readmeElement)) { return(PackageValidationResult.Invalid(string.Format(Strings.UploadPackage_NodeContainsChildren, ReadmeNodeName))); } var readmeFilePath = FileNameHelper.GetZipEntryPath(readmeElement.Value); if (!FileExists(nuGetPackage, readmeFilePath)) { return(PackageValidationResult.Invalid( string.Format( Strings.UploadPackage_FileDoesNotExist, Strings.UploadPackage_ReadmeFileType, readmeFilePath))); } var readmeFileExtension = Path.GetExtension(readmeFilePath); if (!AllowedReadmeFileExtensions.Contains(readmeFileExtension, StringComparer.OrdinalIgnoreCase)) { var result = PackageValidationResult.Invalid( string.Format( Strings.UploadPackage_InvalidReadmeFileExtension, readmeFileExtension, string.Join(", ", AllowedReadmeFileExtensions.Where(x => x != string.Empty).Select(extension => $"'{extension}'")))); return(result); } var readmeFileEntry = nuGetPackage.GetEntry(readmeFilePath); if (readmeFileEntry.Length > MaxAllowedReadmeLengthForUploading) { return(PackageValidationResult.Invalid( string.Format( Strings.UploadPackage_FileTooLong, Strings.UploadPackage_ReadmeFileType, MaxAllowedReadmeLengthForUploading.ToUserFriendlyBytesLabel()))); } if (!await IsStreamLengthMatchesReportedAsync(nuGetPackage, readmeFilePath, readmeFileEntry.Length)) { return(PackageValidationResult.Invalid(Strings.UploadPackage_CorruptNupkg)); } // zip streams do not support seeking, so we'll have to reopen them using (var readmeFileStream = nuGetPackage.GetStream(readmeFilePath)) { // check if specified file is a text file if (!await TextHelper.LooksLikeUtf8TextStreamAsync(readmeFileStream)) { return(PackageValidationResult.Invalid(Strings.UploadPackage_ReadmeMustBePlainText)); } } return(null); }