diff options
author | Lars Wirzenius <liw@liw.fi> | 2017-11-02 16:13:31 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2017-11-02 16:57:51 +0200 |
commit | ba16a904e153fc71f1537b588793659800c78b4c (patch) | |
tree | dc7076bc11804b242910a7710305874b06d96e5a | |
parent | 4fed1867dcd5343f5c7d53592a43b8595bfb777f (diff) | |
download | qvisqve-ba16a904e153fc71f1537b588793659800c78b4c.tar.gz |
Fix: flatten objects with same name, unorderable fields
Bug reported by Mantas. If a resource (or its prototype) has two
fields with the same name, but unorderable value types (such as string
and integer), the flatten_object function used to crash. This is now
fixed.
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | qvarn/objstore.py | 13 | ||||
-rw-r--r-- | qvarn/resource_type_tests.py | 1 | ||||
-rw-r--r-- | resource_type/files.yaml | 7 |
4 files changed, 24 insertions, 2 deletions
@@ -13,6 +13,11 @@ Bug fixes: resources, not just `foo`. This has been fixed. Bug reported by Kaius, fixed by Lars. +* Mantas reported that if a resource type or resource had two fields + with the same type but values that were not possible to compare, + such as a string and an integer, Qvarn would crash. This is now + fixed. + Version 0.86, released 2017-10-10 ---------------------------------- diff --git a/qvarn/objstore.py b/qvarn/objstore.py index 90d4e84..d88774e 100644 --- a/qvarn/objstore.py +++ b/qvarn/objstore.py @@ -386,7 +386,18 @@ class NoSuchObject(Exception): def flatten_object(obj): - return list(sorted(set(_flatten(obj)))) + # We sort only by the name, not the object in each pair in the + # list. Otherwise, if there are two fields with the same name but + # incompatible value types this will break. However, to guarantee + # that objects always result in the same flattened representation, + # we also compare the second field. For this, we convert the + # second value to a string with repr. This allows the second + # fields to be compared regardless of type. + + pairs = _flatten(obj) + unique_pairs = set(pairs) + sorted_pairs = sorted(unique_pairs, key=repr) + return list(sorted_pairs) def _flatten(obj, obj_key=None): diff --git a/qvarn/resource_type_tests.py b/qvarn/resource_type_tests.py index a1fd09a..36c775b 100644 --- a/qvarn/resource_type_tests.py +++ b/qvarn/resource_type_tests.py @@ -59,6 +59,7 @@ class ResourceTypeTests(unittest.TestCase): 'prototype': { 'foo': '', 'bar': '', + 'version': 0, # test for bug }, 'subpaths': { 'subfoo': { diff --git a/resource_type/files.yaml b/resource_type/files.yaml index 947b7f6..ef74217 100644 --- a/resource_type/files.yaml +++ b/resource_type/files.yaml @@ -4,7 +4,12 @@ versions: - prototype: {id: '', revision: '', type: ''} version: v0 - files: [file] - prototype: {filename: '', id: '', revision: '', type: ''} + prototype: + filename: '' + id: '' + revision: '' + type: '' + version: 0 subpaths: file: prototype: {body: blob, content_type: ''} |