Unverified Commit f810b1c3 authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

don't strip whitespace when reading XML data nodes (#590)

* don't strip whitespace when reading XML data nodes

smithy-xml had a bug that erroneously stripped whitespace when parsing data nodes. This created incorrect parsers when parsing keys that contained spaces. An S3 protocol test is included.

* Update CHANGELOG.md

* fix s3 list-objects
parent ea47391f
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
## vNext (Month Day Year)

**New This Week**
- :bug: Bugfix: Fix parsing bug where whitespace was stripped when parsing XML (#590)

## v0.15 (June 29th 2021)
This week, we've added EKS, ECR and Cloudwatch. The JSON deserialization implementation has been replaced, please be
on the lookout for potential issues.
+63 −0
Original line number Diff line number Diff line
@@ -38,6 +38,69 @@ apply GetBucketLocation @httpResponseTests([
    }
])

apply ListObjects @httpResponseTests([
    {
        id: "KeysWithWhitespace",
        documentation: "This test validates that parsing respects whitespace",
        code: 200,
        bodyMediaType: "application/xml",
        protocol: "aws.protocols#restXml",
        body: """
        <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n
        <ListBucketResult
        	xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">
        	<Name>bucketname</Name>
        	<Prefix></Prefix>
        	<Marker></Marker>
        	<MaxKeys>1000</MaxKeys>
        	<IsTruncated>false</IsTruncated>
        	<Contents>
        		<Key>    </Key>
        		<LastModified>2021-07-16T16:20:53.000Z</LastModified>
        		<ETag>&quot;etag123&quot;</ETag>
        		<Size>0</Size>
        		<Owner>
        			<ID>owner</ID>
        		</Owner>
        		<StorageClass>STANDARD</StorageClass>
        	</Contents>
        	<Contents>
        		<Key> a </Key>
        		<LastModified>2021-07-16T16:02:10.000Z</LastModified>
        		<ETag>&quot;etag123&quot;</ETag>
        		<Size>0</Size>
        		<Owner>
        			<ID>owner</ID>
        		</Owner>
        		<StorageClass>STANDARD</StorageClass>
        	</Contents>
        </ListBucketResult>
        """,
        params: {
            MaxKeys: 1000,
            IsTruncated: false,
            Marker: "",
            Name: "bucketname",
            Prefix: "",
            Contents: [{
                Key: "    ",
                LastModified: 1626452453,
                ETag: "\"etag123\"",
                Size: 0,
                Owner: { ID: "owner" },
                StorageClass: "STANDARD"
            }, {
               Key: " a ",
               LastModified: 1626451330,
               ETag: "\"etag123\"",
               Size: 0,
               Owner: { ID: "owner" },
               StorageClass: "STANDARD"
           }]
        }
    }
])

apply PutBucketLifecycleConfiguration @httpRequestTests([
    {
        id: "PutBucketLifecycleConfiguration",
+2 −2
Original line number Diff line number Diff line
@@ -164,10 +164,10 @@ fun discoverServices(allServices: Boolean, generateOnly: Set<String>): List<AwsS
        val inTier1 = generateOnly.isEmpty() && tier1Services.contains(it.module)
        allServices || inGenerateOnly || inTier1
    }
    if (generateOnly.isNotEmpty()) {
    if (generateOnly.isEmpty()) {
        val modules = services.map { it.module }.toSet()
        tier1Services.forEach { service ->
            check(modules.contains(service)) { "Service $service was in list of tier 1 services but not generated!" }
            check(modules.contains(service)) { "Service $service was in list of tier 1 services but not generated! ($generateOnly)" }
        }
    }
    return services
+13 −16
Original line number Diff line number Diff line
@@ -7,11 +7,10 @@ use std::process;

use s3::{Client, Config, Region};

use aws_types::region::ProvideRegion;
use aws_types::region;

use aws_types::region::ProvideRegion;
use structopt::StructOpt;
use tracing_subscriber::fmt::format::FmtSpan;
use tracing_subscriber::fmt::SubscriberBuilder;

#[derive(Debug, StructOpt)]
struct Opt {
@@ -44,23 +43,21 @@ async fn main() {
        verbose,
    } = Opt::from_args();

    let region = default_region
        .as_ref()
        .map(|region| Region::new(region.clone()))
        .or_else(|| aws_types::region::default_provider().region())
        .unwrap_or_else(|| Region::new("us-west-2"));
    let region = region::ChainProvider::first_try(default_region.map(Region::new))
        .or_default_provider()
        .or_else(Region::new("us-west-2"));

    tracing_subscriber::fmt::init();

    if verbose {
        println!("S3 client version: {}", s3::PKG_VERSION);
        println!("Region:            {:?}", &region);

        SubscriberBuilder::default()
            .with_env_filter("info")
            .with_span_events(FmtSpan::CLOSE)
            .init();
        println!(
            "Region:            {:?}",
            region.region().expect("region must be set")
        );
    }

    let config = Config::builder().region(&region).build();
    let config = Config::builder().region(region).build();

    let client = Client::from_conf(config);

@@ -68,7 +65,7 @@ async fn main() {
        Ok(resp) => {
            println!("Objects:");
            for object in resp.contents.unwrap_or_default() {
                println!(" {}", object.key.expect("objects have keys"));
                println!(" `{}`", object.key.expect("objects have keys"));
            }
        }
        Err(e) => {
+2 −1
Original line number Diff line number Diff line
@@ -157,8 +157,9 @@ fn is_list(node: Node) -> bool {
fn non_empty_children<'a, 'input: 'a>(
    node: Node<'a, 'input>,
) -> impl Iterator<Item = Node<'a, 'input>> {
    let single_child = node.children().count() == 1;
    node.children()
        .filter(|c| !c.is_text() || !c.text().unwrap().trim().is_empty())
        .filter(move |c| single_child || !c.is_text() || !c.text().unwrap().trim().is_empty())
}

#[cfg(test)]
Loading