|
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml;
using Newtonsoft.Json;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using NuGet.Protocol.Core.Types;
namespace NuGet.Protocol
{
public static class HttpStreamValidation
{
public static void ValidateJObject(string uri, Stream stream)
{
if (uri == null)
{
throw new ArgumentNullException(nameof(uri));
}
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
try
{
using (var reader = new StreamReader(
stream: stream,
encoding: Encoding.UTF8,
detectEncodingFromByteOrderMarks: false,
bufferSize: 4096,
leaveOpen: true))
using (var jsonReader = new JsonTextReader(reader) { CloseInput = false })
{
var firstTokenFound = jsonReader.Read();
if (!firstTokenFound || jsonReader.TokenType != JsonToken.StartObject)
{
throw new JsonReaderException("The JSON document is not an object.");
}
while (jsonReader.Read())
{
}
if (jsonReader.Depth != 0)
{
throw new JsonReaderException("The JSON document is not complete.");
}
}
}
catch (Exception e) when (!(e is InvalidDataException))
{
string message = string.Format(
CultureInfo.CurrentCulture,
Strings.Protocol_InvalidJsonObject,
uri);
throw new InvalidDataException(message, e);
}
}
public static void ValidateNupkg(string uri, Stream stream)
{
if (uri == null)
{
throw new ArgumentNullException(nameof(uri));
}
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
try
{
using (var reader = new PackageArchiveReader(
stream: stream,
leaveStreamOpen: true))
using (var nuspec = reader.GetNuspec()) // This method throws if no .nuspec exists.
{
_ = new NuspecReader(nuspec); // This method throws if reading the .nuspec fails
}
}
catch (Exception e)
{
string message = string.Format(
CultureInfo.CurrentCulture,
Strings.Log_InvalidNupkgFromUrl,
uri);
throw new InvalidDataException(message, e);
}
}
internal static void ValidatePackageIdentity(string uri, Stream stream, PackageIdentity expectedIdentity)
{
if (uri == null)
{
throw new ArgumentNullException(nameof(uri));
}
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
if (expectedIdentity == null)
{
throw new ArgumentNullException(nameof(expectedIdentity));
}
try
{
using (var reader = new PackageArchiveReader(
stream: stream,
leaveStreamOpen: true))
{
using (var nuspecStream = reader.GetNuspec())
{
var nuspec = new NuspecReader(nuspecStream);
var actualIdentity = nuspec.GetIdentity();
if (!PackageIdentityComparer.Default.Equals(expectedIdentity, actualIdentity))
{
string message = string.Format(
CultureInfo.InvariantCulture,
Strings.Error_PackageIdentityDoesNotMatch,
expectedIdentity.Id,
expectedIdentity.Version,
actualIdentity.Id,
actualIdentity.Version);
throw new FatalProtocolException(message);
}
}
}
}
catch (Exception e)
{
string message = string.Format(
CultureInfo.CurrentCulture,
Strings.Log_InvalidNupkgFromUrl,
uri);
throw new InvalidDataException(message, e);
}
}
public static void ValidateXml(string uri, Stream stream)
{
if (uri == null)
{
throw new ArgumentNullException(nameof(uri));
}
if (stream == null)
{
throw new ArgumentNullException(nameof(stream));
}
try
{
using (var xmlReader = XmlReader.Create(
input: stream,
settings: new XmlReaderSettings { CloseInput = false }))
{
while (xmlReader.Read())
{
}
if (xmlReader.Depth != 0)
{
throw new JsonReaderException("The XML document is not complete.");
}
}
}
catch (Exception e)
{
var message = string.Format(
CultureInfo.CurrentCulture,
Strings.Protocol_InvalidXml,
uri);
throw new InvalidDataException(message, e);
}
}
}
}
|