Add unit test for CFXA_Document::RecongnizeXFAVersionNumber() and fix.
Split into static method so it can be tested without initializing all
of cppgc. Then fix parsing of minor version number where length was
off-by-one.
Change-Id: Ie50d40e3f8bc3544c60663ebff389f7982e69d32
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/86790
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/xfa/fxfa/parser/BUILD.gn b/xfa/fxfa/parser/BUILD.gn
index 9091e1b..58a30b2 100644
--- a/xfa/fxfa/parser/BUILD.gn
+++ b/xfa/fxfa/parser/BUILD.gn
@@ -698,6 +698,7 @@
pdfium_unittest_source_set("unittests") {
sources = [
"cxfa_document_builder_unittest.cpp",
+ "cxfa_document_unittest.cpp",
"cxfa_localevalue_unittest.cpp",
"cxfa_measurement_unittest.cpp",
"cxfa_node_unittest.cpp",
diff --git a/xfa/fxfa/parser/cxfa_document.cpp b/xfa/fxfa/parser/cxfa_document.cpp
index 634daec..b9e69f2 100644
--- a/xfa/fxfa/parser/cxfa_document.cpp
+++ b/xfa/fxfa/parser/cxfa_document.cpp
@@ -1467,6 +1467,15 @@
XFA_VERSION CXFA_Document::RecognizeXFAVersionNumber(
const WideString& wsTemplateNS) {
+ XFA_VERSION eVersion = ParseXFAVersion(wsTemplateNS);
+ if (eVersion != XFA_VERSION_UNKNOWN)
+ m_eCurVersionMode = eVersion;
+
+ return eVersion;
+}
+
+// static
+XFA_VERSION CXFA_Document::ParseXFAVersion(const WideString& wsTemplateNS) {
WideStringView wsTemplateURIPrefix(kTemplateNS);
if (wsTemplateNS.GetLength() <= wsTemplateURIPrefix.GetLength())
return XFA_VERSION_UNKNOWN;
@@ -1485,14 +1494,13 @@
int8_t iMinor =
FXSYS_wtoi(wsTemplateNS
.Substr(nDotPos.value() + 1,
- wsTemplateNS.GetLength() - nDotPos.value() - 2)
+ wsTemplateNS.GetLength() - nDotPos.value() - 1)
.c_str());
XFA_VERSION eVersion =
static_cast<XFA_VERSION>(static_cast<int32_t>(iMajor) * 100 + iMinor);
if (eVersion < XFA_VERSION_MIN || eVersion > XFA_VERSION_MAX)
return XFA_VERSION_UNKNOWN;
- m_eCurVersionMode = eVersion;
return eVersion;
}
diff --git a/xfa/fxfa/parser/cxfa_document.h b/xfa/fxfa/parser/cxfa_document.h
index 7065772..f7e2a537 100644
--- a/xfa/fxfa/parser/cxfa_document.h
+++ b/xfa/fxfa/parser/cxfa_document.h
@@ -14,6 +14,7 @@
#include <memory>
#include <vector>
+#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/unowned_ptr.h"
#include "fxjs/gc/heap.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
@@ -145,6 +146,10 @@
void SetPendingNodesUnusedAndUnbound();
private:
+ friend class CXFA_DocumentTest_ParseXFAVersion_Test;
+
+ static XFA_VERSION ParseXFAVersion(const WideString& wsTemplateNS);
+
CXFA_Document(CXFA_FFNotify* notify,
cppgc::Heap* heap,
LayoutProcessorIface* pLayout);
diff --git a/xfa/fxfa/parser/cxfa_document_unittest.cpp b/xfa/fxfa/parser/cxfa_document_unittest.cpp
new file mode 100644
index 0000000..43872d1
--- /dev/null
+++ b/xfa/fxfa/parser/cxfa_document_unittest.cpp
@@ -0,0 +1,83 @@
+// Copyright 2021 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "xfa/fxfa/parser/cxfa_document.h"
+
+#include "core/fxcrt/fx_string.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+TEST(CXFA_DocumentTest, ParseXFAVersion) {
+ // Malformed
+ EXPECT_EQ(XFA_VERSION_UNKNOWN, CXFA_Document::ParseXFAVersion(L""));
+ EXPECT_EQ(XFA_VERSION_UNKNOWN,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template"));
+ EXPECT_EQ(XFA_VERSION_UNKNOWN,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-templatX/"));
+ EXPECT_EQ(XFA_VERSION_UNKNOWN,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/"));
+ EXPECT_EQ(XFA_VERSION_UNKNOWN,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/2"));
+
+ // Out-of-range
+ EXPECT_EQ(XFA_VERSION_UNKNOWN,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/-1.0"));
+ EXPECT_EQ(XFA_VERSION_UNKNOWN,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/1.9"));
+ EXPECT_EQ(XFA_VERSION_UNKNOWN,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/4.1"));
+
+ // Missing digits
+ EXPECT_EQ(XFA_VERSION_UNKNOWN,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/."));
+ EXPECT_EQ(XFA_VERSION_UNKNOWN,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/.3"));
+ EXPECT_EQ(XFA_VERSION_300, CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/3."));
+ EXPECT_EQ(XFA_VERSION_UNKNOWN,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/clams.6"));
+ EXPECT_EQ(XFA_VERSION_300,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/3.clams"));
+
+ // Min / max values
+ EXPECT_EQ(XFA_VERSION_200,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/2.0"));
+ EXPECT_EQ(400, CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/4.0"));
+
+ // Number and decimal point parsing.
+ EXPECT_EQ(XFA_VERSION_306,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/3.6"));
+
+ // TODO(tsepez): maybe fail on these dubious values?
+ EXPECT_EQ(XFA_VERSION_306,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/0003.00006"));
+ EXPECT_EQ(XFA_VERSION_306,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/0003.00006.0000"));
+ EXPECT_EQ(XFA_VERSION_206,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/2.6clams"));
+ EXPECT_EQ(XFA_VERSION_206,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/1.106"));
+ EXPECT_EQ(XFA_VERSION_306,
+ CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/4.-94"));
+ EXPECT_EQ(317, CXFA_Document::ParseXFAVersion(
+ L"http://www.xfa.org/schema/xfa-template/3.17"));
+}