summary refs log tree commit diff stats
path: root/lib/packages
diff options
context:
space:
mode:
authorAndrey Makarov <ph.makarov@gmail.com>2021-06-20 21:00:42 +0300
committerGitHub <noreply@github.com>2021-06-20 20:00:42 +0200
commit1b3c0f142dd5abc3b3509feb194f54e6acf046c0 (patch)
treea4c896ae387e3a36d3e6b4162528302378897a94 /lib/packages
parent7d5e6b0169fb83c7682bfad5d675c21db785c324 (diff)
downloadNim-1b3c0f142dd5abc3b3509feb194f54e6acf046c0.tar.gz
validate rst field for :number-lines:, :status: (#18304)
Diffstat (limited to 'lib/packages')
-rw-r--r--lib/packages/docutils/rst.nim1
-rw-r--r--lib/packages/docutils/rstgen.nim30
2 files changed, 23 insertions, 8 deletions
diff --git a/lib/packages/docutils/rst.nim b/lib/packages/docutils/rst.nim
index 031a86d98..64910aa19 100644
--- a/lib/packages/docutils/rst.nim
+++ b/lib/packages/docutils/rst.nim
@@ -225,6 +225,7 @@ type
     meNewSectionExpected = "new section expected $1",
     meGeneralParseError = "general parse error",
     meInvalidDirective = "invalid directive: '$1'",
+    meInvalidRstField = "invalid field: $1",
     meFootnoteMismatch = "mismatch in number of footnotes and their refs: $1",
     mwRedefinitionOfLabel = "redefinition of label '$1'",
     mwUnknownSubstitution = "unknown substitution '$1'",
diff --git a/lib/packages/docutils/rstgen.nim b/lib/packages/docutils/rstgen.nim
index e3f889283..829177263 100644
--- a/lib/packages/docutils/rstgen.nim
+++ b/lib/packages/docutils/rstgen.nim
@@ -907,6 +907,25 @@ proc renderSmiley(d: PDoc, n: PRstNode, result: var string) =
     "\\includegraphics{$1}",
     [d.config.getOrDefault"doc.smiley_format" % n.text])
 
+proc getField1Int(d: PDoc, n: PRstNode, fieldName: string): int =
+  # TODO: proper column/line info
+  template err(msg: string) =
+    d.msgHandler(d.filename, 1, 0, meInvalidRstField, msg)
+  let value = n.getFieldValue
+  var number: int
+  let nChars = parseInt(value, number)
+  if nChars == 0:
+    if value.len == 0:
+      err("field $1 requires an argument" % [fieldName])
+    else:
+      err("field $1 requires an integer, but '$2' was given" %
+          [fieldName, value])
+  elif nChars < value.len:
+    err("extra arguments were given to $1: '$2'" %
+        [fieldName, value[nChars..^1]])
+  else:
+    result = number
+
 proc parseCodeBlockField(d: PDoc, n: PRstNode, params: var CodeBlockParams) =
   ## Parses useful fields which can appear before a code block.
   ##
@@ -916,9 +935,7 @@ proc parseCodeBlockField(d: PDoc, n: PRstNode, params: var CodeBlockParams) =
   of "number-lines":
     params.numberLines = true
     # See if the field has a parameter specifying a different line than 1.
-    var number: int
-    if parseInt(n.getFieldValue, number) > 0:
-      params.startLine = number
+    params.startLine = getField1Int(d, n, "number-lines")
   of "file", "filename":
     # The ``file`` option is a Nim extension to the official spec, it acts
     # like it would for other directives like ``raw`` or ``cvs-table``. This
@@ -936,9 +953,7 @@ proc parseCodeBlockField(d: PDoc, n: PRstNode, params: var CodeBlockParams) =
       # consider whether `$docCmd` should be appended here too
       params.testCmd = unescape(params.testCmd)
   of "status", "exitcode":
-    var status: int
-    if parseInt(n.getFieldValue, status) > 0:
-      params.status = status
+    params.status = getField1Int(d, n, n.getArgument)
   of "default-language":
     params.langStr = n.getFieldValue.strip
     params.lang = params.langStr.getSourceLanguage
@@ -954,7 +969,6 @@ proc parseCodeBlockParams(d: PDoc, n: PRstNode): CodeBlockParams =
   if n.isNil:
     return
   assert n.kind in {rnCodeBlock, rnInlineCode}
-  assert(not n.sons[2].isNil)
 
   # Parse the field list for rendering parameters if there are any.
   if not n.sons[1].isNil:
@@ -1028,8 +1042,8 @@ proc renderCode(d: PDoc, n: PRstNode, result: var string) =
   ## option to differentiate between a plain code block and Nim's code block
   ## extension.
   assert n.kind in {rnCodeBlock, rnInlineCode}
-  if n.sons[2] == nil: return
   var params = d.parseCodeBlockParams(n)
+  if n.sons[2] == nil: return
   var m = n.sons[2].sons[0]
   assert m.kind == rnLeaf