Return WideString from CFGAS_LinkUserData::GetLinkURL()

Avoids re-generating a widestring as a temporary for a call
to GotoURL(). Propagate the value upwards using empty strings as
a nullptr replacement.

Bug: pdfium:1706
Change-Id: I0f7d2943c40cbbb29e03095846094e469faa69af
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/83732
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Tom Sepez <tsepez@chromium.org>
diff --git a/xfa/fgas/layout/cfgas_linkuserdata.h b/xfa/fgas/layout/cfgas_linkuserdata.h
index 7cacfba..7585f4b 100644
--- a/xfa/fgas/layout/cfgas_linkuserdata.h
+++ b/xfa/fgas/layout/cfgas_linkuserdata.h
@@ -14,7 +14,7 @@
  public:
   CONSTRUCT_VIA_MAKE_RETAIN;
 
-  const wchar_t* GetLinkURL() const { return m_wsURLContent.c_str(); }
+  WideString GetLinkURL() const { return m_wsURLContent; }
 
  private:
   explicit CFGAS_LinkUserData(const WideString& wsText);
diff --git a/xfa/fxfa/cxfa_fftext.cpp b/xfa/fxfa/cxfa_fftext.cpp
index 05388a9..6d58680 100644
--- a/xfa/fxfa/cxfa_fftext.cpp
+++ b/xfa/fxfa/cxfa_fftext.cpp
@@ -100,17 +100,9 @@
 bool CXFA_FFText::AcceptsFocusOnButtonDown(uint32_t dwFlags,
                                            const CFX_PointF& point,
                                            FWL_MouseCommand command) {
-  if (command != FWL_MouseCommand::LeftButtonDown)
-    return false;
-
-  if (!GetRectWithoutRotate().Contains(point))
-    return false;
-
-  const wchar_t* wsURLContent = GetLinkURLAtPoint(point);
-  if (!wsURLContent)
-    return false;
-
-  return true;
+  return command == FWL_MouseCommand::LeftButtonDown &&
+         GetRectWithoutRotate().Contains(point) &&
+         !GetLinkURLAtPoint(point).IsEmpty();
 }
 
 bool CXFA_FFText::OnLButtonDown(uint32_t dwFlags, const CFX_PointF& point) {
@@ -119,7 +111,8 @@
 }
 
 bool CXFA_FFText::OnMouseMove(uint32_t dwFlags, const CFX_PointF& point) {
-  return GetRectWithoutRotate().Contains(point) && !!GetLinkURLAtPoint(point);
+  return GetRectWithoutRotate().Contains(point) &&
+         !GetLinkURLAtPoint(point).IsEmpty();
 }
 
 bool CXFA_FFText::OnLButtonUp(uint32_t dwFlags, const CFX_PointF& point) {
@@ -127,8 +120,8 @@
     return false;
 
   SetButtonDown(false);
-  const wchar_t* wsURLContent = GetLinkURLAtPoint(point);
-  if (!wsURLContent)
+  WideString wsURLContent = GetLinkURLAtPoint(point);
+  if (wsURLContent.IsEmpty())
     return false;
 
   GetDoc()->GotoURL(wsURLContent);
@@ -136,17 +129,17 @@
 }
 
 FWL_WidgetHit CXFA_FFText::HitTest(const CFX_PointF& point) {
-  if (!GetRectWithoutRotate().Contains(point))
-    return FWL_WidgetHit::Unknown;
-  if (!GetLinkURLAtPoint(point))
-    return FWL_WidgetHit::Unknown;
-  return FWL_WidgetHit::HyperLink;
+  if (GetRectWithoutRotate().Contains(point) &&
+      !GetLinkURLAtPoint(point).IsEmpty()) {
+    return FWL_WidgetHit::HyperLink;
+  }
+  return FWL_WidgetHit::Unknown;
 }
 
-const wchar_t* CXFA_FFText::GetLinkURLAtPoint(const CFX_PointF& point) {
+WideString CXFA_FFText::GetLinkURLAtPoint(const CFX_PointF& point) {
   CXFA_TextLayout* pTextLayout = m_pNode->GetTextLayout();
   if (!pTextLayout)
-    return nullptr;
+    return WideString();
 
   CFX_RectF rect = GetRectWithoutRotate();
   return pTextLayout->GetLinkURLAtPoint(point - rect.TopLeft());
diff --git a/xfa/fxfa/cxfa_fftext.h b/xfa/fxfa/cxfa_fftext.h
index 7de77a1..354dc72 100644
--- a/xfa/fxfa/cxfa_fftext.h
+++ b/xfa/fxfa/cxfa_fftext.h
@@ -31,7 +31,8 @@
  private:
   explicit CXFA_FFText(CXFA_Node* pNode);
 
-  const wchar_t* GetLinkURLAtPoint(const CFX_PointF& point);
+  // Returns empty string when no link is present.
+  WideString GetLinkURLAtPoint(const CFX_PointF& point);
 };
 
 #endif  // XFA_FXFA_CXFA_FFTEXT_H_
diff --git a/xfa/fxfa/cxfa_textlayout.cpp b/xfa/fxfa/cxfa_textlayout.cpp
index 66f0ecc..37ee2d0 100644
--- a/xfa/fxfa/cxfa_textlayout.cpp
+++ b/xfa/fxfa/cxfa_textlayout.cpp
@@ -107,14 +107,14 @@
   m_pBreak.reset();
 }
 
-const wchar_t* CXFA_TextLayout::GetLinkURLAtPoint(const CFX_PointF& point) {
+WideString CXFA_TextLayout::GetLinkURLAtPoint(const CFX_PointF& point) {
   for (const auto& pPieceLine : m_pieceLines) {
     for (const auto& pPiece : pPieceLine->m_textPieces) {
       if (pPiece->pLinkData && pPiece->rtPiece.Contains(point))
         return pPiece->pLinkData->GetLinkURL();
     }
   }
-  return nullptr;
+  return WideString();
 }
 
 void CXFA_TextLayout::GetTextDataNode() {
diff --git a/xfa/fxfa/cxfa_textlayout.h b/xfa/fxfa/cxfa_textlayout.h
index 5d99ea1..4a2d6f3 100644
--- a/xfa/fxfa/cxfa_textlayout.h
+++ b/xfa/fxfa/cxfa_textlayout.h
@@ -62,7 +62,9 @@
   bool HasBlock() const { return m_bHasBlock; }
   void ClearBlocks() { m_Blocks.clear(); }
   void ResetHasBlock() { m_bHasBlock = false; }
-  const wchar_t* GetLinkURLAtPoint(const CFX_PointF& point);
+
+  // Returns empty string when no link is present.
+  WideString GetLinkURLAtPoint(const CFX_PointF& point);
 
  private:
   class TextPiece : public CFGAS_TextPiece {