Repository: mozilla/pdf.js
File: src/display/annotation_layer.js (JavaScript)

Code before:

    const popupToElements = new Map();
    const elementParams = {
      data: null,
      layer,
      linkService: params.linkService,
      downloadManager: params.downloadManager,
      imageResourcesPath: params.imageResourcesPath || "",
      renderForms: params.renderForms !== false,
      svgFactory: new DOMSVGFactory(),
      annotationStorage: params.annotationStorage || new AnnotationStorage(),
      enableScripting: params.enableScripting === true,
      hasJSActions: params.hasJSActions,
      fieldObjects: params.fieldObjects,
      parent: this,
      elements: null,
    };

    for (const data of annotations) {
      if (data.noHTML) {
        continue;
      }
      const isPopupAnnotation = data.annotationType === AnnotationType.POPUP;
      if (!isPopupAnnotation) {
        const { width, height } = getRectDims(data.rect);
        if (width <= 0 || height <= 0) {
          continue; // Ignore empty annotations.
        }
      } else {
        const elements = popupToElements.get(data.id);
        if (!elements) {
          // Ignore popup annotations without a corresponding annotation.
          continue;
        }
        elementParams.elements = elements;
      }
      elementParams.data = data;
      const element = AnnotationElementFactory.create(elementParams);

      if (!element.isRenderable) {
        continue;
      }

      if (!isPopupAnnotation && data.popupRef) {
        const elements = popupToElements.get(data.popupRef);
        if (!elements) {
          popupToElements.set(data.popupRef, [element]);
        } else {
          elements.push(element);
        }
      }

Review comment (bug):
This code also handles negative widths/heights, which I assume is to handle cases where the rectangle data is incorrect such that a subtraction would lead to a negative number. However, I'm not sure if we have actually seen such cases or if this code is just defensive. In any case, is this something the new code should also handle or is it not really a concern?

Code after:
      svgFactory: new DOMSVGFactory(),
      annotationStorage: params.annotationStorage || new AnnotationStorage(),
      enableScripting: params.enableScripting === true,
      hasJSActions: params.hasJSActions,
      fieldObjects: params.fieldObjects,
      parent: this,
      elements: null,
    };

    for (const data of annotations) {
      if (data.noHTML) {
        continue;
      }
      const isPopupAnnotation = data.annotationType === AnnotationType.POPUP;
      if (!isPopupAnnotation) {
        if (data.rect[2] === data.rect[0] || data.rect[3] === data.rect[1]) {
          continue; // Ignore empty annotations.
        }
      } else {
        const elements = popupToElements.get(data.id);
        if (!elements) {
          // Ignore popup annotations without a corresponding annotation.
          continue;
        }
        elementParams.elements = elements;
      }
      elementParams.data = data;
      const element = AnnotationElementFactory.create(elementParams);

      if (!element.isRenderable) {
        continue;
      }

      if (!isPopupAnnotation && data.popupRef) {
        const elements = popupToElements.get(data.popupRef);
        if (!elements) {
          popupToElements.set(data.popupRef, [element]);
        } else {
          elements.push(element);
        }
      }

      const rendered = element.render();
      if (data.hidden) {
        rendered.style.visibility = "hidden";
      }
      await this.#appendElement(rendered, data.id);

      if (element._isEditable) {
        this.#editableAnnotations.set(element.data.id, element);
        this._annotationEditorUIManager?.renderAnnotationElement(element);