about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNoah Lev <camelidcamel@gmail.com>2021-08-25 20:09:17 -0700
committerNoah Lev <camelidcamel@gmail.com>2021-08-25 20:09:17 -0700
commit4478ecc352d6f3f12c1cb4b9dd5e7e06762286ee (patch)
treeee5a8d865ca92a95b53447400046fb2e92a4bade
parentd932e62dd9a6137a831d0917aa80aefd7ff47018 (diff)
downloadrust-4478ecc352d6f3f12c1cb4b9dd5e7e06762286ee.tar.gz
rust-4478ecc352d6f3f12c1cb4b9dd5e7e06762286ee.zip
Don't panic if `close_tag()` is called without tags to close
This can happen when a tag is opened after the length limit is reached;
the tag will not end up being added to `unclosed_tags` because the queue
will never be flushed. So, now, if the `unclosed_tags` stack is empty,
`close_tag()` does nothing.

This change fixes a panic in the `limit_0` unit test.
-rw-r--r--src/librustdoc/html/length_limit.rs12
-rw-r--r--src/librustdoc/html/length_limit/tests.rs5
2 files changed, 14 insertions, 3 deletions
diff --git a/src/librustdoc/html/length_limit.rs b/src/librustdoc/html/length_limit.rs
index 28a207a84ba..bbdc91c8d2e 100644
--- a/src/librustdoc/html/length_limit.rs
+++ b/src/librustdoc/html/length_limit.rs
@@ -86,8 +86,16 @@ impl HtmlWithLimit {
 
     /// Close the most recently opened HTML tag.
     pub(super) fn close_tag(&mut self) {
-        let tag_name = self.unclosed_tags.pop().unwrap();
-        write!(self.buf, "</{}>", tag_name).unwrap();
+        match self.unclosed_tags.pop() {
+            // Close the most recently opened tag.
+            Some(tag_name) => write!(self.buf, "</{}>", tag_name).unwrap(),
+            // There are valid cases where `close_tag()` is called without
+            // there being any tags to close. For example, this occurs when
+            // a tag is opened after the length limit is exceeded;
+            // `flush_queue()` will never be called, and thus, the tag will
+            // not end up being added to `unclosed_tags`.
+            None => {}
+        }
     }
 
     /// Write all queued tags and add them to the `unclosed_tags` list.
diff --git a/src/librustdoc/html/length_limit/tests.rs b/src/librustdoc/html/length_limit/tests.rs
index 5a006d44d58..2d02b8a16da 100644
--- a/src/librustdoc/html/length_limit/tests.rs
+++ b/src/librustdoc/html/length_limit/tests.rs
@@ -107,11 +107,14 @@ fn quickly_past_the_limit() {
 }
 
 #[test]
-#[should_panic = "called `Option::unwrap()` on a `None` value"]
 fn close_too_many() {
     let mut buf = HtmlWithLimit::new(60);
     buf.open_tag("p");
     buf.push("Hello");
     buf.close_tag();
+    // This call does not panic because there are valid cases
+    // where `close_tag()` is called with no tags left to close.
+    // So `close_tag()` does nothing in this case.
     buf.close_tag();
+    assert_eq!(buf.finish(), "<p>Hello</p>");
 }