diff --git a/cyclonedx/model/__init__.py b/cyclonedx/model/__init__.py
index 3ac988db..6b77dbb7 100644
--- a/cyclonedx/model/__init__.py
+++ b/cyclonedx/model/__init__.py
@@ -689,6 +689,8 @@ class XsUri(serializable.helpers.BaseHelper):
__SPEC_REPLACEMENTS = (
(' ', '%20'),
+ ('"', '%22'),
+ ("'", '%27'),
('[', '%5B'),
(']', '%5D'),
('<', '%3C'),
diff --git a/tests/_data/models.py b/tests/_data/models.py
index ab1805eb..963b1743 100644
--- a/tests/_data/models.py
+++ b/tests/_data/models.py
@@ -1213,7 +1213,14 @@ def get_bom_for_issue_497_urls() -> Bom:
ExternalReference(
type=ExternalReferenceType.OTHER,
comment='control characters',
- url=XsUri('https://acme.org/?foo=sp ace&bar[23]=42<=1<2>=3>2&cb={lol}')
+ url=XsUri('https://acme.org/?'
+ 'foo=sp ace&'
+ 'bar[23]=42&'
+ 'lt=1<2&'
+ 'gt=3>2&'
+ 'cb={lol}&'
+ 'quote="test"is\'test\''
+ )
),
ExternalReference(
type=ExternalReferenceType.OTHER,
diff --git a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.1.xml.bin b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.1.xml.bin
index d006b51e..6506e2bf 100644
--- a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.1.xml.bin
+++ b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.1.xml.bin
@@ -14,7 +14,7 @@
pre-encoded
- https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D
+ https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"e=%22test%22is%27test%27
control characters
diff --git a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.2.json.bin b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.2.json.bin
index aa874e99..af420942 100644
--- a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.2.json.bin
+++ b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.2.json.bin
@@ -16,7 +16,7 @@
{
"comment": "control characters",
"type": "other",
- "url": "https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"
+ "url": "https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"e=%22test%22is%27test%27"
}
],
"name": "dummy",
diff --git a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.2.xml.bin b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.2.xml.bin
index edf73273..659778ba 100644
--- a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.2.xml.bin
+++ b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.2.xml.bin
@@ -17,7 +17,7 @@
pre-encoded
- https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D
+ https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"e=%22test%22is%27test%27
control characters
diff --git a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.3.json.bin b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.3.json.bin
index 625c6a9e..1eba574f 100644
--- a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.3.json.bin
+++ b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.3.json.bin
@@ -16,7 +16,7 @@
{
"comment": "control characters",
"type": "other",
- "url": "https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"
+ "url": "https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"e=%22test%22is%27test%27"
}
],
"name": "dummy",
diff --git a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.3.xml.bin b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.3.xml.bin
index e6af9f05..eb950283 100644
--- a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.3.xml.bin
+++ b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.3.xml.bin
@@ -17,7 +17,7 @@
pre-encoded
- https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D
+ https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"e=%22test%22is%27test%27
control characters
diff --git a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.4.json.bin b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.4.json.bin
index 09ad3d10..f715c57a 100644
--- a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.4.json.bin
+++ b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.4.json.bin
@@ -16,7 +16,7 @@
{
"comment": "control characters",
"type": "other",
- "url": "https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"
+ "url": "https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"e=%22test%22is%27test%27"
}
],
"name": "dummy",
diff --git a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.4.xml.bin b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.4.xml.bin
index 264d4286..0364698a 100644
--- a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.4.xml.bin
+++ b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.4.xml.bin
@@ -16,7 +16,7 @@
pre-encoded
- https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D
+ https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"e=%22test%22is%27test%27
control characters
diff --git a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.5.json.bin b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.5.json.bin
index aa21468f..60a822f1 100644
--- a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.5.json.bin
+++ b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.5.json.bin
@@ -16,7 +16,7 @@
{
"comment": "control characters",
"type": "other",
- "url": "https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"
+ "url": "https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"e=%22test%22is%27test%27"
}
],
"name": "dummy",
diff --git a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.5.xml.bin b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.5.xml.bin
index 62049bdc..f947d6ce 100644
--- a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.5.xml.bin
+++ b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.5.xml.bin
@@ -16,7 +16,7 @@
pre-encoded
- https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D
+ https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"e=%22test%22is%27test%27
control characters
diff --git a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.6.json.bin b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.6.json.bin
index b07192c6..4336a31c 100644
--- a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.6.json.bin
+++ b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.6.json.bin
@@ -16,7 +16,7 @@
{
"comment": "control characters",
"type": "other",
- "url": "https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"
+ "url": "https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"e=%22test%22is%27test%27"
}
],
"name": "dummy",
diff --git a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.6.xml.bin b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.6.xml.bin
index b780c8cf..c7fee449 100644
--- a/tests/_data/snapshots/get_bom_for_issue_497_urls-1.6.xml.bin
+++ b/tests/_data/snapshots/get_bom_for_issue_497_urls-1.6.xml.bin
@@ -16,7 +16,7 @@
pre-encoded
- https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D
+ https://acme.org/?foo=sp%20ace&bar%5B23%5D=42<=1%3C2>=3%3E2&cb=%7Blol%7D"e=%22test%22is%27test%27
control characters