-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug fix for incomplete xml imports #2468
Changes from all commits
6a41a4d
a8925c0
b270027
477df31
dfd5f07
aea8207
218863e
6314b6a
9b4d804
1362429
875b805
610b5e6
feac68c
4e08636
34e3c8c
5b1a414
41f3c96
ff744f5
ddf05d3
da06d2c
2865224
911e8b3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
|
||
mslib.utils.verify_waypoint_data | ||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
||
basic checks for xml waypoint data. | ||
|
||
This file is part of MSS. | ||
|
||
:copyright: Copyright 2024 Reimar Bauer | ||
:license: APACHE-2.0, see LICENSE for details. | ||
|
||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
|
||
http://www.apache.org/licenses/LICENSE-2.0 | ||
|
||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
""" | ||
|
||
|
||
import defusedxml.minidom | ||
import xml.parsers.expat | ||
|
||
|
||
def verify_waypoint_data(xml_content): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could be an ideal use-case for XML Schemas. That would require more than the stdlib xml support though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is currently only a simple solution. A refactoring needs to be done too. |
||
try: | ||
doc = defusedxml.minidom.parseString(xml_content) | ||
except xml.parsers.expat.ExpatError: | ||
return False | ||
|
||
ft_el = doc.getElementsByTagName("FlightTrack")[0] | ||
waypoints = ft_el.getElementsByTagName("Waypoint") | ||
if (len(waypoints)) < 2: | ||
return False | ||
|
||
for wp_el in ft_el.getElementsByTagName("Waypoint"): | ||
try: | ||
wp_el.getAttribute("location") | ||
float(wp_el.getAttribute("lat")) | ||
float(wp_el.getAttribute("lon")) | ||
float(wp_el.getAttribute("flightlevel")) | ||
wp_el.getElementsByTagName("Comments")[0] | ||
except ValueError: | ||
return False | ||
|
||
return True |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,6 +32,7 @@ | |
from mslib.mscolab.models import User, Operation, Permission, Change, Message | ||
from mslib.mscolab.seed import add_user, get_user | ||
from mslib.mscolab.utils import get_recent_op_id | ||
from tests.utils import XML_CONTENT1, XML_CONTENT2, XML_CONTENT3 | ||
|
||
|
||
class Test_Files: | ||
|
@@ -94,25 +95,54 @@ def test_is_creator(self): | |
def test_file_save(self): | ||
with self.app.test_client(): | ||
flight_path, operation = self._create_operation(flight_path="operation77") | ||
assert self.fm.save_file(operation.id, "beta", self.user) | ||
assert self.fm.get_file(operation.id, self.user) == "beta" | ||
assert self.fm.save_file(operation.id, "gamma", self.user) | ||
assert self.fm.get_file(operation.id, self.user) == "gamma" | ||
assert self.fm.save_file(operation.id, XML_CONTENT1, self.user) | ||
assert self.fm.get_file(operation.id, self.user) == XML_CONTENT1 | ||
assert self.fm.save_file(operation.id, XML_CONTENT2, self.user) | ||
assert self.fm.get_file(operation.id, self.user) == XML_CONTENT2 | ||
# check if change is saved properly | ||
changes = self.fm.get_all_changes(operation.id, self.user) | ||
assert len(changes) == 2 | ||
|
||
def test_cant_save(self): | ||
with self.app.test_client(): | ||
flight_path, operation = self._create_operation(flight_path="operation911") | ||
assert self.fm.save_file(operation.id, "text", self.user) is False | ||
incomplete = """<?xml version="1.0" encoding="utf-8"?> | ||
<FlightTrack version="9.1.0"> | ||
<ListOfWaypoints/> | ||
</FlightTrack>""" | ||
assert self.fm.save_file(operation.id, incomplete, self.user) is False | ||
incomplete = """<?xml version="1.0" encoding="utf-8"?> | ||
<FlightTrack version="9.1.0."> | ||
<ListOfWaypoints> | ||
<Waypoint flightlevel="350"> | ||
<Comments></Comments> | ||
</Waypoint> | ||
<Waypoint flightlevel="350"> | ||
<Comments></Comments> | ||
</Waypoint> | ||
</ListOfWaypoints> | ||
</FlightTrack>""" | ||
assert self.fm.save_file(operation.id, incomplete, self.user) is False | ||
|
||
def test_stub_data(self): | ||
with self.app.test_client(): | ||
flight_path, operation = self._create_operation(flight_path="operationstub") | ||
content = self.fm.get_file(operation.id, self.user) | ||
assert flight_path == "operationstub" | ||
assert content == mscolab_settings.STUB_CODE | ||
|
||
def test_undo(self): | ||
with self.app.test_client(): | ||
flight_path, operation = self._create_operation(flight_path="operation7", content="alpha") | ||
assert self.fm.save_file(operation.id, "beta", self.user) | ||
assert self.fm.save_file(operation.id, "gamma", self.user) | ||
flight_path, operation = self._create_operation(flight_path="operation7", content=XML_CONTENT1) | ||
assert self.fm.save_file(operation.id, XML_CONTENT2, self.user) | ||
assert self.fm.save_file(operation.id, XML_CONTENT3, self.user) | ||
changes = Change.query.filter_by(op_id=operation.id).all() | ||
assert changes is not None | ||
assert changes[0].id == 1 | ||
assert self.fm.undo_changes(changes[0].id, self.user) is True | ||
assert len(self.fm.get_all_changes(operation.id, self.user)) == 3 | ||
assert "beta" in self.fm.get_file(operation.id, self.user) | ||
assert XML_CONTENT2 == self.fm.get_file(operation.id, self.user) | ||
|
||
def test_get_operation(self): | ||
with self.app.test_client(): | ||
|
@@ -156,8 +186,7 @@ def test_delete_operation(self): | |
assert len(messages) == 0 | ||
|
||
def _example_data(self): | ||
self.content1 = """\ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
self.content1 = """<?xml version="1.0" encoding="utf-8"?> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this was also giving an xml.parsers.expat.ExpatError |
||
<FlightTrack> | ||
<Name>new flight track (1)</Name> | ||
<ListOfWaypoints> | ||
|
@@ -178,8 +207,7 @@ def _example_data(self): | |
</Waypoint> | ||
</ListOfWaypoints> | ||
</FlightTrack>""" | ||
self.content2 = """\ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
self.content2 = """<?xml version="1.0" encoding="utf-8"?> | ||
<FlightTrack> | ||
<Name>new flight track (1)</Name> | ||
<ListOfWaypoints> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the intention is to protect against e.g. maliciously crafted XML or the like, then verification must be the first thing that is done, before using the XML for anything else. In this case though, the XML might be used already here:
MSS/mslib/msui/mscolab.py
Line 1971 in ff744f5
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, if
function
is not None, then that supplied function would need to do the verification as well. But this is a theoretical concern, it seems like for XML files it is always None, and it is only used to provide a way to read CSV files instead.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a users functions has to return name, waypoints e.g. https://github.com/Open-MSS/MSS/blob/develop/mslib/plugins/io/flitestar.py
How a user can test his functions is a different scope.