1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominik Seichter                                *
3  *   domseichter@web.de                                                    *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 
21 #include "../PdfTest.h"
22 #include <iostream>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <cstdio>
26 
27 using namespace PoDoFo;
28 
29 //
30 // Test encoding of names.
31 // pszString : internal representation, ie unencoded name
32 // pszExpectedEncoded: the encoded string PoDoFo should produce
33 //
TestName(const char * pszString,const char * pszExpectedEncoded)34 void TestName( const char* pszString, const char* pszExpectedEncoded )
35 {
36     printf("Testing name: %s\n", pszString );
37 
38     PdfName name( pszString );
39     printf("   -> Expected   Value: %s\n", pszExpectedEncoded );
40     printf("   -> Got        Value: %s\n", name.GetEscapedName().c_str() );
41     printf("   -> Unescaped  Value: %s\n", name.GetName().c_str() );
42 
43     if( strcmp( pszExpectedEncoded, name.GetEscapedName().c_str() ) != 0 )
44     {
45         PODOFO_RAISE_ERROR( ePdfError_TestFailed );
46     }
47 
48     // Ensure the encoded string compares equal to its unencoded
49     // variant
50     if( name != PdfName::FromEscaped(pszExpectedEncoded) )
51     {
52         PODOFO_RAISE_ERROR( ePdfError_TestFailed );
53     }
54 }
55 
TestEncodedName(const char * pszString,const char * pszExpected)56 void TestEncodedName( const char* pszString, const char* pszExpected )
57 {
58     PdfName name( PdfName::FromEscaped(pszString) );
59     printf("Testing encoded name: %s\n", pszString );
60     printf("   -> Expected   Value: %s\n", pszExpected );
61     printf("   -> Got        Value: %s\n", name.GetName().c_str() );
62     printf("   -> Escaped    Value: %s\n", name.GetEscapedName().c_str() );
63 
64     if ( strcmp( pszExpected, name.GetName().c_str() ) != 0 )
65     {
66         PODOFO_RAISE_ERROR( ePdfError_TestFailed );
67     }
68 
69     // Ensure the name compares equal with one constructed from the
70     // expected unescaped form
71     if ( ! (name == PdfName(pszExpected)) )
72     {
73         PODOFO_RAISE_ERROR( ePdfError_TestFailed );
74     }
75 }
76 
TestNameEquality(const char * pszName1,const char * pszName2)77 void TestNameEquality( const char * pszName1, const char* pszName2 )
78 {
79     PdfName name1( PdfName::FromEscaped(pszName1) );
80     PdfName name2( PdfName::FromEscaped(pszName2) );
81 
82     printf("Testing equality of encoded names '%s' and '%s'\n", pszName1, pszName2);
83     printf("   -> Name1    Decoded Value: %s\n", name1.GetName().c_str());
84     printf("   -> Name2    Decoded Value: %s\n", name2.GetName().c_str());
85 
86     if (name1 != name2)
87     {
88         PODOFO_RAISE_ERROR( ePdfError_TestFailed );
89     }
90 }
91 
Test(const char * pszString,EPdfDataType eDataType,const char * pszExpected=NULL)92 void Test( const char* pszString, EPdfDataType eDataType, const char* pszExpected = NULL )
93 {
94     PdfVariant  variant;
95     std::string ret;
96 
97     if( !pszExpected )
98         pszExpected = pszString;
99 
100     printf("Testing with value: %s\n", pszString );
101     PdfTokenizer tokenizer( pszString, strlen( pszString ) );
102 
103     tokenizer.GetNextVariant( variant, NULL );
104 
105     printf("   -> Expected Datatype: %i\n", eDataType );
106     printf("   -> Got      Datatype: %i\n", variant.GetDataType() );
107     if( variant.GetDataType() != eDataType )
108     {
109         PODOFO_RAISE_ERROR( ePdfError_TestFailed );
110     }
111 
112     variant.ToString( ret );
113     printf("   -> Convert To String: %s\n", ret.c_str() );
114     if( strcmp( pszExpected, ret.c_str() ) != 0 )
115     {
116         PODOFO_RAISE_ERROR( ePdfError_TestFailed );
117     }
118 }
119 
main()120 int main()
121 {
122     PdfError   eCode;
123 
124     printf("This test tests the PdfVariant class.\n");
125     printf("---\n");
126 
127     PODOFO_UNIQUEU_PTR<PdfFilter> pFilter( PdfFilterFactory::Create( ePdfFilter_ASCIIHexDecode ) );
128 
129     // testing strings
130     TEST_SAFE_OP( Test( "(Hallo Welt!)", ePdfDataType_String ) );
131     TEST_SAFE_OP( Test( "(Hallo \\(sch�ne\\) Welt!)", ePdfDataType_String ) );
132     TEST_SAFE_OP( Test( "(Balanced () brackets are (ok ()) in PDF Strings)", ePdfDataType_String,
133                         "(Balanced \\(\\) brackets are \\(ok \\(\\)\\) in PDF Strings)" ) );
134     TEST_SAFE_OP( Test( "()", ePdfDataType_String ) );
135     TEST_SAFE_OP( Test( "(Test: \\064)", ePdfDataType_String, "(Test: \064)" ) );
136     TEST_SAFE_OP( Test( "(Test: \\0645)", ePdfDataType_String, "(Test: 45)" ) );
137     TEST_SAFE_OP( Test( "(Test: \\478)", ePdfDataType_String, "(Test: '8)" ) );
138     printf("---\n");
139 
140 
141     // testing HEX Strings
142     TEST_SAFE_OP( Test( "<FFEB0400A0CC>", ePdfDataType_HexString ) );
143     TEST_SAFE_OP( Test( "<FFEB0400A0C>", ePdfDataType_HexString, "<FFEB0400A0C0>" ) );
144     TEST_SAFE_OP( Test( "<>", ePdfDataType_HexString ) );
145     printf("---\n");
146 
147     // testing bool
148     TEST_SAFE_OP( Test( "false", ePdfDataType_Bool ) );
149     TEST_SAFE_OP( Test( "true", ePdfDataType_Bool ) );
150     printf("---\n");
151 
152     // testing null
153     TEST_SAFE_OP( Test( "null", ePdfDataType_Null ) );
154     printf("---\n");
155 
156     // testing numbers
157     TEST_SAFE_OP( Test( "145", ePdfDataType_Number ) );
158     TEST_SAFE_OP( Test( "-12", ePdfDataType_Number ) );
159     TEST_SAFE_OP( Test( "3.140000", ePdfDataType_Real ) );
160     TEST_SAFE_OP( Test( "-2.970000", ePdfDataType_Real ) );
161     TEST_SAFE_OP( Test( "0", ePdfDataType_Number ) );
162     TEST_SAFE_OP_IGNORE( Test( "4.", ePdfDataType_Real ) );
163     printf("---\n");
164 
165     // testing references
166     TEST_SAFE_OP( Test( "2 0 R", ePdfDataType_Reference ) );
167     TEST_SAFE_OP( Test( "3 0 R", ePdfDataType_Reference ) );
168     TEST_SAFE_OP( Test( "4 1 R", ePdfDataType_Reference ) );
169     printf("---\n");
170 
171     // testing names
172     TEST_SAFE_OP( Test( "/Type", ePdfDataType_Name ) );
173     TEST_SAFE_OP( Test( "/Length", ePdfDataType_Name ) );
174     TEST_SAFE_OP( Test( "/Adobe#20Green", ePdfDataType_Name ) );
175     TEST_SAFE_OP( Test( "/$$", ePdfDataType_Name ) );
176     TEST_SAFE_OP( Test( "/1.2", ePdfDataType_Name ) );
177     TEST_SAFE_OP( Test( "/.notdef", ePdfDataType_Name ) );
178     TEST_SAFE_OP( Test( "/@pattern", ePdfDataType_Name ) );
179     TEST_SAFE_OP( Test( "/A;Name_With-Various***Characters?", ePdfDataType_Name ) );
180     TEST_SAFE_OP( Test( "/", ePdfDataType_Name ) ); // empty names are legal, too!
181     printf("---\n");
182 
183     // testing arrays
184     TEST_SAFE_OP_IGNORE( Test( "[]", ePdfDataType_Array ) );  // this test may fail as the formating is different
185     TEST_SAFE_OP( Test( "[ ]", ePdfDataType_Array ) );
186     TEST_SAFE_OP( Test( "[ 1 2 3 4 ]", ePdfDataType_Array ) );
187     TEST_SAFE_OP_IGNORE( Test( "[1 2 3 4]", ePdfDataType_Array ) ); // this test may fail as the formating is different
188     TEST_SAFE_OP( Test( "[ 2 (Hallo Welt!) 3.500000 /FMC ]", ePdfDataType_Array ) );
189     TEST_SAFE_OP( Test( "[ [ 1 2 ] (Hallo Welt!) 3.500000 /FMC ]", ePdfDataType_Array ) );
190     TEST_SAFE_OP_IGNORE( Test( "[/ImageA/ImageB/ImageC]", ePdfDataType_Array ) ); // this test may fail as the formating is different
191     TEST_SAFE_OP_IGNORE( Test( "[<530464995927cef8aaf46eb953b93373><530464995927cef8aaf46eb953b93373>]", ePdfDataType_Array ) );
192     TEST_SAFE_OP_IGNORE( Test( "[ 2 0 R (Test Data) 4 << /Key /Data >> 5 0 R ]", ePdfDataType_Array ) );
193     TEST_SAFE_OP_IGNORE( Test( "[<</key/name>>2 0 R]", ePdfDataType_Array ) );
194     printf("---\n");
195 
196     // Test some names. The first argument is the unencoded representation, the second
197     // is the expected encoded result. The result must not only be /a/ correct encoded
198     // name for the unencoded form, but must be the exact one PoDoFo should produce.
199     TEST_SAFE_OP( TestName( "Length With Spaces", "Length#20With#20Spaces" ) );
200     TEST_SAFE_OP( TestName( "Length\001\002\003Spaces\177",  "Length#01#02#03Spaces#7F" ) );
201     TEST_SAFE_OP( TestName( "Length#01#02#03Spaces#7F", "Length#2301#2302#2303Spaces#237F" ) );
202     TEST_SAFE_OP( TestName( "Tab\tTest", "Tab#09Test" ) );
203     printf("---\n");
204 
205     // Test some pre-encoded names. The first argument is the encoded name that'll be
206     // read from the PDF; the second is the expected representation.
207     TEST_SAFE_OP( TestEncodedName( "PANTONE#205757#20CV", "PANTONE 5757 CV") );
208     TEST_SAFE_OP( TestEncodedName( "paired#28#29parentheses", "paired()parentheses") );
209     TEST_SAFE_OP( TestEncodedName( "The_Key_of_F#23_Minor", "The_Key_of_F#_Minor") );
210     TEST_SAFE_OP( TestEncodedName( "A#42", "AB") );
211     printf("---\n");
212 
213     // Make sure differently encoded names compare equal if their decoded values
214     // are equal.
215     TEST_SAFE_OP( TestNameEquality( "With Spaces", "With#20Spaces" ) );
216     TEST_SAFE_OP( TestNameEquality( "#57#69#74#68#20#53#70#61#63#65#73", "With#20Spaces" ) );
217     printf("---\n");
218 
219     // TODO: Move to AlgorithmTest
220     char* pszHex = static_cast<char*>(malloc( sizeof(char) * 256 ));
221     memset(pszHex, 0, 256);
222     strcpy( pszHex, "Hallo Du schoene Welt!" );
223     pdf_long lLen = strlen( pszHex );
224     char* pszResult = NULL;
225     pdf_long lRes = -1;
226     std::string out;
227 
228     TEST_SAFE_OP( pFilter->Encode( pszHex, lLen, &pszResult, &lRes ) );
229     free( pszHex );
230     pszHex = pszResult;
231     lLen = lRes;
232     out.assign(pszHex, lLen);
233     std::cerr << "Encoded buffer: (" << out << ')' << std::endl;
234 
235     TEST_SAFE_OP( pFilter->Decode( pszHex, lLen, &pszResult, &lRes ) );
236     free( pszHex );
237     pszHex = pszResult;
238     lLen = lRes;
239     out.assign(pszHex, lLen);
240     std::cerr << "Encoded buffer: (" << out << ')' << std::endl;
241 
242     TEST_SAFE_OP( pFilter->Encode( pszHex, lLen, &pszResult, &lRes ) );
243     free( pszHex );
244     pszHex = pszResult;
245     lLen = lRes;
246     out.assign(pszHex, lLen);
247     std::cerr << "Encoded buffer: (" << out << ')' << std::endl;
248 
249     TEST_SAFE_OP( pFilter->Decode( pszHex, lLen, &pszResult, &lRes  ) );
250     free( pszHex );
251     pszHex = pszResult;
252     lLen = lRes;
253     out.assign(pszHex, lLen);
254     std::cerr << "Encoded buffer: (" << out << ')' << std::endl;
255     free( pszHex );
256 
257 
258     // test a hex string containing a whitespace character
259     pszHex = static_cast<char*>(malloc( sizeof(char) * 256 ));
260     strcpy( pszHex, "48616C6C6F2044\n75207363686F656E652057656C7421");
261     lLen = strlen( pszHex );
262 
263     TEST_SAFE_OP( pFilter->Decode( pszHex, lLen, &pszResult, &lRes  ) );
264     free( pszHex );
265     pszHex = pszResult;
266     lLen = lRes;
267     out.assign(pszHex, lLen);
268     std::cerr << "Encoded buffer: (" << out << ')' << std::endl;
269     free( pszResult );
270 
271     // TODO: test variant equality comparisons
272 
273     printf("Test completed with error code: %i\n", eCode.GetError() );
274     return eCode.GetError();
275 }
276