Skip to content

Fix browser freezing when PostgreSQL decides not to highlight any matches

Yuto Takano requested to merge fix-infinite-loop-search into master

Closes #386 (closed) .

Frontend entered an infinite loop in MarkdownText.addMarks when PostgreSQL decides to return search results from ts_query but doesn't highlight them when requesting ts_headline with the same query. This seems to happen on staging/prod databases and could not be replicated locally even when all data was copied, which leads me to believe it's a locale issue (my laptop is en_US for reference).

Example backend -> frontend response when searching for "bg" (see the "highlighted_words" field)

On staging/prod:


    {
      "text": "I'm not sure if 1 is correct. If we look at the linearity property of Fourier: For any complex numbers a and b, if h(x) = af(x) + bg(x), then \u0125(\u03be) = a \u00b7 f\u0302(\u03be) + b \u00b7 \u011d(\u03be). So it should be 2 \u00b7 F(u,v) and not 2 \u2217 F(u,v).\r\nAnd if we look at 2 as a constant function, then the DFT of c(x) = 2 isn't 2 but the dirac-delta impulse at 2. So this still doesn't make sense.",
      "long_id": "85iheehpj8j2ax5g",
      "rank": 0.06079271,
      "author_username": "barlasa",
      "author_displayname": "Ayseg\u00fcl Barlas",
      "highlighted_words": [
        "bg"
      ],
      "answer_long_id": "5c1d583729082200e37306e3",
      "exam_displayname": "FS10",
      "filename": "bdubehxd.pdf",
      "category_displayname": "Visual Computing",
      "category_slug": "VisualComputing",
      "type": "comment"
    },
    {
      "text": "sch\u00e9in Schr\u00ebft\u00a0bg. ",
      "long_id": "m9sxb0sowgsm9tgj",
      "rank": 0.06079271,
      "author_username": "caoral",
      "author_displayname": "Cagri Oral",
      "highlighted_words": [],
      "answer_long_id": "wtno55y3wkl0bh4l",
      "exam_displayname": "FS21",
      "filename": "4pft8mxl.pdf",
      "category_displayname": "Lineare Algebra",
      "category_slug": "LineareAlgebra",
      "type": "comment"
    }

On my local machine:


        {
            "text": "I'm not sure if 1 is correct. If we look at the linearity property of Fourier: For any complex numbers a and b, if h(x) = af(x) + bg(x), then \u0125(\u03be) = a \u00b7 f\u0302(\u03be) + b \u00b7 \u011d(\u03be). So it should be 2 \u00b7 F(u,v) and not 2 \u2217 F(u,v).\r\nAnd if we look at 2 as a constant function, then the DFT of c(x) = 2 isn't 2 but the dirac-delta impulse at 2. So this still doesn't make sense.",
            "long_id": "85iheehpj8j2ax5g",
            "rank": 0.06079271,
            "author_username": "barlasa",
            "author_displayname": "Ayseg\u00fcl Barlas",
            "highlighted_words": [
                "bg"
            ],
            "answer_long_id": "5c1d583729082200e37306e3",
            "exam_displayname": "FS10",
            "filename": "bdubehxd.pdf",
            "category_displayname": "Visual Computing",
            "category_slug": "VisualComputing",
            "type": "comment"
        },
        {
            "text": "sch\u00e9in Schr\u00ebft\u00a0bg. ",
            "long_id": "m9sxb0sowgsm9tgj",
            "rank": 0.06079271,
            "author_username": "caoral",
            "author_displayname": "Cagri Oral",
            "highlighted_words": [
                "bg"
            ],
            "answer_long_id": "wtno55y3wkl0bh4l",
            "exam_displayname": "FS21",
            "filename": "4pft8mxl.pdf",
            "category_displayname": "Lineare Algebra",
            "category_slug": "LineareAlgebra",
            "type": "comment"
        }

answer/comment.highlighted_words from the backend is passed as addMarks(obj, new RegExp(highlighted_words.join("|"))). But when the array is empty, the RegExp is instantiated as new RegExp(""). This instance matches all inputs, even the empty string. So string.match(regex) returns a match with 0 length, causing the while loop within addMarks to loop forever.

This never happened on the old search page (and only happens on QuickSearch) since the old search page uses a wrapper component HighlightedMarkdown that checks for this exact case....

We fix the problem and prevent it in the future by:

  • Inside addMarks(), if anyone accidentally does the same mistake in the future, check if the RegExp is empty and return early.
  • Merge the functionality of HighlightedMarkdown (only used in 1 other place) into MarkdownText, which prevents developers from passing raw RegEx. They must now pass an array of words to highlight, which can now safely by empty or undefined.
Edited by Yuto Takano

Merge request reports

Loading