Repository: tefra/xsdata
Pull request #875 (2023-12-08 04:13:45)

Enable validation when decoding base64 data
## 📒 Description

Enables validation on calls to `base64.b64decode()` so that both base16 and base64 will raise a `ConverterError` if invalid characters are decoded.


Resolves #874

## 🔗 What I've Done

Pass `validate=True` to `b64decode()` method. Also implemented a unit test to exercise the behavior.


## 💬 Comments

None

## 🛫 Checklist

- [ ] Updated docs
- [x] Added unit-tests
- [ ] [Sample tests](https://github.com/tefra/xsdata-samples) pass
- [ ] [W3C tests](https://github.com/tefra/xsdata-w3c-tests) pass


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=tefra_xsdata&pullRequest=875)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=875&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=875&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=875&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=875&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=875&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=875&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=875&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=875&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=tefra_xsdata&pullRequest=875&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=875&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=875&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=tefra_xsdata&pullRequest=875&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=875) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=875&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=tefra_xsdata&pullRequest=875&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/xsdata/formats/converter.py b/xsdata/formats/converter.py
index 521fadd7..02a069c6 100644
--- a/xsdata/formats/converter.py
+++ b/xsdata/formats/converter.py
@@ -295,7 +295,7 @@ class BytesConverter(Converter):
                 return binascii.unhexlify(value)
 
             if fmt == "base64":
-                return base64.b64decode(value)
+                return base64.b64decode(value, validate=True)
 
             raise ConverterError(f"Unknown format '{fmt}'")
         except ValueError as e:


Test patch:
diff --git a/tests/formats/test_converter.py b/tests/formats/test_converter.py
index 0519ff50..dea0046e 100644
--- a/tests/formats/test_converter.py
+++ b/tests/formats/test_converter.py
@@ -223,6 +223,9 @@ class BytesConverterTests(TestCase):
         with self.assertRaises(ConverterError):
             self.converter.deserialize("aaa", format="base16")
 
+        with self.assertRaises(ConverterError):
+            self.converter.deserialize("AA~AA", format="base64")
+
     def test_unknown_formats(self):
         with self.assertRaises(ConverterError):
             self.converter.serialize("foo")