libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

test_ole2.c (25404B)


      1 /*
      2      This file is part of libextractor.
      3      Copyright (C) 2012 Vidyut Samanta and Christian Grothoff
      4 
      5      libextractor is free software; you can redistribute it and/or modify
      6      it under the terms of the GNU General Public License as published
      7      by the Free Software Foundation; either version 3, or (at your
      8      option) any later version.
      9 
     10      libextractor is distributed in the hope that it will be useful, but
     11      WITHOUT ANY WARRANTY; without even the implied warranty of
     12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13      General Public License for more details.
     14 
     15      You should have received a copy of the GNU General Public License
     16      along with libextractor; see the file COPYING.  If not, write to the
     17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     18      Boston, MA 02110-1301, USA.
     19 */
     20 /**
     21  * @file plugins/test_ole2.c
     22  * @brief testcase for ole2 plugin
     23  * @author Christian Grothoff
     24  */
     25 #include "platform.h"
     26 #include "test_lib.h"
     27 
     28 
     29 /**
     30  * Check the general shape of a full text: valid UTF-8, 0-terminated,
     31  * no leading or trailing white space, paragraphs separated by exactly
     32  * "\n\n", no other line breaks, no double spaces.
     33  *
     34  * @param data the full text
     35  * @param data_len number of bytes in @a data, including the 0
     36  * @return 1 if the shape is right
     37  */
     38 static int
     39 fulltext_shape_ok (const char *data,
     40                    size_t data_len)
     41 {
     42   const unsigned char *t = (const unsigned char *) data;
     43   size_t len;
     44   size_t i;
     45 
     46   if ( (data_len < 2) ||
     47        ('\0' != data[data_len - 1]) ||
     48        (strlen (data) != data_len - 1) )
     49     return 0;
     50   len = data_len - 1;
     51   if (isspace (t[0]) || isspace (t[len - 1]))
     52     return 0;
     53   for (i = 0; i < len; i++)
     54   {
     55     if ('\n' == t[i])
     56     {
     57       if ( (i + 2 >= len) ||
     58            ('\n' != t[i + 1]) ||
     59            isspace (t[i + 2]) ||
     60            isspace (t[i - 1]) )
     61         return 0;
     62       i++;
     63       continue;
     64     }
     65     if ( (' ' == t[i]) && (' ' == t[i + 1]) )
     66       return 0;
     67     if ( (t[i] < 0x20) )
     68       return 0;
     69     if (t[i] >= 0x80)
     70     {
     71       unsigned int n;
     72       unsigned int k;
     73 
     74       if ( (t[i] & 0xE0) == 0xC0)
     75         n = 1;
     76       else if ( (t[i] & 0xF0) == 0xE0)
     77         n = 2;
     78       else if ( (t[i] & 0xF8) == 0xF0)
     79         n = 3;
     80       else
     81         return 0;
     82       if (i + n >= len)
     83         return 0;
     84       for (k = 1; k <= n; k++)
     85         if ( (t[i + k] & 0xC0) != 0x80)
     86           return 0;
     87       i += n;
     88     }
     89   }
     90   return 1;
     91 }
     92 
     93 
     94 /**
     95  * Expected start of the full text of ole2_blair.doc (verified against
     96  * "soffice --headless --convert-to txt").
     97  */
     98 #define BLAIR_HEAD \
     99         "IRAQ \xe2\x80\x93 ITS INFRASTRUCTURE OF CONCEALMENT, DECEPTION AND " \
    100         "INTIMIDATION\n\nThis report draws upon a number of sources, "
    101 
    102 /**
    103  * Expected end of the full text of ole2_blair.doc.
    104  */
    105 #define BLAIR_TAIL \
    106         "\n\nThe overall effect of the systems of control and intimidation is " \
    107         "that every Iraqi is suspicious of all except closest family."
    108 
    109 
    110 /**
    111  * Validate the full text of ole2_blair.doc.  Its footer holds a PAGE
    112  * field ("- 19 -"), and its organisation chart ("SADDAM AND HIS SONS") is
    113  * in text boxes; both
    114  * must not show up.
    115  *
    116  * @param data the full text
    117  * @param data_len number of bytes in @a data
    118  * @return 1 if acceptable
    119  */
    120 static int
    121 validate_blair (const void *data,
    122                 size_t data_len)
    123 {
    124   const char *t = data;
    125 
    126   if (! fulltext_shape_ok (t, data_len))
    127     return 0;
    128   return (0 == strncmp (t, BLAIR_HEAD, strlen (BLAIR_HEAD))) &&
    129          (data_len > strlen (BLAIR_TAIL)) &&
    130          (0 == strcmp (t + data_len - 1 - strlen (BLAIR_TAIL),
    131                        BLAIR_TAIL)) &&
    132          (NULL != strstr (t,
    133                           "\n\nBut Iraq has singularly failed to do this."
    134                           "\n\n")) &&
    135          (NULL != strstr (t,
    136                           "Inspection is not a game of \xe2\x80\x9c" "catch "
    137                           "as catch can\xe2\x80\x9d.\xe2\x80\x9d\n\n")) &&
    138          (NULL == strstr (t, "- 19 -")) &&
    139          (NULL == strstr (t, "PAGE")) &&
    140          (NULL == strstr (t, "SADDAM"));
    141 }
    142 
    143 
    144 /**
    145  * Called with each item from the default (no option) run; counts
    146  * #EXTRACTOR_METATYPE_FULL_TEXT items.
    147  *
    148  * @param cls pointer to an `unsigned int` counter
    149  * @param plugin_name unused
    150  * @param type type of the item
    151  * @param format unused
    152  * @param data_mime_type unused
    153  * @param data unused
    154  * @param data_len unused
    155  * @return 0 (continue)
    156  */
    157 static int
    158 count_fulltext (void *cls,
    159                 const char *plugin_name,
    160                 enum EXTRACTOR_MetaType type,
    161                 enum EXTRACTOR_MetaFormat format,
    162                 const char *data_mime_type,
    163                 const char *data,
    164                 size_t data_len)
    165 {
    166   unsigned int *cnt = cls;
    167 
    168   (void) plugin_name;
    169   (void) format;
    170   (void) data_mime_type;
    171   (void) data;
    172   (void) data_len;
    173   if (EXTRACTOR_METATYPE_FULL_TEXT == type)
    174     (*cnt)++;
    175   return 0;
    176 }
    177 
    178 
    179 /**
    180  * Closure for #capture_fulltext.
    181  */
    182 struct Capture
    183 {
    184   /**
    185    * Number of full text items seen.
    186    */
    187   unsigned int cnt;
    188 
    189   /**
    190    * Copy of the last full text seen, or NULL.
    191    */
    192   char *text;
    193 };
    194 
    195 
    196 /**
    197  * Called with each item; remembers the full text.
    198  *
    199  * @param cls a `struct Capture`
    200  * @param plugin_name unused
    201  * @param type type of the item
    202  * @param format unused
    203  * @param data_mime_type unused
    204  * @param data the item
    205  * @param data_len number of bytes in @a data
    206  * @return 0 (continue)
    207  */
    208 static int
    209 capture_fulltext (void *cls,
    210                   const char *plugin_name,
    211                   enum EXTRACTOR_MetaType type,
    212                   enum EXTRACTOR_MetaFormat format,
    213                   const char *data_mime_type,
    214                   const char *data,
    215                   size_t data_len)
    216 {
    217   struct Capture *cap = cls;
    218 
    219   (void) plugin_name;
    220   (void) format;
    221   (void) data_mime_type;
    222   if (EXTRACTOR_METATYPE_FULL_TEXT != type)
    223     return 0;
    224   cap->cnt++;
    225   free (cap->text);
    226   cap->text = NULL;
    227   if ( (0 < data_len) &&
    228        ('\0' == data[data_len - 1]) )
    229     cap->text = strdup (data);
    230   return 0;
    231 }
    232 
    233 
    234 /**
    235  * Run the plugin with configuration @a config on each of @a files and
    236  * compare the full text with @a expected.
    237  *
    238  * @param config plugin name and options
    239  * @param files NULL-terminated list of files
    240  * @param expected expected full text for each file, NULL for none
    241  * @return 0 on success
    242  */
    243 static int
    244 check_fulltext (const char *config,
    245                 const char *const *files,
    246                 const char *const *expected)
    247 {
    248   struct EXTRACTOR_PluginList *pl;
    249   unsigned int i;
    250   int ret = 0;
    251 
    252   pl = EXTRACTOR_plugin_add_config (NULL,
    253                                     config,
    254                                     EXTRACTOR_OPTION_DEFAULT_POLICY);
    255   for (i = 0; NULL != files[i]; i++)
    256   {
    257     struct Capture cap = { 0, NULL };
    258 
    259     EXTRACTOR_extract (pl,
    260                        files[i],
    261                        NULL, 0,
    262                        &capture_fulltext,
    263                        &cap);
    264     if (NULL == expected[i])
    265     {
    266       if (0 != cap.cnt)
    267       {
    268         fprintf (stderr,
    269                  "%s: unexpected full text from %s\n",
    270                  config,
    271                  files[i]);
    272         ret = 1;
    273       }
    274     }
    275     else if ( (1 != cap.cnt) ||
    276               (NULL == cap.text) ||
    277               (! fulltext_shape_ok (cap.text, strlen (cap.text) + 1)) ||
    278               (0 != strcmp (cap.text, expected[i])) )
    279     {
    280       fprintf (stderr,
    281                "%s: wrong full text from %s: got `%s'\n",
    282                config,
    283                files[i],
    284                (NULL == cap.text) ? "(none)" : cap.text);
    285       ret = 1;
    286     }
    287     free (cap.text);
    288   }
    289   EXTRACTOR_plugin_remove_all (pl);
    290   return ret;
    291 }
    292 
    293 
    294 /**
    295  * Main function for the OLE2 testcase.
    296  *
    297  * @param argc number of arguments (ignored)
    298  * @param argv arguments (ignored)
    299  * @return 0 on success
    300  */
    301 int
    302 main (int argc, char *argv[])
    303 {
    304   struct SolutionData ole2_msword_sol[] = {
    305     {
    306       EXTRACTOR_METATYPE_CREATOR,
    307       EXTRACTOR_METAFORMAT_UTF8,
    308       "text/plain",
    309       "Nils Durner",
    310       strlen ("Nils Durner") + 1,
    311       0
    312     },
    313     {
    314       EXTRACTOR_METATYPE_UNKNOWN_DATE,
    315       EXTRACTOR_METAFORMAT_UTF8,
    316       "text/plain",
    317       "2005-03-21T06:11:12Z",
    318       strlen ("2005-03-21T06:11:12Z") + 1,
    319       0
    320     },
    321     {
    322       EXTRACTOR_METATYPE_DESCRIPTION,
    323       EXTRACTOR_METAFORMAT_UTF8,
    324       "text/plain",
    325       "This is a small document to test meta data extraction by GNU libextractor.",
    326       strlen (
    327         "This is a small document to test meta data extraction by GNU libextractor.")
    328       + 1,
    329       0
    330     },
    331     {
    332       EXTRACTOR_METATYPE_KEYWORDS,
    333       EXTRACTOR_METAFORMAT_UTF8,
    334       "text/plain",
    335       "ole ole2 eole2extractor",
    336       strlen ("ole ole2 eole2extractor") + 1,
    337       0
    338     },
    339     {
    340       EXTRACTOR_METATYPE_SUBJECT,
    341       EXTRACTOR_METAFORMAT_UTF8,
    342       "text/plain",
    343       "GNU libextractor",
    344       strlen ("GNU libextractor") + 1,
    345       0
    346     },
    347     {
    348       EXTRACTOR_METATYPE_TITLE,
    349       EXTRACTOR_METAFORMAT_UTF8,
    350       "text/plain",
    351       "Testcase for the ole2 extractor",
    352       strlen ("Testcase for the ole2 extractor") + 1,
    353       0
    354     },
    355     {
    356       EXTRACTOR_METATYPE_LAST_SAVED_BY,
    357       EXTRACTOR_METAFORMAT_UTF8,
    358       "text/plain",
    359       "Nils Durner",
    360       strlen ("Nils Durner") + 1,
    361       0
    362     },
    363     {
    364       EXTRACTOR_METATYPE_CREATION_DATE,
    365       EXTRACTOR_METAFORMAT_UTF8,
    366       "text/plain",
    367       "2005-03-21T06:10:19Z",
    368       strlen ("2005-03-21T06:10:19Z") + 1,
    369       0
    370     },
    371     {
    372       EXTRACTOR_METATYPE_EDITING_CYCLES,
    373       EXTRACTOR_METAFORMAT_UTF8,
    374       "text/plain",
    375       "2",
    376       strlen ("2") + 1,
    377       0
    378     },
    379     {
    380       EXTRACTOR_METATYPE_AUTHORING_OS,
    381       EXTRACTOR_METAFORMAT_UTF8,
    382       "text/plain",
    383       "Windows 1.0",
    384       strlen ("Windows 1.0") + 1,
    385       0
    386     },
    387     /* only expected with the "fulltext" option; its 'solved' is -1
    388        (end of list) for the default run */
    389     {
    390       EXTRACTOR_METATYPE_FULL_TEXT,
    391       EXTRACTOR_METAFORMAT_UTF8,
    392       "text/plain",
    393       "This is a test document for libextractor.",
    394       strlen ("This is a test document for libextractor.") + 1,
    395       -1
    396     },
    397     { 0, 0, NULL, NULL, 0, -1 }
    398   };
    399 
    400   struct SolutionData ole2_starwriter_sol[] = {
    401     {
    402       EXTRACTOR_METATYPE_CREATOR,
    403       EXTRACTOR_METAFORMAT_UTF8,
    404       "text/plain",
    405       "Christian Grothoff",
    406       strlen ("Christian Grothoff") + 1,
    407       0
    408     },
    409     {
    410       EXTRACTOR_METATYPE_UNKNOWN_DATE,
    411       EXTRACTOR_METAFORMAT_UTF8,
    412       "text/plain",
    413       "2004-09-24T02:54:31Z",
    414       strlen ("2004-09-24T02:54:31Z") + 1,
    415       0
    416     },
    417     {
    418       EXTRACTOR_METATYPE_DESCRIPTION,
    419       EXTRACTOR_METAFORMAT_UTF8,
    420       "text/plain",
    421       "The comments",
    422       strlen ("The comments") + 1,
    423       0
    424     },
    425     {
    426       EXTRACTOR_METATYPE_KEYWORDS,
    427       EXTRACTOR_METAFORMAT_UTF8,
    428       "text/plain",
    429       "The Keywords",
    430       strlen ("The Keywords") + 1,
    431       0
    432     },
    433     {
    434       EXTRACTOR_METATYPE_SUBJECT,
    435       EXTRACTOR_METAFORMAT_UTF8,
    436       "text/plain",
    437       "The Subject",
    438       strlen ("The Subject") + 1,
    439       0
    440     },
    441     {
    442       EXTRACTOR_METATYPE_TITLE,
    443       EXTRACTOR_METAFORMAT_UTF8,
    444       "text/plain",
    445       "The Title",
    446       strlen ("The Title") + 1,
    447       0
    448     },
    449     {
    450       EXTRACTOR_METATYPE_LAST_SAVED_BY,
    451       EXTRACTOR_METAFORMAT_UTF8,
    452       "text/plain",
    453       "Christian Grothoff",
    454       strlen ("Christian Grothoff") + 1,
    455       0
    456     },
    457     {
    458       EXTRACTOR_METATYPE_CREATION_DATE,
    459       EXTRACTOR_METAFORMAT_UTF8,
    460       "text/plain",
    461       "2004-09-24T02:53:15Z",
    462       strlen ("2004-09-24T02:53:15Z") + 1,
    463       0
    464     },
    465     {
    466       EXTRACTOR_METATYPE_EDITING_CYCLES,
    467       EXTRACTOR_METAFORMAT_UTF8,
    468       "text/plain",
    469       "4",
    470       strlen ("4") + 1,
    471       0
    472     },
    473     {
    474       EXTRACTOR_METATYPE_TITLE,
    475       EXTRACTOR_METAFORMAT_UTF8,
    476       "text/plain",
    477       "The Title",
    478       strlen ("The Title") + 1,
    479       0
    480     },
    481     {
    482       EXTRACTOR_METATYPE_SUBJECT,
    483       EXTRACTOR_METAFORMAT_UTF8,
    484       "text/plain",
    485       "The Subject",
    486       strlen ("The Subject") + 1,
    487       0
    488     },
    489     {
    490       EXTRACTOR_METATYPE_COMMENT,
    491       EXTRACTOR_METAFORMAT_UTF8,
    492       "text/plain",
    493       "The comments",
    494       strlen ("The comments") + 1,
    495       0
    496     },
    497     {
    498       EXTRACTOR_METATYPE_KEYWORDS,
    499       EXTRACTOR_METAFORMAT_UTF8,
    500       "text/plain",
    501       "The Keywords",
    502       strlen ("The Keywords") + 1,
    503       0
    504     },
    505     {
    506       EXTRACTOR_METATYPE_AUTHORING_OS,
    507       EXTRACTOR_METAFORMAT_UTF8,
    508       "text/plain",
    509       "Windows (16 bit) 1.0",
    510       strlen ("Windows (16 bit) 1.0") + 1,
    511       0
    512     },
    513     { 0, 0, NULL, NULL, 0, -1 }
    514   };
    515 #if HAVE_ICONV
    516   struct SolutionData ole2_blair_sol[] = {
    517     {
    518       EXTRACTOR_METATYPE_LANGUAGE,
    519       EXTRACTOR_METAFORMAT_UTF8,
    520       "text/plain",
    521       "U.S. English",
    522       strlen ("U.S. English") + 1,
    523       0
    524     },
    525     {
    526       EXTRACTOR_METATYPE_CREATOR,
    527       EXTRACTOR_METAFORMAT_UTF8,
    528       "text/plain",
    529       "default",
    530       strlen ("default") + 1,
    531       0
    532     },
    533     {
    534       EXTRACTOR_METATYPE_UNKNOWN_DATE,
    535       EXTRACTOR_METAFORMAT_UTF8,
    536       "text/plain",
    537       "2003-02-03T11:18:00Z",
    538       strlen ("2003-02-03T11:18:00Z") + 1,
    539       0
    540     },
    541     {
    542       EXTRACTOR_METATYPE_TITLE,
    543       EXTRACTOR_METAFORMAT_UTF8,
    544       "text/plain",
    545       "Iraq- ITS INFRASTRUCTURE OF CONCEALMENT, DECEPTION AND INTIMIDATION",
    546       strlen (
    547         "Iraq- ITS INFRASTRUCTURE OF CONCEALMENT, DECEPTION AND INTIMIDATION")
    548       + 1,
    549       0
    550     },
    551     {
    552       EXTRACTOR_METATYPE_CHARACTER_COUNT,
    553       EXTRACTOR_METAFORMAT_UTF8,
    554       "text/plain",
    555       "22090",
    556       strlen ("22090") + 1,
    557       0
    558     },
    559     {
    560       EXTRACTOR_METATYPE_LAST_SAVED_BY,
    561       EXTRACTOR_METAFORMAT_UTF8,
    562       "text/plain",
    563       "MKhan",
    564       strlen ("MKhan") + 1,
    565       0
    566     },
    567     {
    568       EXTRACTOR_METATYPE_PAGE_COUNT,
    569       EXTRACTOR_METAFORMAT_UTF8,
    570       "text/plain",
    571       "1",
    572       strlen ("1") + 1,
    573       0
    574     },
    575     {
    576       EXTRACTOR_METATYPE_WORD_COUNT,
    577       EXTRACTOR_METAFORMAT_UTF8,
    578       "text/plain",
    579       "3875",
    580       strlen ("3875") + 1,
    581       0
    582     },
    583     {
    584       EXTRACTOR_METATYPE_CREATION_DATE,
    585       EXTRACTOR_METAFORMAT_UTF8,
    586       "text/plain",
    587       "2003-02-03T09:31:00Z",
    588       strlen ("2003-02-03T09:31:00Z") + 1,
    589       0
    590     },
    591     {
    592       EXTRACTOR_METATYPE_EDITING_CYCLES,
    593       EXTRACTOR_METAFORMAT_UTF8,
    594       "text/plain",
    595       "4",
    596       strlen ("4") + 1,
    597       0
    598     },
    599     {
    600       EXTRACTOR_METATYPE_MIMETYPE,
    601       EXTRACTOR_METAFORMAT_UTF8,
    602       "text/plain",
    603       "application/vnd.ms-files",
    604       strlen ("application/vnd.ms-files") + 1,
    605       0
    606     },
    607     {
    608       EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE,
    609       EXTRACTOR_METAFORMAT_UTF8,
    610       "text/plain",
    611       "Microsoft Word 8.0",
    612       strlen ("Microsoft Word 8.0") + 1,
    613       0
    614     },
    615     {
    616       EXTRACTOR_METATYPE_TEMPLATE,
    617       EXTRACTOR_METAFORMAT_UTF8,
    618       "text/plain",
    619       "Normal.dot",
    620       strlen ("Normal.dot") + 1,
    621       0
    622     },
    623     {
    624       EXTRACTOR_METATYPE_LINE_COUNT,
    625       EXTRACTOR_METAFORMAT_UTF8,
    626       "text/plain",
    627       "184",
    628       strlen ("184") + 1,
    629       0
    630     },
    631     {
    632       EXTRACTOR_METATYPE_PARAGRAPH_COUNT,
    633       EXTRACTOR_METAFORMAT_UTF8,
    634       "text/plain",
    635       "44",
    636       strlen ("44") + 1,
    637       0
    638     },
    639     {
    640       EXTRACTOR_METATYPE_REVISION_HISTORY,
    641       EXTRACTOR_METAFORMAT_UTF8,
    642       "text/plain",
    643       "Revision #0: Author `cic22' worked on `C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd'",
    644       strlen (
    645         "Revision #0: Author `cic22' worked on `C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd'")
    646       + 1,
    647       0
    648     },
    649     {
    650       EXTRACTOR_METATYPE_REVISION_HISTORY,
    651       EXTRACTOR_METAFORMAT_UTF8,
    652       "text/plain",
    653       "Revision #1: Author `cic22' worked on `C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd'",
    654       strlen (
    655         "Revision #1: Author `cic22' worked on `C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd'")
    656       + 1,
    657       0
    658     },
    659     {
    660       EXTRACTOR_METATYPE_REVISION_HISTORY,
    661       EXTRACTOR_METAFORMAT_UTF8,
    662       "text/plain",
    663       "Revision #2: Author `cic22' worked on `C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd'",
    664       strlen (
    665         "Revision #2: Author `cic22' worked on `C:\\DOCUME~1\\phamill\\LOCALS~1\\Temp\\AutoRecovery save of Iraq - security.asd'")
    666       + 1,
    667       0
    668     },
    669     {
    670       EXTRACTOR_METATYPE_REVISION_HISTORY,
    671       EXTRACTOR_METAFORMAT_UTF8,
    672       "text/plain",
    673       "Revision #3: Author `JPratt' worked on `C:\\TEMP\\Iraq - security.doc'",
    674       strlen (
    675         "Revision #3: Author `JPratt' worked on `C:\\TEMP\\Iraq - security.doc'")
    676       + 1,
    677       0
    678     },
    679     {
    680       EXTRACTOR_METATYPE_REVISION_HISTORY,
    681       EXTRACTOR_METAFORMAT_UTF8,
    682       "text/plain",
    683       "Revision #4: Author `JPratt' worked on `A:\\Iraq - security.doc'",
    684       strlen (
    685         "Revision #4: Author `JPratt' worked on `A:\\Iraq - security.doc'") + 1,
    686       0
    687     },
    688     {
    689       EXTRACTOR_METATYPE_REVISION_HISTORY,
    690       EXTRACTOR_METAFORMAT_UTF8,
    691       "text/plain",
    692       "Revision #5: Author `ablackshaw' worked on `C:\\ABlackshaw\\Iraq - security.doc'",
    693       strlen (
    694         "Revision #5: Author `ablackshaw' worked on `C:\\ABlackshaw\\Iraq - security.doc'")
    695       + 1,
    696       0
    697     },
    698     {
    699       EXTRACTOR_METATYPE_REVISION_HISTORY,
    700       EXTRACTOR_METAFORMAT_UTF8,
    701       "text/plain",
    702       "Revision #6: Author `ablackshaw' worked on `C:\\ABlackshaw\\A;Iraq - security.doc'",
    703       strlen (
    704         "Revision #6: Author `ablackshaw' worked on `C:\\ABlackshaw\\A;Iraq - security.doc'")
    705       + 1,
    706       0
    707     },
    708     {
    709       EXTRACTOR_METATYPE_REVISION_HISTORY,
    710       EXTRACTOR_METAFORMAT_UTF8,
    711       "text/plain",
    712       "Revision #7: Author `ablackshaw' worked on `A:\\Iraq - security.doc'",
    713       strlen (
    714         "Revision #7: Author `ablackshaw' worked on `A:\\Iraq - security.doc'")
    715       + 1,
    716       0
    717     },
    718     {
    719       EXTRACTOR_METATYPE_REVISION_HISTORY,
    720       EXTRACTOR_METAFORMAT_UTF8,
    721       "text/plain",
    722       "Revision #8: Author `MKhan' worked on `C:\\TEMP\\Iraq - security.doc'",
    723       strlen (
    724         "Revision #8: Author `MKhan' worked on `C:\\TEMP\\Iraq - security.doc'")
    725       + 1,
    726       0
    727     },
    728     {
    729       EXTRACTOR_METATYPE_REVISION_HISTORY,
    730       EXTRACTOR_METAFORMAT_UTF8,
    731       "text/plain",
    732       "Revision #9: Author `MKhan' worked on `C:\\WINNT\\Profiles\\mkhan\\Desktop\\Iraq.doc'",
    733       strlen (
    734         "Revision #9: Author `MKhan' worked on `C:\\WINNT\\Profiles\\mkhan\\Desktop\\Iraq.doc'")
    735       + 1,
    736       0
    737     },
    738     {
    739       EXTRACTOR_METATYPE_AUTHORING_OS,
    740       EXTRACTOR_METAFORMAT_UTF8,
    741       "text/plain",
    742       "Windows 4.0",
    743       strlen ("Windows 4.0") + 1,
    744       0
    745     },
    746     /* only expected with the "fulltext" option */
    747     {
    748       EXTRACTOR_METATYPE_FULL_TEXT,
    749       EXTRACTOR_METAFORMAT_UTF8,
    750       "text/plain",
    751       "^IRAQ",
    752       0,
    753       -1,
    754       1,
    755       &validate_blair
    756     },
    757     { 0, 0, NULL, NULL, 0, -1 }
    758   };
    759 #endif
    760   struct SolutionData ole2_excel_sol[] = {
    761     {
    762       EXTRACTOR_METATYPE_CREATOR,
    763       EXTRACTOR_METAFORMAT_UTF8,
    764       "text/plain",
    765       "JV",
    766       strlen ("JV") + 1,
    767       0
    768     },
    769     {
    770       EXTRACTOR_METATYPE_LAST_SAVED_BY,
    771       EXTRACTOR_METAFORMAT_UTF8,
    772       "text/plain",
    773       "JV",
    774       strlen ("JV") + 1,
    775       0
    776     },
    777     {
    778       EXTRACTOR_METATYPE_CREATION_DATE,
    779       EXTRACTOR_METAFORMAT_UTF8,
    780       "text/plain",
    781       "2002-03-20T21:26:28Z",
    782       strlen ("2002-03-20T21:26:28Z") + 1,
    783       0
    784     },
    785     {
    786       EXTRACTOR_METATYPE_MIMETYPE,
    787       EXTRACTOR_METAFORMAT_UTF8,
    788       "text/plain",
    789       "application/vnd.ms-files",
    790       strlen ("application/vnd.ms-files") + 1,
    791       0
    792     },
    793     {
    794       EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE,
    795       EXTRACTOR_METAFORMAT_UTF8,
    796       "text/plain",
    797       "Microsoft Excel",
    798       strlen ("Microsoft Excel") + 1,
    799       0
    800     },
    801     {
    802       EXTRACTOR_METATYPE_AUTHORING_OS,
    803       EXTRACTOR_METAFORMAT_UTF8,
    804       "text/plain",
    805       "Macintosh 3.10",
    806       strlen ("Macintosh 3.10") + 1,
    807       0
    808     },
    809     /* The WRITEACCESS record of the File Protection Block names the
    810        user that saved the file independently of the summary
    811        information; here both agree, but they often do not. */
    812     {
    813       EXTRACTOR_METATYPE_LAST_SAVED_BY,
    814       EXTRACTOR_METAFORMAT_UTF8,
    815       "text/plain",
    816       "JV",
    817       strlen ("JV") + 1,
    818       0
    819     },
    820     { 0, 0, NULL, NULL, 0, -1 }
    821   };
    822 
    823   /* A PowerPoint presentation.  The `Current User' stream records who
    824      last opened the file for editing; note that it disagrees with both
    825      the author and the last-saved-by of the summary information. */
    826   struct SolutionData ole2_powerpoint_sol[] = {
    827     {
    828       EXTRACTOR_METATYPE_LAST_SAVED_BY,
    829       EXTRACTOR_METAFORMAT_UTF8,
    830       "text/plain",
    831       "FDA.CDER",
    832       strlen ("FDA.CDER") + 1,
    833       0
    834     },
    835     {
    836       EXTRACTOR_METATYPE_LAST_SAVED_BY,
    837       EXTRACTOR_METAFORMAT_UTF8,
    838       "text/plain",
    839       "CDER USER",
    840       strlen ("CDER USER") + 1,
    841       0
    842     },
    843     {
    844       EXTRACTOR_METATYPE_CREATOR,
    845       EXTRACTOR_METAFORMAT_UTF8,
    846       "text/plain",
    847       "CDER.USER",
    848       strlen ("CDER.USER") + 1,
    849       0
    850     },
    851     {
    852       EXTRACTOR_METATYPE_AUTHORING_OS,
    853       EXTRACTOR_METAFORMAT_UTF8,
    854       "text/plain",
    855       "Windows 5.0",
    856       strlen ("Windows 5.0") + 1,
    857       0
    858     },
    859     {
    860       EXTRACTOR_METATYPE_TITLE,
    861       EXTRACTOR_METAFORMAT_UTF8,
    862       "text/plain",
    863       " Topical Dosage Forms Classification/Nomenclature Introduction",
    864       strlen (" Topical Dosage Forms Classification/Nomenclature Introduction")
    865       + 1,
    866       0
    867     },
    868     {
    869       EXTRACTOR_METATYPE_UNKNOWN_DATE,
    870       EXTRACTOR_METAFORMAT_UTF8,
    871       "text/plain",
    872       "2003-03-07T16:12:40Z",
    873       strlen ("2003-03-07T16:12:40Z") + 1,
    874       0
    875     },
    876     {
    877       EXTRACTOR_METATYPE_CREATION_DATE,
    878       EXTRACTOR_METAFORMAT_UTF8,
    879       "text/plain",
    880       "2003-02-19T00:20:15Z",
    881       strlen ("2003-02-19T00:20:15Z") + 1,
    882       0
    883     },
    884     {
    885       EXTRACTOR_METATYPE_EDITING_CYCLES,
    886       EXTRACTOR_METAFORMAT_UTF8,
    887       "text/plain",
    888       "5",
    889       strlen ("5") + 1,
    890       0
    891     },
    892     {
    893       EXTRACTOR_METATYPE_WORD_COUNT,
    894       EXTRACTOR_METAFORMAT_UTF8,
    895       "text/plain",
    896       "228",
    897       strlen ("228") + 1,
    898       0
    899     },
    900     {
    901       EXTRACTOR_METATYPE_PARAGRAPH_COUNT,
    902       EXTRACTOR_METAFORMAT_UTF8,
    903       "text/plain",
    904       "36",
    905       strlen ("36") + 1,
    906       0
    907     },
    908     {
    909       EXTRACTOR_METATYPE_MIMETYPE,
    910       EXTRACTOR_METAFORMAT_UTF8,
    911       "text/plain",
    912       "application/vnd.ms-files",
    913       strlen ("application/vnd.ms-files") + 1,
    914       0
    915     },
    916     {
    917       EXTRACTOR_METATYPE_CREATED_BY_SOFTWARE,
    918       EXTRACTOR_METAFORMAT_UTF8,
    919       "text/plain",
    920       "Microsoft PowerPoint",
    921       strlen ("Microsoft PowerPoint") + 1,
    922       0
    923     },
    924     {
    925       EXTRACTOR_METATYPE_TEMPLATE,
    926       EXTRACTOR_METAFORMAT_UTF8,
    927       "text/plain",
    928       "C:\\Program Files\\Microsoft Office\\Templates\\Blank Presentation.pot",
    929       strlen (
    930         "C:\\Program Files\\Microsoft Office\\Templates\\Blank Presentation.pot")
    931       + 1,
    932       0
    933     },
    934     { 0, 0, NULL, NULL, 0, -1 }
    935   };
    936 
    937   struct ProblemSet ps[] = {
    938     { "testdata/ole2_msword.doc",
    939       ole2_msword_sol },
    940     { "testdata/ole2_starwriter40.sdw",
    941       ole2_starwriter_sol },
    942 #if HAVE_ICONV
    943     { "testdata/ole2_blair.doc",
    944       ole2_blair_sol },
    945 #endif
    946     { "testdata/ole2_excel.xls",
    947       ole2_excel_sol },
    948     { "testdata/ole2_powerpoint.ppt",
    949       ole2_powerpoint_sol },
    950     { NULL, NULL }
    951   };
    952   /* ole2_fulltext.doc is odf_fulltext.odt converted by LibreOffice (see
    953      contrib/gen_odf_testdata.sh); its header/footer, footnote, comment
    954      and PAGE/NUMPAGES fields must not show up.  The bookmark reference
    955      got lost in the conversion. */
    956   const char *const ft_files[] = {
    957     "testdata/ole2_fulltext.doc",
    958     "testdata/ole2_starwriter40.sdw",
    959     "testdata/ole2_excel.xls",
    960     "testdata/ole2_powerpoint.ppt",
    961     NULL
    962   };
    963   const char *const ft_expected[] = {
    964     "Synthetic Heading\n\n"
    965     "First paragraph with spaces and a tab and a break; entities & <tag> "
    966     "\xe2\x98\xba \xe2\x82\xac and the sentence continues.\n\n"
    967     "This is page of pages.\n\n"
    968     "List item one\n\n"
    969     "List item two\n\n"
    970     "Cell A1\n\nCell B1\n\nCell A2\n\nCell B2\n\n"
    971     "See for details.\n\n"
    972     "Last paragraph.",
    973     NULL,
    974     NULL,
    975     NULL
    976   };
    977   const char *const no_ft_expected[] = {
    978     NULL, NULL, NULL, NULL
    979   };
    980   const char *const default_files[] = {
    981     "testdata/ole2_msword.doc",
    982     "testdata/ole2_blair.doc",
    983     NULL
    984   };
    985   int ret;
    986   unsigned int i;
    987 
    988   if (0 != (ret = ET_main ("ole2", ps)))
    989     return ret;
    990   if (0 != check_fulltext ("ole2", ft_files, no_ft_expected))
    991     return 1;
    992   if (0 != check_fulltext ("ole2", default_files, no_ft_expected))
    993     return 1;
    994   for (i = 0; -1 != ole2_msword_sol[i].solved; i++)
    995     ;
    996   ole2_msword_sol[i].solved = 0;
    997 #if HAVE_ICONV
    998   for (i = 0; -1 != ole2_blair_sol[i].solved; i++)
    999     ;
   1000   ole2_blair_sol[i].solved = 0;
   1001 #endif
   1002   if (0 != (ret = ET_main ("ole2(fulltext)", ps)))
   1003     return ret;
   1004   return check_fulltext ("ole2(fulltext)", ft_files, ft_expected);
   1005 }
   1006 
   1007 
   1008 /* end of test_ole2.c */