Skip to content

Commit 4b7a488

Browse files
committed
Fix a bug with parsing the list objects' CommonPrefixes that would result in the
response only containing the last common prefix instead of all of them. It was assuming there would only be a single <CommonPrefixes> element with multiple <Prefix> elements inside it. It now matches the S3 spec which is multiple <CommonPrefixes> elements each only containing a single <Prefix> element.
1 parent 91542d3 commit 4b7a488

File tree

1 file changed

+15
-19
lines changed

1 file changed

+15
-19
lines changed

src/ds3.c

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -863,32 +863,25 @@ static ds3_object _parse_object(xmlDocPtr doc, xmlNodePtr contents_node) {
863863
return object;
864864
}
865865

866-
struct common_prefixes {
867-
ds3_str** prefixes;
868-
uint64_t num_prefixes;
869-
};
870-
871-
static struct common_prefixes _parse_common_prefixes(xmlDocPtr doc, xmlNodePtr contents_node) {
866+
static ds3_str* _parse_common_prefixes(xmlDocPtr doc, xmlNodePtr contents_node) {
872867
xmlNodePtr child_node;
873-
GArray* prefix_array = g_array_new(FALSE, TRUE, sizeof(ds3_str*));
874-
struct common_prefixes prefixes;
875-
memset(&prefixes, 0, sizeof(struct common_prefixes));
868+
ds3_str* prefix = 0;
876869

877870
for(child_node = contents_node->xmlChildrenNode; child_node != NULL; child_node = child_node->next) {
878871
if(element_equal(child_node, "Prefix") == true) {
879-
ds3_str* prefix = xml_get_string(doc, child_node);
880-
g_array_append_val(prefix_array, prefix);
872+
if(prefix) {
873+
fprintf(stderr, "More than one Prefix found in CommonPrefixes\n");
874+
}
875+
else {
876+
prefix = xml_get_string(doc, child_node);
877+
}
881878
}
882879
else {
883880
fprintf(stderr, "Unknown xml element: %s\n", child_node->name);
884881
}
885882
}
886883

887-
prefixes.prefixes = (ds3_str**) prefix_array->data;
888-
prefixes.num_prefixes = prefix_array->len;
889-
g_array_free(prefix_array, FALSE);
890-
891-
return prefixes;
884+
return prefix;
892885
}
893886

894887
ds3_error* ds3_get_bucket(const ds3_client* client, const ds3_request* request, ds3_get_bucket_response** _response) {
@@ -898,6 +891,7 @@ ds3_error* ds3_get_bucket(const ds3_client* client, const ds3_request* request,
898891
xmlNodePtr child_node;
899892
xmlChar* text;
900893
GArray* object_array = g_array_new(FALSE, TRUE, sizeof(ds3_object));
894+
GArray* common_prefix_array = g_array_new(FALSE, TRUE, sizeof(ds3_str*));
901895
GByteArray* xml_blob = g_byte_array_new();
902896
_internal_request_dispatcher(client, request, xml_blob, load_buffer, NULL, NULL);
903897

@@ -993,9 +987,8 @@ ds3_error* ds3_get_bucket(const ds3_client* client, const ds3_request* request,
993987
xmlFree(text);
994988
}
995989
else if(element_equal(child_node, "CommonPrefixes") == true) {
996-
struct common_prefixes prefixes = _parse_common_prefixes(doc, child_node);
997-
response->common_prefixes = prefixes.prefixes;
998-
response->num_common_prefixes = prefixes.num_prefixes;
990+
ds3_str* prefix = _parse_common_prefixes(doc, child_node);
991+
g_array_append_val(common_prefix_array, prefix);
999992
}
1000993
else {
1001994
fprintf(stderr, "Unknown element: (%s)\n", child_node->name);
@@ -1004,8 +997,11 @@ ds3_error* ds3_get_bucket(const ds3_client* client, const ds3_request* request,
1004997

1005998
response->objects = (ds3_object*) object_array->data;
1006999
response->num_objects = object_array->len;
1000+
response->common_prefixes = (ds3_str**)common_prefix_array->data;
1001+
response->num_common_prefixes = common_prefix_array->len;
10071002
xmlFreeDoc(doc);
10081003
g_array_free(object_array, FALSE);
1004+
g_array_free(common_prefix_array, FALSE);
10091005
g_byte_array_free(xml_blob, TRUE);
10101006
*_response = response;
10111007
return NULL;

0 commit comments

Comments
 (0)