Skip to content

Commit ca39326

Browse files
authored
feat: Validate docName and seriesInfo value for I-D (#1116)
* refactor: Remove redundant import * refactor: Remove an obsolete warning * feat: Validate docName and seriesInfo value for I-D Fixes #1115
1 parent 312b01a commit ca39326

File tree

2 files changed

+99
-19
lines changed

2 files changed

+99
-19
lines changed

test.py

+76-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from xml2rfc.boilerplate_rfc_7841 import boilerplate_rfc_status_of_memo
1212
from xml2rfc.walkpdf import xmldoc
13-
from xml2rfc.writers.base import default_options
13+
from xml2rfc.writers.base import default_options, BaseV3Writer, RfcWriterError
1414
from xml2rfc.writers.text import MAX_WIDTH
1515

1616
try:
@@ -697,6 +697,81 @@ def test_render_reference(self):
697697
self.assertEqual(len(lines), 2)
698698
self.assertIn(url, lines[1].text)
699699

700+
class BaseV3WriterTest(unittest.TestCase):
701+
'''BaseV3Writer tests'''
702+
703+
def setUp(self):
704+
xml2rfc.log.quiet = True
705+
path = 'tests/input/elements.xml'
706+
self.parser = xml2rfc.XmlRfcParser(path,
707+
quiet=True,
708+
options=default_options,
709+
**options_for_xmlrfcparser)
710+
self.xmlrfc = self.parser.parse()
711+
self.writer = BaseV3Writer(self.xmlrfc, quiet=True)
712+
713+
def test_validate_draft_name(self):
714+
# Valid documents
715+
valid_docs = []
716+
valid_docs.append(lxml.etree.fromstring('''
717+
<rfc
718+
number="9280"
719+
docName = "draft-ietf-foo-bar-23"
720+
ipr="trust200902"
721+
submissionType="editorial"
722+
category="info">
723+
<link href="https://datatracker.ietf.org/doc/draft-ietf-foo-bar-23" rel="prev"/>
724+
<front>
725+
<seriesInfo name="RFC" value="9280" stream="IETF" />
726+
</front>
727+
</rfc>'''))
728+
valid_docs.append(lxml.etree.fromstring('''
729+
<rfc
730+
docName = "draft-ietf-foo-bar-23"
731+
ipr="trust200902"
732+
submissionType="editorial"
733+
category="info">
734+
<front>
735+
<seriesInfo name="Internet-Draft" value="draft-ietf-foo-bar-23" />
736+
</front>
737+
</rfc>'''))
738+
valid_docs.append(lxml.etree.fromstring('''
739+
<rfc
740+
docName = "draft-ietf-foo-bar-23"
741+
ipr="trust200902"
742+
submissionType="editorial"
743+
category="info">
744+
<front>
745+
</front>
746+
</rfc>'''))
747+
valid_docs.append(lxml.etree.fromstring('''
748+
<rfc
749+
ipr="trust200902"
750+
submissionType="editorial"
751+
category="info">
752+
<front>
753+
<seriesInfo name="Internet-Draft" value="draft-ietf-foo-bar-23" />
754+
</front>
755+
</rfc>'''))
756+
for valid_doc in valid_docs:
757+
self.writer.root = valid_doc
758+
self.assertTrue(self.writer.validate_draft_name())
759+
760+
# Invalid document
761+
invalid_doc = lxml.etree.fromstring('''
762+
<rfc
763+
docName = "draft-ietf-foo-bar-23"
764+
ipr="trust200902"
765+
submissionType="editorial"
766+
category="info">
767+
<front>
768+
<seriesInfo name="Internet-Draft" value="draft-ietf-foo-bar-3" />
769+
</front>
770+
</rfc>''')
771+
self.writer.root = invalid_doc
772+
with self.assertRaises(RfcWriterError):
773+
self.writer.validate_draft_name()
774+
700775

701776
if __name__ == '__main__':
702777
unittest.main()

xml2rfc/writers/base.py

+23-18
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import copy
88
import datetime
99
import textwrap
10-
import lxml
1110
import os
1211
import re
1312
import xml2rfc.log
@@ -1057,7 +1056,7 @@ def write_section_rec(self, section, count_str="1.", appendix=False,
10571056
p_count = 1 # Paragraph counter
10581057
for element in section:
10591058
# Check for a PI
1060-
if element.tag is lxml.etree.PI:
1059+
if element.tag is etree.PI:
10611060
pidict = self.parse_pi(element)
10621061
if pidict and "needLines" in pidict:
10631062
self.needLines(pidict["needLines"])
@@ -1297,7 +1296,7 @@ def _build_index(self):
12971296
if 'anchor' in ref.attrib:
12981297
self._indexRef(ref_counter, title=title.text, anchor=ref.attrib["anchor"])
12991298
else:
1300-
raise RfcWriterError("Reference is missing an anchor: %s" % lxml.etree.tostring(ref))
1299+
raise RfcWriterError("Reference is missing an anchor: %s" % etree.tostring(ref))
13011300

13021301
# Appendix sections
13031302
back = self.r.find('back')
@@ -1646,7 +1645,7 @@ def write_to_file(self, file):
16461645

16471646
v3_rnc_file = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data', 'v3.rnc')
16481647
v3_rng_file = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'data', 'v3.rng')
1649-
v3_schema = lxml.etree.ElementTree(file=v3_rng_file)
1648+
v3_schema = etree.ElementTree(file=v3_rng_file)
16501649

16511650
def get_element_tags():
16521651
tags = set()
@@ -1733,7 +1732,7 @@ def __init__(self, xmlrfc, quiet=None, options=default_options, date=None):
17331732
self.date = date if date is not None else datetime.date.today()
17341733
self.v3_rnc_file = v3_rnc_file
17351734
self.v3_rng_file = v3_rng_file
1736-
self.v3_rng = lxml.etree.RelaxNG(file=self.v3_rng_file)
1735+
self.v3_rng = etree.RelaxNG(file=self.v3_rng_file)
17371736
self.v3_schema = v3_schema
17381737
self.schema = v3_schema
17391738
self.index_items = []
@@ -1780,21 +1779,21 @@ def get_relevant_pis(self, e):
17801779
if e != None:
17811780
# directly inside element
17821781
for c in e.getchildren():
1783-
if c.tag == lxml.etree.PI and c.target == xml2rfc.V3_PI_TARGET:
1782+
if c.tag == etree.PI and c.target == xml2rfc.V3_PI_TARGET:
17841783
pis.append(c)
17851784
# siblings before element
17861785
for s in e.itersiblings(preceding=True):
1787-
if s.tag == lxml.etree.PI and s.target == xml2rfc.V3_PI_TARGET:
1786+
if s.tag == etree.PI and s.target == xml2rfc.V3_PI_TARGET:
17881787
pis.append(s)
17891788
# ancestor's earlier siblings
17901789
for a in e.iterancestors():
17911790
for s in a.itersiblings(preceding=True):
1792-
if s.tag == lxml.etree.PI and s.target == xml2rfc.V3_PI_TARGET:
1791+
if s.tag == etree.PI and s.target == xml2rfc.V3_PI_TARGET:
17931792
pis.append(s)
17941793
# before root elements
17951794
p = self.root.getprevious()
17961795
while p != None:
1797-
if p.tag == lxml.etree.PI and p.target == xml2rfc.V3_PI_TARGET:
1796+
if p.tag == etree.PI and p.target == xml2rfc.V3_PI_TARGET:
17981797
pis.append(p)
17991798
p = p.getprevious()
18001799
return pis
@@ -2045,9 +2044,9 @@ def pretty_print_prep(self, e, p):
20452044
ind = self.options.indent
20462045
## The actual printing is done in self.write()
20472046
def indent(e, i):
2048-
if e.tag in (lxml.etree.CDATA, ):
2047+
if e.tag in (etree.CDATA, ):
20492048
return
2050-
if e.tag in (lxml.etree.Comment, lxml.etree.PI, ):
2049+
if e.tag in (etree.Comment, etree.PI, ):
20512050
if not e.tail:
20522051
if e.getnext() != None:
20532052
e.tail = '\n'+' '*i
@@ -2128,13 +2127,6 @@ def validate(self, when='', warn=False):
21282127
self.v3_rng.assertValid(tree)
21292128
return True
21302129
except Exception as e:
2131-
lxmlver = lxml.etree.LXML_VERSION[:3]
2132-
if lxmlver < (3, 8, 0):
2133-
self.warn(None, "The available version of the lxml library (%s) does not provide xpath "
2134-
"information as part of validation errors. Upgrade to version 3.8.0 or "
2135-
"higher for better error messages." % ('.'.join(str(v) for v in lxmlver), ))
2136-
# These warnings are occasionally incorrect -- disable this
2137-
# output for now:
21382130
deadly = False
21392131
if hasattr(e, 'error_log'):
21402132
for error in e.error_log:
@@ -2166,6 +2158,19 @@ def validate_before(self, e, p):
21662158
if not self.validate('before'):
21672159
self.note(None, "Schema validation failed for input document")
21682160

2161+
self.validate_draft_name()
2162+
2163+
def validate_draft_name(self):
2164+
if not self.root.attrib.get('number', False):
2165+
docName = self.root.attrib.get('docName', None)
2166+
info = self.root.find('./front/seriesInfo[@name="Internet-Draft"]')
2167+
si_draft_name = info.get('value') if info != None else None
2168+
2169+
if all([docName, si_draft_name]) and docName != si_draft_name:
2170+
self.die(self.root, 'docName and value in <seriesInfo name="Internet-Draft" ..> must match.')
2171+
2172+
return True
2173+
21692174
def validate_after(self, e, p):
21702175
# XXX: There is an issue with exponential increase in validation time
21712176
# as a function of the number of attributes on the root element, on

0 commit comments

Comments
 (0)