mirror of
https://github.com/qpdf/qpdf.git
synced 2024-12-22 10:58:58 +00:00
Add additional information when listing attachments
This commit is contained in:
parent
04fc7c4bea
commit
f049a77c59
@ -1,5 +1,8 @@
|
||||
2022-05-30 Jay Berkenbilt <ejb@ql.org>
|
||||
|
||||
* Include additional information in --list-attachments --verbose
|
||||
and in --json --json-key=attachments.
|
||||
|
||||
* Add QUtil::qpdf_time_to_iso8601 and QUtil::pdf_time_to_iso8601
|
||||
for converting PDF/qpdf timestamps to ISO-8601 date format.
|
||||
|
||||
|
3
TODO
3
TODO
@ -72,9 +72,6 @@ Remaining work:
|
||||
|
||||
* --encryption: show recovered user password when available
|
||||
|
||||
* --list-attachments: add information from --verbose. Add to a
|
||||
"details" subkey.
|
||||
|
||||
* Consider having --check, --show-encryption, etc., just select the
|
||||
right keys when in json mode. I don't think I want check on by
|
||||
default, so that might be different.
|
||||
|
2
job.sums
2
job.sums
@ -14,4 +14,4 @@ libqpdf/qpdf/auto_job_json_decl.hh 06caa46eaf71db8a50c046f91866baa8087745a947431
|
||||
libqpdf/qpdf/auto_job_json_init.hh 5f6b53e3c81d4b54ce5c4cf9c3f52d0c02f987c53bf8841c0280367bad23e335
|
||||
libqpdf/qpdf/auto_job_schema.hh 9d543cd4a43eafffc2c4b8a6fee29e399c271c52cb6f7d417ae5497b3c1127dc
|
||||
manual/_ext/qpdf.py 6add6321666031d55ed4aedf7c00e5662bba856dfcd66ccb526563bffefbb580
|
||||
manual/cli.rst e7c35f8183d015d7fe074e38baed4c89bad827fd9c23b4cafd73d562df82ab1b
|
||||
manual/cli.rst 82ead389c03bbf5e0498bd0571a11dc06544d591f4e4454c00322e3473fc556d
|
||||
|
@ -993,8 +993,16 @@ QPDFJob::doListAttachments(QPDF& pdf)
|
||||
}
|
||||
cout << " all data streams:" << std::endl;
|
||||
for (auto i2: efoh->getEmbeddedFileStreams().ditems()) {
|
||||
auto efs = QPDFEFStreamObjectHelper(i2.second);
|
||||
cout << " " << i2.first << " -> "
|
||||
<< i2.second.getObjGen() << std::endl;
|
||||
<< efs.getObjectHandle().getObjGen() << std::endl;
|
||||
cout << " creation date: " << efs.getCreationDate()
|
||||
<< std::endl
|
||||
<< " modification date: " << efs.getModDate()
|
||||
<< std::endl
|
||||
<< " mime type: " << efs.getSubtype() << std::endl
|
||||
<< " checksum: "
|
||||
<< QUtil::hex_encode(efs.getChecksum()) << std::endl;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1445,6 +1453,22 @@ QPDFJob::doJSONEncrypt(Pipeline* p, bool& first, QPDF& pdf)
|
||||
void
|
||||
QPDFJob::doJSONAttachments(Pipeline* p, bool& first, QPDF& pdf)
|
||||
{
|
||||
auto to_iso8601 = [](std::string const& d) {
|
||||
// Convert PDF date to iso8601 if not empty; if empty, return
|
||||
// empty.
|
||||
std::string iso8601;
|
||||
QUtil::pdf_time_to_iso8601(d, iso8601);
|
||||
return iso8601;
|
||||
};
|
||||
|
||||
auto null_or_string = [](std::string const& s) {
|
||||
if (s.empty()) {
|
||||
return JSON::makeNull();
|
||||
} else {
|
||||
return JSON::makeString(s);
|
||||
}
|
||||
};
|
||||
|
||||
JSON j_attachments = JSON::makeDictionary();
|
||||
QPDFEmbeddedFileDocumentHelper efdh(pdf);
|
||||
for (auto const& iter: efdh.getEmbeddedFiles()) {
|
||||
@ -1459,6 +1483,31 @@ QPDFJob::doJSONAttachments(Pipeline* p, bool& first, QPDF& pdf)
|
||||
j_details.addDictionaryMember(
|
||||
"preferredcontents",
|
||||
JSON::makeString(fsoh->getEmbeddedFileStream().unparse()));
|
||||
j_details.addDictionaryMember(
|
||||
"description", null_or_string(fsoh->getDescription()));
|
||||
auto j_names =
|
||||
j_details.addDictionaryMember("names", JSON::makeDictionary());
|
||||
for (auto const& i2: fsoh->getFilenames()) {
|
||||
j_names.addDictionaryMember(i2.first, JSON::makeString(i2.second));
|
||||
}
|
||||
auto j_streams =
|
||||
j_details.addDictionaryMember("streams", JSON::makeDictionary());
|
||||
for (auto i2: fsoh->getEmbeddedFileStreams().ditems()) {
|
||||
auto efs = QPDFEFStreamObjectHelper(i2.second);
|
||||
auto j_stream =
|
||||
j_streams.addDictionaryMember(i2.first, JSON::makeDictionary());
|
||||
j_stream.addDictionaryMember(
|
||||
"creationdate",
|
||||
null_or_string(to_iso8601(efs.getCreationDate())));
|
||||
j_stream.addDictionaryMember(
|
||||
"modificationdate",
|
||||
null_or_string(to_iso8601(efs.getCreationDate())));
|
||||
j_stream.addDictionaryMember(
|
||||
"mimetype", null_or_string(efs.getSubtype()));
|
||||
j_stream.addDictionaryMember(
|
||||
"checksum",
|
||||
null_or_string(QUtil::hex_encode(efs.getChecksum())));
|
||||
}
|
||||
}
|
||||
JSON::writeDictionaryItem(p, first, "attachments", j_attachments, 0);
|
||||
}
|
||||
@ -1640,7 +1689,19 @@ QPDFJob::json_schema(int json_version, std::set<std::string>* keys)
|
||||
"<attachment-key>": {
|
||||
"filespec": "object containing the file spec",
|
||||
"preferredcontents": "most preferred embedded file stream",
|
||||
"preferredname": "most preferred file name"
|
||||
"preferredname": "most preferred file name",
|
||||
"description": "description of attachment",
|
||||
"names": {
|
||||
"<name-key>": "file name for key"
|
||||
},
|
||||
"streams": {
|
||||
"<stream-key>": {
|
||||
"creationdate": "ISO-8601 creation date or null",
|
||||
"modificationdate": "ISO-8601 modification date or null",
|
||||
"mimetype": "mime type or null",
|
||||
"checksum": "MD5 checksum or null"
|
||||
}
|
||||
}
|
||||
}
|
||||
})"));
|
||||
}
|
||||
|
@ -3124,7 +3124,10 @@ Related Options
|
||||
:qpdf:ref:`--verbose`, additional information, including preferred
|
||||
file name, description, dates, and more are also displayed. The key
|
||||
is usually but not always equal to the file name and is needed by
|
||||
some of the other options. See also :ref:`attachments`.
|
||||
some of the other options. See also :ref:`attachments`. Note that
|
||||
this option displays dates in PDF timestamp syntax. When attachment
|
||||
information is included in json output (see :ref:`--json`), dates
|
||||
are shown in ISO-8601 format.
|
||||
|
||||
.. qpdf:option:: --show-attachment=key
|
||||
|
||||
|
@ -96,6 +96,13 @@ For a detailed list of changes, please see the file
|
||||
- See :ref:`breaking-crypto-api` for specific details, and see
|
||||
:ref:`weak-crypto` for a general discussion.
|
||||
|
||||
- CLI Enhancements
|
||||
|
||||
- ``qpdf --list-attachments --verbose`` include some additional
|
||||
information about attachments. Additional information about
|
||||
attachments is also included in the ``attachments`` json key
|
||||
with ``--json``.
|
||||
|
||||
- Library Enhancements
|
||||
|
||||
- New methods ``insertItemAndGet``, ``appendItemAndGet``,
|
||||
@ -120,6 +127,9 @@ For a detailed list of changes, please see the file
|
||||
- Add new ``Pipeline`` type ``Pl_String`` to append to a
|
||||
``std::string``.
|
||||
|
||||
- Add methods to QUtil for converting PDF timestamps and QPDFTime
|
||||
objects to ISO-8601 timestamps.
|
||||
|
||||
- Enhance JSON class to better support incrementally reading and
|
||||
writing large amounts of data without having to keep everything
|
||||
in memory.
|
||||
|
@ -189,7 +189,8 @@ $td->runtest("add attachments: current date",
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
$td->runtest("list attachments",
|
||||
{$td->COMMAND =>
|
||||
"qpdf --password=u --list-attachments a.pdf --verbose"},
|
||||
"qpdf --password=u --list-attachments a.pdf --verbose",
|
||||
$td->FILTER => "perl filter-attachment-date.pl"},
|
||||
{$td->FILE => "list-attachments-4.out", $td->EXIT_STATUS => 0},
|
||||
$td->NORMALIZE_NEWLINES);
|
||||
# The object to show here is the one in list-attachments-4.out
|
||||
|
@ -26,6 +26,7 @@ my @json_files = (
|
||||
['field-types', ['--show-encryption-key']],
|
||||
['image-streams', ['--decode-level=all']],
|
||||
['image-streams', ['--decode-level=specialized']],
|
||||
['attachment-fields', []],
|
||||
['page-labels-and-outlines', ['--json-key=objects']],
|
||||
['page-labels-and-outlines', ['--json-key=pages']],
|
||||
['page-labels-and-outlines', ['--json-key=pagelabels']],
|
||||
|
190
qpdf/qtest/qpdf/attachment-fields.pdf
Normal file
190
qpdf/qtest/qpdf/attachment-fields.pdf
Normal file
@ -0,0 +1,190 @@
|
||||
%PDF-1.3
|
||||
%¿÷¢þ
|
||||
%QDF-1.0
|
||||
|
||||
%% Original object ID: 1 0
|
||||
1 0 obj
|
||||
<<
|
||||
/Names <<
|
||||
/EmbeddedFiles 2 0 R
|
||||
>>
|
||||
/PageMode /UseAttachments
|
||||
/Pages 3 0 R
|
||||
/Type /Catalog
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Original object ID: 2 0
|
||||
2 0 obj
|
||||
<<
|
||||
/Names [
|
||||
(a.txt)
|
||||
4 0 R
|
||||
<feff03c0002e007400780074>
|
||||
5 0 R
|
||||
]
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Original object ID: 3 0
|
||||
3 0 obj
|
||||
<<
|
||||
/Count 1
|
||||
/Kids [
|
||||
6 0 R
|
||||
]
|
||||
/Type /Pages
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Original object ID: 4 0
|
||||
4 0 obj
|
||||
<<
|
||||
/EF <<
|
||||
/F 7 0 R
|
||||
/UF 7 0 R
|
||||
>>
|
||||
/F (a.txt)
|
||||
/Type /Filespec
|
||||
/UF (a.txt)
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Original object ID: 5 0
|
||||
5 0 obj
|
||||
<<
|
||||
/Desc (Two filenames)
|
||||
/EF <<
|
||||
/F 9 0 R
|
||||
/UF 9 0 R
|
||||
>>
|
||||
/F (pi.txt)
|
||||
/Type /Filespec
|
||||
/UF <feff03c0002e007400780074>
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Page 1
|
||||
%% Original object ID: 6 0
|
||||
6 0 obj
|
||||
<<
|
||||
/Contents 11 0 R
|
||||
/MediaBox [
|
||||
0
|
||||
0
|
||||
612
|
||||
792
|
||||
]
|
||||
/Parent 3 0 R
|
||||
/Resources <<
|
||||
/Font <<
|
||||
/F1 13 0 R
|
||||
>>
|
||||
/ProcSet 14 0 R
|
||||
>>
|
||||
/Type /Page
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Original object ID: 7 0
|
||||
7 0 obj
|
||||
<<
|
||||
/Params <<
|
||||
/Size 7
|
||||
>>
|
||||
/Type /EmbeddedFile
|
||||
/Length 8 0 R
|
||||
>>
|
||||
stream
|
||||
potato
|
||||
endstream
|
||||
endobj
|
||||
|
||||
8 0 obj
|
||||
7
|
||||
endobj
|
||||
|
||||
%% Original object ID: 8 0
|
||||
9 0 obj
|
||||
<<
|
||||
/Params <<
|
||||
/CheckSum <e561f9248d7563d15dd93457b02ebbb6>
|
||||
/CreationDate (D:20220530094116-05'00')
|
||||
/ModDate (D:20220530094116-05'00')
|
||||
/Size 7
|
||||
>>
|
||||
/Subtype /text#2fplain
|
||||
/Type /EmbeddedFile
|
||||
/Length 10 0 R
|
||||
>>
|
||||
stream
|
||||
potato
|
||||
endstream
|
||||
endobj
|
||||
|
||||
10 0 obj
|
||||
7
|
||||
endobj
|
||||
|
||||
%% Contents for page 1
|
||||
%% Original object ID: 9 0
|
||||
11 0 obj
|
||||
<<
|
||||
/Length 12 0 R
|
||||
>>
|
||||
stream
|
||||
BT
|
||||
/F1 24 Tf
|
||||
72 720 Td
|
||||
(Potato) Tj
|
||||
ET
|
||||
endstream
|
||||
endobj
|
||||
|
||||
12 0 obj
|
||||
44
|
||||
endobj
|
||||
|
||||
%% Original object ID: 10 0
|
||||
13 0 obj
|
||||
<<
|
||||
/BaseFont /Helvetica
|
||||
/Encoding /WinAnsiEncoding
|
||||
/Subtype /Type1
|
||||
/Type /Font
|
||||
>>
|
||||
endobj
|
||||
|
||||
%% Original object ID: 11 0
|
||||
14 0 obj
|
||||
[
|
||||
/PDF
|
||||
/Text
|
||||
]
|
||||
endobj
|
||||
|
||||
xref
|
||||
0 15
|
||||
0000000000 65535 f
|
||||
0000000052 00000 n
|
||||
0000000203 00000 n
|
||||
0000000330 00000 n
|
||||
0000000429 00000 n
|
||||
0000000564 00000 n
|
||||
0000000753 00000 n
|
||||
0000000975 00000 n
|
||||
0000001089 00000 n
|
||||
0000001134 00000 n
|
||||
0000001406 00000 n
|
||||
0000001475 00000 n
|
||||
0000001576 00000 n
|
||||
0000001624 00000 n
|
||||
0000001759 00000 n
|
||||
trailer <<
|
||||
/Root 1 0 R
|
||||
/Size 15
|
||||
/ID [<3d1a89e08f9d6b3e1f787d04fceed440><4e13de38230bb10a03e49285a742c392>]
|
||||
>>
|
||||
startxref
|
||||
1795
|
||||
%%EOF
|
8
qpdf/qtest/qpdf/filter-attachment-date.pl
Normal file
8
qpdf/qtest/qpdf/filter-attachment-date.pl
Normal file
@ -0,0 +1,8 @@
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
while (<>)
|
||||
{
|
||||
s/D:\d{14}\S+/<date>/;
|
||||
print;
|
||||
}
|
305
qpdf/qtest/qpdf/json-attachment-fields-v1.out
Normal file
305
qpdf/qtest/qpdf/json-attachment-fields-v1.out
Normal file
@ -0,0 +1,305 @@
|
||||
{
|
||||
"version": 1,
|
||||
"parameters": {
|
||||
"decodelevel": "generalized"
|
||||
},
|
||||
"pages": [
|
||||
{
|
||||
"contents": [
|
||||
"11 0 R"
|
||||
],
|
||||
"images": [],
|
||||
"label": null,
|
||||
"object": "6 0 R",
|
||||
"outlines": [],
|
||||
"pageposfrom1": 1
|
||||
}
|
||||
],
|
||||
"pagelabels": [],
|
||||
"acroform": {
|
||||
"fields": [],
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {
|
||||
"a.txt": {
|
||||
"description": null,
|
||||
"filespec": "4 0 R",
|
||||
"names": {
|
||||
"/F": "a.txt",
|
||||
"/UF": "a.txt"
|
||||
},
|
||||
"preferredcontents": "7 0 R",
|
||||
"preferredname": "a.txt",
|
||||
"streams": {
|
||||
"/F": {
|
||||
"checksum": null,
|
||||
"creationdate": null,
|
||||
"mimetype": null,
|
||||
"modificationdate": null
|
||||
},
|
||||
"/UF": {
|
||||
"checksum": null,
|
||||
"creationdate": null,
|
||||
"mimetype": null,
|
||||
"modificationdate": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"π.txt": {
|
||||
"description": "Two filenames",
|
||||
"filespec": "5 0 R",
|
||||
"names": {
|
||||
"/F": "pi.txt",
|
||||
"/UF": "π.txt"
|
||||
},
|
||||
"preferredcontents": "9 0 R",
|
||||
"preferredname": "π.txt",
|
||||
"streams": {
|
||||
"/F": {
|
||||
"checksum": "e561f9248d7563d15dd93457b02ebbb6",
|
||||
"creationdate": "2022-05-30T09:41:16-05:00",
|
||||
"mimetype": "text/plain",
|
||||
"modificationdate": "2022-05-30T09:41:16-05:00"
|
||||
},
|
||||
"/UF": {
|
||||
"checksum": "e561f9248d7563d15dd93457b02ebbb6",
|
||||
"creationdate": "2022-05-30T09:41:16-05:00",
|
||||
"mimetype": "text/plain",
|
||||
"modificationdate": "2022-05-30T09:41:16-05:00"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"moddifyannotations": true,
|
||||
"modify": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
"objects": {
|
||||
"1 0 R": {
|
||||
"/Names": {
|
||||
"/EmbeddedFiles": "2 0 R"
|
||||
},
|
||||
"/PageMode": "/UseAttachments",
|
||||
"/Pages": "3 0 R",
|
||||
"/Type": "/Catalog"
|
||||
},
|
||||
"2 0 R": {
|
||||
"/Names": [
|
||||
"a.txt",
|
||||
"4 0 R",
|
||||
"π.txt",
|
||||
"5 0 R"
|
||||
]
|
||||
},
|
||||
"3 0 R": {
|
||||
"/Count": 1,
|
||||
"/Kids": [
|
||||
"6 0 R"
|
||||
],
|
||||
"/Type": "/Pages"
|
||||
},
|
||||
"4 0 R": {
|
||||
"/EF": {
|
||||
"/F": "7 0 R",
|
||||
"/UF": "7 0 R"
|
||||
},
|
||||
"/F": "a.txt",
|
||||
"/Type": "/Filespec",
|
||||
"/UF": "a.txt"
|
||||
},
|
||||
"5 0 R": {
|
||||
"/Desc": "Two filenames",
|
||||
"/EF": {
|
||||
"/F": "9 0 R",
|
||||
"/UF": "9 0 R"
|
||||
},
|
||||
"/F": "pi.txt",
|
||||
"/Type": "/Filespec",
|
||||
"/UF": "π.txt"
|
||||
},
|
||||
"6 0 R": {
|
||||
"/Contents": "11 0 R",
|
||||
"/MediaBox": [
|
||||
0,
|
||||
0,
|
||||
612,
|
||||
792
|
||||
],
|
||||
"/Parent": "3 0 R",
|
||||
"/Resources": {
|
||||
"/Font": {
|
||||
"/F1": "13 0 R"
|
||||
},
|
||||
"/ProcSet": "14 0 R"
|
||||
},
|
||||
"/Type": "/Page"
|
||||
},
|
||||
"7 0 R": {
|
||||
"/Length": "8 0 R",
|
||||
"/Params": {
|
||||
"/Size": 7
|
||||
},
|
||||
"/Type": "/EmbeddedFile"
|
||||
},
|
||||
"8 0 R": 7,
|
||||
"9 0 R": {
|
||||
"/Length": "10 0 R",
|
||||
"/Params": {
|
||||
"/CheckSum": "åaù$“ucÑ]Ù4W°.»¶",
|
||||
"/CreationDate": "D:20220530094116-05'00'",
|
||||
"/ModDate": "D:20220530094116-05'00'",
|
||||
"/Size": 7
|
||||
},
|
||||
"/Subtype": "/text#2fplain",
|
||||
"/Type": "/EmbeddedFile"
|
||||
},
|
||||
"10 0 R": 7,
|
||||
"11 0 R": {
|
||||
"/Length": "12 0 R"
|
||||
},
|
||||
"12 0 R": 44,
|
||||
"13 0 R": {
|
||||
"/BaseFont": "/Helvetica",
|
||||
"/Encoding": "/WinAnsiEncoding",
|
||||
"/Subtype": "/Type1",
|
||||
"/Type": "/Font"
|
||||
},
|
||||
"14 0 R": [
|
||||
"/PDF",
|
||||
"/Text"
|
||||
],
|
||||
"trailer": {
|
||||
"/ID": [
|
||||
"=ˆ›à‘šk>˜x}\u0004üîÔ@",
|
||||
"N\u0013Þ8#\u000b±\n\u0003ä™–§BÙ"
|
||||
],
|
||||
"/Root": "1 0 R",
|
||||
"/Size": 15
|
||||
}
|
||||
},
|
||||
"objectinfo": {
|
||||
"1 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": false,
|
||||
"length": null
|
||||
}
|
||||
},
|
||||
"2 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": false,
|
||||
"length": null
|
||||
}
|
||||
},
|
||||
"3 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": false,
|
||||
"length": null
|
||||
}
|
||||
},
|
||||
"4 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": false,
|
||||
"length": null
|
||||
}
|
||||
},
|
||||
"5 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": false,
|
||||
"length": null
|
||||
}
|
||||
},
|
||||
"6 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": false,
|
||||
"length": null
|
||||
}
|
||||
},
|
||||
"7 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": true,
|
||||
"length": 7
|
||||
}
|
||||
},
|
||||
"8 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": false,
|
||||
"length": null
|
||||
}
|
||||
},
|
||||
"9 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": true,
|
||||
"length": 7
|
||||
}
|
||||
},
|
||||
"10 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": false,
|
||||
"length": null
|
||||
}
|
||||
},
|
||||
"11 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": true,
|
||||
"length": 44
|
||||
}
|
||||
},
|
||||
"12 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": false,
|
||||
"length": null
|
||||
}
|
||||
},
|
||||
"13 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": false,
|
||||
"length": null
|
||||
}
|
||||
},
|
||||
"14 0 R": {
|
||||
"stream": {
|
||||
"filter": null,
|
||||
"is": false,
|
||||
"length": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
241
qpdf/qtest/qpdf/json-attachment-fields-v2.out
Normal file
241
qpdf/qtest/qpdf/json-attachment-fields-v2.out
Normal file
@ -0,0 +1,241 @@
|
||||
{
|
||||
"version": 2,
|
||||
"parameters": {
|
||||
"decodelevel": "generalized"
|
||||
},
|
||||
"pages": [
|
||||
{
|
||||
"contents": [
|
||||
"11 0 R"
|
||||
],
|
||||
"images": [],
|
||||
"label": null,
|
||||
"object": "6 0 R",
|
||||
"outlines": [],
|
||||
"pageposfrom1": 1
|
||||
}
|
||||
],
|
||||
"pagelabels": [],
|
||||
"acroform": {
|
||||
"fields": [],
|
||||
"hasacroform": false,
|
||||
"needappearances": false
|
||||
},
|
||||
"attachments": {
|
||||
"a.txt": {
|
||||
"description": null,
|
||||
"filespec": "4 0 R",
|
||||
"names": {
|
||||
"/F": "a.txt",
|
||||
"/UF": "a.txt"
|
||||
},
|
||||
"preferredcontents": "7 0 R",
|
||||
"preferredname": "a.txt",
|
||||
"streams": {
|
||||
"/F": {
|
||||
"checksum": null,
|
||||
"creationdate": null,
|
||||
"mimetype": null,
|
||||
"modificationdate": null
|
||||
},
|
||||
"/UF": {
|
||||
"checksum": null,
|
||||
"creationdate": null,
|
||||
"mimetype": null,
|
||||
"modificationdate": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"π.txt": {
|
||||
"description": "Two filenames",
|
||||
"filespec": "5 0 R",
|
||||
"names": {
|
||||
"/F": "pi.txt",
|
||||
"/UF": "π.txt"
|
||||
},
|
||||
"preferredcontents": "9 0 R",
|
||||
"preferredname": "π.txt",
|
||||
"streams": {
|
||||
"/F": {
|
||||
"checksum": "e561f9248d7563d15dd93457b02ebbb6",
|
||||
"creationdate": "2022-05-30T09:41:16-05:00",
|
||||
"mimetype": "text/plain",
|
||||
"modificationdate": "2022-05-30T09:41:16-05:00"
|
||||
},
|
||||
"/UF": {
|
||||
"checksum": "e561f9248d7563d15dd93457b02ebbb6",
|
||||
"creationdate": "2022-05-30T09:41:16-05:00",
|
||||
"mimetype": "text/plain",
|
||||
"modificationdate": "2022-05-30T09:41:16-05:00"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"encrypt": {
|
||||
"capabilities": {
|
||||
"accessibility": true,
|
||||
"extract": true,
|
||||
"modify": true,
|
||||
"modifyannotations": true,
|
||||
"modifyassembly": true,
|
||||
"modifyforms": true,
|
||||
"modifyother": true,
|
||||
"printhigh": true,
|
||||
"printlow": true
|
||||
},
|
||||
"encrypted": false,
|
||||
"ownerpasswordmatched": false,
|
||||
"parameters": {
|
||||
"P": 0,
|
||||
"R": 0,
|
||||
"V": 0,
|
||||
"bits": 0,
|
||||
"filemethod": "none",
|
||||
"key": null,
|
||||
"method": "none",
|
||||
"streammethod": "none",
|
||||
"stringmethod": "none"
|
||||
},
|
||||
"userpasswordmatched": false
|
||||
},
|
||||
"outlines": [],
|
||||
"objects": {
|
||||
"obj:1 0 R": {
|
||||
"value": {
|
||||
"/Names": {
|
||||
"/EmbeddedFiles": "2 0 R"
|
||||
},
|
||||
"/PageMode": "/UseAttachments",
|
||||
"/Pages": "3 0 R",
|
||||
"/Type": "/Catalog"
|
||||
}
|
||||
},
|
||||
"obj:2 0 R": {
|
||||
"value": {
|
||||
"/Names": [
|
||||
"u:a.txt",
|
||||
"4 0 R",
|
||||
"u:π.txt",
|
||||
"5 0 R"
|
||||
]
|
||||
}
|
||||
},
|
||||
"obj:3 0 R": {
|
||||
"value": {
|
||||
"/Count": 1,
|
||||
"/Kids": [
|
||||
"6 0 R"
|
||||
],
|
||||
"/Type": "/Pages"
|
||||
}
|
||||
},
|
||||
"obj:4 0 R": {
|
||||
"value": {
|
||||
"/EF": {
|
||||
"/F": "7 0 R",
|
||||
"/UF": "7 0 R"
|
||||
},
|
||||
"/F": "u:a.txt",
|
||||
"/Type": "/Filespec",
|
||||
"/UF": "u:a.txt"
|
||||
}
|
||||
},
|
||||
"obj:5 0 R": {
|
||||
"value": {
|
||||
"/Desc": "u:Two filenames",
|
||||
"/EF": {
|
||||
"/F": "9 0 R",
|
||||
"/UF": "9 0 R"
|
||||
},
|
||||
"/F": "u:pi.txt",
|
||||
"/Type": "/Filespec",
|
||||
"/UF": "u:π.txt"
|
||||
}
|
||||
},
|
||||
"obj:6 0 R": {
|
||||
"value": {
|
||||
"/Contents": "11 0 R",
|
||||
"/MediaBox": [
|
||||
0,
|
||||
0,
|
||||
612,
|
||||
792
|
||||
],
|
||||
"/Parent": "3 0 R",
|
||||
"/Resources": {
|
||||
"/Font": {
|
||||
"/F1": "13 0 R"
|
||||
},
|
||||
"/ProcSet": "14 0 R"
|
||||
},
|
||||
"/Type": "/Page"
|
||||
}
|
||||
},
|
||||
"obj:7 0 R": {
|
||||
"stream": {
|
||||
"dict": {
|
||||
"/Length": "8 0 R",
|
||||
"/Params": {
|
||||
"/Size": 7
|
||||
},
|
||||
"/Type": "/EmbeddedFile"
|
||||
}
|
||||
}
|
||||
},
|
||||
"obj:8 0 R": {
|
||||
"value": 7
|
||||
},
|
||||
"obj:9 0 R": {
|
||||
"stream": {
|
||||
"dict": {
|
||||
"/Length": "10 0 R",
|
||||
"/Params": {
|
||||
"/CheckSum": "b:e561f9248d7563d15dd93457b02ebbb6",
|
||||
"/CreationDate": "u:D:20220530094116-05'00'",
|
||||
"/ModDate": "u:D:20220530094116-05'00'",
|
||||
"/Size": 7
|
||||
},
|
||||
"/Subtype": "/text/plain",
|
||||
"/Type": "/EmbeddedFile"
|
||||
}
|
||||
}
|
||||
},
|
||||
"obj:10 0 R": {
|
||||
"value": 7
|
||||
},
|
||||
"obj:11 0 R": {
|
||||
"stream": {
|
||||
"dict": {
|
||||
"/Length": "12 0 R"
|
||||
}
|
||||
}
|
||||
},
|
||||
"obj:12 0 R": {
|
||||
"value": 44
|
||||
},
|
||||
"obj:13 0 R": {
|
||||
"value": {
|
||||
"/BaseFont": "/Helvetica",
|
||||
"/Encoding": "/WinAnsiEncoding",
|
||||
"/Subtype": "/Type1",
|
||||
"/Type": "/Font"
|
||||
}
|
||||
},
|
||||
"obj:14 0 R": {
|
||||
"value": [
|
||||
"/PDF",
|
||||
"/Text"
|
||||
]
|
||||
},
|
||||
"trailer": {
|
||||
"value": {
|
||||
"/ID": [
|
||||
"b:3d1a89e08f9d6b3e1f787d04fceed440",
|
||||
"b:4e13de38230bb10a03e49285a742c392"
|
||||
],
|
||||
"/Root": "1 0 R",
|
||||
"/Size": 15
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,15 @@ auto-1 -> 8,0
|
||||
/UF -> auto-1
|
||||
all data streams:
|
||||
/F -> 8,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type: text/plain
|
||||
checksum: a857d18d3fc23ad412122ef040733331
|
||||
/UF -> 8,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type: text/plain
|
||||
checksum: a857d18d3fc23ad412122ef040733331
|
||||
auto-3 -> 10,0
|
||||
description: two words
|
||||
preferred name: auto-Three.txt
|
||||
@ -14,7 +22,15 @@ auto-3 -> 10,0
|
||||
/UF -> auto-Three.txt
|
||||
all data streams:
|
||||
/F -> 10,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: d6c7ac7cf295ae133fea186cfd068dab
|
||||
/UF -> 10,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: d6c7ac7cf295ae133fea186cfd068dab
|
||||
auto-Two -> 12,0
|
||||
preferred name: auto-2
|
||||
all names:
|
||||
@ -22,4 +38,12 @@ auto-Two -> 12,0
|
||||
/UF -> auto-2
|
||||
all data streams:
|
||||
/F -> 12,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: 9f991a5669c47a94f9350f53e3953e57
|
||||
/UF -> 12,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: 9f991a5669c47a94f9350f53e3953e57
|
||||
|
@ -5,7 +5,15 @@
|
||||
/UF -> auto-1
|
||||
all data streams:
|
||||
/F -> 11,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type: text/plain
|
||||
checksum: a857d18d3fc23ad412122ef040733331
|
||||
/UF -> 11,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type: text/plain
|
||||
checksum: a857d18d3fc23ad412122ef040733331
|
||||
1-auto-3 -> 13,0
|
||||
description: two words
|
||||
preferred name: auto-Three.txt
|
||||
@ -14,7 +22,15 @@
|
||||
/UF -> auto-Three.txt
|
||||
all data streams:
|
||||
/F -> 13,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: d6c7ac7cf295ae133fea186cfd068dab
|
||||
/UF -> 13,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: d6c7ac7cf295ae133fea186cfd068dab
|
||||
1-auto-Two -> 15,0
|
||||
preferred name: auto-2
|
||||
all names:
|
||||
@ -22,7 +38,15 @@
|
||||
/UF -> auto-2
|
||||
all data streams:
|
||||
/F -> 15,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: 9f991a5669c47a94f9350f53e3953e57
|
||||
/UF -> 15,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: 9f991a5669c47a94f9350f53e3953e57
|
||||
auto-1 -> 17,0
|
||||
preferred name: auto-1
|
||||
all names:
|
||||
@ -30,7 +54,15 @@ auto-1 -> 17,0
|
||||
/UF -> auto-1
|
||||
all data streams:
|
||||
/F -> 17,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type: text/plain
|
||||
checksum: a857d18d3fc23ad412122ef040733331
|
||||
/UF -> 17,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type: text/plain
|
||||
checksum: a857d18d3fc23ad412122ef040733331
|
||||
auto-3 -> 19,0
|
||||
description: two words
|
||||
preferred name: auto-Three.txt
|
||||
@ -39,7 +71,15 @@ auto-3 -> 19,0
|
||||
/UF -> auto-Three.txt
|
||||
all data streams:
|
||||
/F -> 19,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: d6c7ac7cf295ae133fea186cfd068dab
|
||||
/UF -> 19,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: d6c7ac7cf295ae133fea186cfd068dab
|
||||
auto-Two -> 21,0
|
||||
preferred name: auto-2
|
||||
all names:
|
||||
@ -47,4 +87,12 @@ auto-Two -> 21,0
|
||||
/UF -> auto-2
|
||||
all data streams:
|
||||
/F -> 21,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: 9f991a5669c47a94f9350f53e3953e57
|
||||
/UF -> 21,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: 9f991a5669c47a94f9350f53e3953e57
|
||||
|
@ -5,7 +5,15 @@ auto-1 -> 8,0
|
||||
/UF -> auto-2
|
||||
all data streams:
|
||||
/F -> 8,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: 9f991a5669c47a94f9350f53e3953e57
|
||||
/UF -> 8,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: 9f991a5669c47a94f9350f53e3953e57
|
||||
auto-3 -> 10,0
|
||||
description: two words
|
||||
preferred name: auto-Three.txt
|
||||
@ -14,7 +22,15 @@ auto-3 -> 10,0
|
||||
/UF -> auto-Three.txt
|
||||
all data streams:
|
||||
/F -> 10,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: d6c7ac7cf295ae133fea186cfd068dab
|
||||
/UF -> 10,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: d6c7ac7cf295ae133fea186cfd068dab
|
||||
auto-Two -> 12,0
|
||||
preferred name: auto-2
|
||||
all names:
|
||||
@ -22,4 +38,12 @@ auto-Two -> 12,0
|
||||
/UF -> auto-2
|
||||
all data streams:
|
||||
/F -> 12,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: 9f991a5669c47a94f9350f53e3953e57
|
||||
/UF -> 12,0
|
||||
creation date: D:20210210091359-05'00'
|
||||
modification date: D:20210210141359Z
|
||||
mime type:
|
||||
checksum: 9f991a5669c47a94f9350f53e3953e57
|
||||
|
@ -5,4 +5,12 @@ auto-1 -> 6,0
|
||||
/UF -> auto-1
|
||||
all data streams:
|
||||
/F -> 6,0
|
||||
creation date: <date>
|
||||
modification date: <date>
|
||||
mime type:
|
||||
checksum: a857d18d3fc23ad412122ef040733331
|
||||
/UF -> 6,0
|
||||
creation date: <date>
|
||||
modification date: <date>
|
||||
mime type:
|
||||
checksum: a857d18d3fc23ad412122ef040733331
|
||||
|
@ -5,19 +5,76 @@
|
||||
},
|
||||
"attachments": {
|
||||
"att1": {
|
||||
"description": "some text",
|
||||
"filespec": "4 0 R",
|
||||
"names": {
|
||||
"/F": "att1.txt",
|
||||
"/UF": "att1.txt"
|
||||
},
|
||||
"preferredcontents": "8 0 R",
|
||||
"preferredname": "att1.txt"
|
||||
"preferredname": "att1.txt",
|
||||
"streams": {
|
||||
"/F": {
|
||||
"checksum": "2e10f186a4cdf5be438747f4bdc2d4d4",
|
||||
"creationdate": "2021-02-07T19:11:21-05:00",
|
||||
"mimetype": "text/plain",
|
||||
"modificationdate": "2021-02-07T19:11:21-05:00"
|
||||
},
|
||||
"/UF": {
|
||||
"checksum": "2e10f186a4cdf5be438747f4bdc2d4d4",
|
||||
"creationdate": "2021-02-07T19:11:21-05:00",
|
||||
"mimetype": "text/plain",
|
||||
"modificationdate": "2021-02-07T19:11:21-05:00"
|
||||
}
|
||||
}
|
||||
},
|
||||
"att2": {
|
||||
"description": null,
|
||||
"filespec": "5 0 R",
|
||||
"names": {
|
||||
"/F": "att2.txt",
|
||||
"/UF": "att2.txt"
|
||||
},
|
||||
"preferredcontents": "10 0 R",
|
||||
"preferredname": "att2.txt"
|
||||
"preferredname": "att2.txt",
|
||||
"streams": {
|
||||
"/F": {
|
||||
"checksum": "2fce9c8228e360ba9b04a1bd1bf63d6b",
|
||||
"creationdate": null,
|
||||
"mimetype": "text/plain",
|
||||
"modificationdate": null
|
||||
},
|
||||
"/UF": {
|
||||
"checksum": "2fce9c8228e360ba9b04a1bd1bf63d6b",
|
||||
"creationdate": null,
|
||||
"mimetype": "text/plain",
|
||||
"modificationdate": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"att3": {
|
||||
"description": null,
|
||||
"filespec": "6 0 R",
|
||||
"names": {
|
||||
"/F": "att3.txt",
|
||||
"/UF": "π.txt"
|
||||
},
|
||||
"preferredcontents": "12 0 R",
|
||||
"preferredname": "π.txt"
|
||||
"preferredname": "π.txt",
|
||||
"streams": {
|
||||
"/F": {
|
||||
"checksum": "2236c155b1d62b7f00285bba081d4336",
|
||||
"creationdate": null,
|
||||
"mimetype": "text/plain",
|
||||
"modificationdate": null
|
||||
},
|
||||
"/UF": {
|
||||
"checksum": "2236c155b1d62b7f00285bba081d4336",
|
||||
"creationdate": null,
|
||||
"mimetype": "text/plain",
|
||||
"modificationdate": null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,15 @@ att1 -> 8,0
|
||||
/UF -> att1.txt
|
||||
all data streams:
|
||||
/F -> 8,0
|
||||
creation date: D:20210207191121-05'00'
|
||||
modification date: D:20210208001122Z
|
||||
mime type: text/plain
|
||||
checksum: 2e10f186a4cdf5be438747f4bdc2d4d4
|
||||
/UF -> 8,0
|
||||
creation date: D:20210207191121-05'00'
|
||||
modification date: D:20210208001122Z
|
||||
mime type: text/plain
|
||||
checksum: 2e10f186a4cdf5be438747f4bdc2d4d4
|
||||
att2 -> 10,0
|
||||
preferred name: att2.txt
|
||||
all names:
|
||||
@ -14,7 +22,15 @@ att2 -> 10,0
|
||||
/UF -> att2.txt
|
||||
all data streams:
|
||||
/F -> 10,0
|
||||
creation date:
|
||||
modification date:
|
||||
mime type: text/plain
|
||||
checksum: 2fce9c8228e360ba9b04a1bd1bf63d6b
|
||||
/UF -> 10,0
|
||||
creation date:
|
||||
modification date:
|
||||
mime type: text/plain
|
||||
checksum: 2fce9c8228e360ba9b04a1bd1bf63d6b
|
||||
att3 -> 12,0
|
||||
preferred name: π.txt
|
||||
all names:
|
||||
@ -22,4 +38,12 @@ att3 -> 12,0
|
||||
/UF -> π.txt
|
||||
all data streams:
|
||||
/F -> 12,0
|
||||
creation date:
|
||||
modification date:
|
||||
mime type: text/plain
|
||||
checksum: 2236c155b1d62b7f00285bba081d4336
|
||||
/UF -> 12,0
|
||||
creation date:
|
||||
modification date:
|
||||
mime type: text/plain
|
||||
checksum: 2236c155b1d62b7f00285bba081d4336
|
||||
|
@ -5,4 +5,12 @@ potato.png -> 6,0
|
||||
/UF -> π.png
|
||||
all data streams:
|
||||
/F -> 6,0
|
||||
creation date: D:20220215153939-05'00'
|
||||
modification date: D:20220215153939-05'00'
|
||||
mime type:
|
||||
checksum: c55e70c0c72d7eaf01230124fe5ff2d9
|
||||
/UF -> 6,0
|
||||
creation date: D:20220215153939-05'00'
|
||||
modification date: D:20220215153939-05'00'
|
||||
mime type:
|
||||
checksum: c55e70c0c72d7eaf01230124fe5ff2d9
|
||||
|
@ -218,7 +218,7 @@ if (defined $tc_log)
|
||||
print_xml(">\n");
|
||||
print_junit("<?xml version=\"1.0\"?>\n" .
|
||||
"<testsuites>\n");
|
||||
my @invalid_test_suites = ();
|
||||
my @failed_test_suites = ();
|
||||
foreach my $test (@tests)
|
||||
{
|
||||
print_and_log("\nRunning $test\n");
|
||||
@ -228,7 +228,7 @@ foreach my $test (@tests)
|
||||
if (scalar(@results) != 5)
|
||||
{
|
||||
print_and_log("test driver $test returned invalid results\n");
|
||||
push(@invalid_test_suites, $test);
|
||||
push(@failed_test_suites, $test);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -263,6 +263,10 @@ foreach my $test (@tests)
|
||||
|
||||
my $passed = (($extra == 0) && ($missing == 0) &&
|
||||
($fails == 0) && ($xpasses == 0));
|
||||
if (! $passed)
|
||||
{
|
||||
push(@failed_test_suites, $test);
|
||||
}
|
||||
|
||||
print_xml(" <testsummary\n" .
|
||||
" overall-outcome=\"" .($passed ? 'pass' : 'fail') . "\"\n".
|
||||
@ -284,7 +288,7 @@ tc_do_final_checks();
|
||||
|
||||
my $okay = ((($totpasses + $totxfails) == $tottests) &&
|
||||
($errors == 0) && ($totmissing == 0) && ($totextra == 0) &&
|
||||
($coverage_okay) && (scalar(@invalid_test_suites) == 0));
|
||||
($coverage_okay) && (scalar(@failed_test_suites) == 0));
|
||||
|
||||
print "\n";
|
||||
print_and_pad("Overall test suite");
|
||||
@ -301,10 +305,10 @@ else
|
||||
}
|
||||
|
||||
my $summary = "\nTESTS COMPLETE. Summary:\n\n";
|
||||
if (@invalid_test_suites)
|
||||
if (@failed_test_suites)
|
||||
{
|
||||
$summary .= "INVALID TEST SUITES:\n";
|
||||
foreach my $t (@invalid_test_suites)
|
||||
$summary .= "FAILED TEST SUITES:\n";
|
||||
foreach my $t (@failed_test_suites)
|
||||
{
|
||||
$summary .= " $t\n";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user