Repository: mozilla/pdf.js
File: src/core/struct_tree.js (JavaScript)

Code before:
      }
    }
  }

  parseKid(pageObjId, kid) {
    // A direct link to content, the integer is an mcid.
    if (Number.isInteger(kid)) {
      if (this.tree.pageDict.objId !== pageObjId) {
        return null;
      }

      return new StructElement({
        type: StructElementType.PAGE_CONTENT,
        mcid: kid,
        pageObjId,
      });
    }

    // Find the dictionary for the kid.
    let kidDict = null;
    if (kid instanceof Ref) {
      kidDict = this.dict.xref.fetch(kid);
      // The kid can be a reference to a dictionary or a number (issue #19694).
      if (!(kidDict instanceof Dict)) {
        return this.parseKid(pageObjId, kidDict);
      }
    } else if (kid instanceof Dict) {
      kidDict = kid;
    }
    if (!kidDict) {
      return null;
    }
    const pageRef = kidDict.getRaw("Pg");
    if (pageRef instanceof Ref) {
      pageObjId = pageRef.toString();
    }

    const type =
      kidDict.get("Type") instanceof Name ? kidDict.get("Type").name : null;
    if (type === "MCR") {
      if (this.tree.pageDict.objId !== pageObjId) {
        return null;
      }
      const kidRef = kidDict.getRaw("Stm");
      return new StructElement({
        type: StructElementType.STREAM_CONTENT,
        refObjId: kidRef instanceof Ref ? kidRef.toString() : null,
        pageObjId,
        mcid: kidDict.get("MCID"),
      });
    }

Review comment (suggestion):
Not having seen the PDF document it's difficult to know for sure, however this seems to me like an unnecessarily roundabout way of fixing this; also we should really add a test-case for this.

Would the following diff perhaps fix this?
```diff
diff --git a/src/core/struct_tree.js b/src/core/struct_tree.js
index fa27a14c0..8b0c37ba5 100644
--- a/src/core/struct_tree.js
+++ b/src/core/struct_tree.js
@@ -565,7 +565,10 @@ class StructElementNode {
     const kids = this.dict.get("K");
     if (Array.isArray(kids)) {
       for (const kid of kids) {
-        const element = this.parseKid(pageObjId, kid);
+        const element = this.parseKid(
+          pageObjId,
+          this.dict.xref.fetchIfRef(kid)
+        );
         if (element) {
           this.kids.push(element);
         }
@@ -593,15 +596,11 @@ class StructElementNode {
     }

     // Find the dictionary for the kid.
-    let kidDict = null;
-    if (kid instanceof Ref) {
-      kidDict = this.dict.xref.fetch(kid);
-    } else if (kid instanceof Dict) {
-      kidDict = kid;
-    }
-    if (!kidDict) {
+    if (!(kid instanceof Dict)) {
       return null;
     }
+    const kidDict = kid;
+
     const pageRef = kidDict.getRaw("Pg");
     if (pageRef instanceof Ref) {
       pageObjId = pageRef.toString();
```



Code after:
      const element = this.parseKid(pageObjId, kids);
      if (element) {
        this.kids.push(element);
      }
    }
  }

  parseKid(pageObjId, kid) {
    // A direct link to content, the integer is an mcid.
    if (Number.isInteger(kid)) {
      if (this.tree.pageDict.objId !== pageObjId) {
        return null;
      }

      return new StructElement({
        type: StructElementType.PAGE_CONTENT,
        mcid: kid,
        pageObjId,
      });
    }

    if (!(kid instanceof Dict)) {
      return null;
    }

    const pageRef = kid.getRaw("Pg");
    if (pageRef instanceof Ref) {
      pageObjId = pageRef.toString();
    }

    const type = kid.get("Type") instanceof Name ? kid.get("Type").name : null;
    if (type === "MCR") {
      if (this.tree.pageDict.objId !== pageObjId) {
        return null;
      }
      const kidRef = kid.getRaw("Stm");
      return new StructElement({
        type: StructElementType.STREAM_CONTENT,
        refObjId: kidRef instanceof Ref ? kidRef.toString() : null,
        pageObjId,
        mcid: kid.get("MCID"),
      });
    }

    if (type === "OBJR") {
      if (this.tree.pageDict.objId !== pageObjId) {
        return null;
      }
      const kidRef = kid.getRaw("Obj");
      return new StructElement({
        type: StructElementType.OBJECT,