@@ -296,6 +296,9 @@ static void pdfobj_flag(struct pdf_struct *pdf, struct pdf_obj *obj, enum pdf_fl
296296 case MANY_FILTERS :
297297 s = "more than 2 filters per obj" ;
298298 break ;
299+ case DECRYPTABLE_PDF :
300+ s = "decryptable PDF" ;
301+ break ;
299302 }
300303 cli_dbgmsg ("cli_pdf: %s flagged in object %u %u\n" , s , obj -> id >>8 , obj -> id & 0xff );
301304}
@@ -567,6 +570,8 @@ static int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj)
567570 char * ascii_decoded = NULL ;
568571 int dump = 1 ;
569572
573+ cli_dbgmsg ("pdf_extract_obj: obj %u %u\n" , obj -> id >>8 , obj -> id & 0xff );
574+
570575 /* TODO: call bytecode hook here, allow override dumpability */
571576 if ((!(obj -> flags & (1 << OBJ_STREAM )) ||
572577 (obj -> flags & (1 << OBJ_HASFILTERS )))
@@ -585,7 +590,7 @@ static int pdf_extract_obj(struct pdf_struct *pdf, struct pdf_obj *obj)
585590 }
586591 if (!dump )
587592 return CL_CLEAN ;
588- cli_dbgmsg ("cli_pdf: dumping obj %u %u\n" , obj -> id >>8 , obj -> id );
593+ cli_dbgmsg ("cli_pdf: dumping obj %u %u\n" , obj -> id >>8 , obj -> id & 0xff );
589594 snprintf (fullname , sizeof (fullname ), "%s" PATHSEP "pdf%02u" , pdf -> dir , pdf -> files ++ );
590595 fout = open (fullname ,O_RDWR |O_CREAT |O_EXCL |O_TRUNC |O_BINARY , 0600 );
591596 if (fout < 0 ) {
@@ -907,6 +912,7 @@ static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
907912 q2 = pdf_nextobject (q , bytesleft );
908913 bytesleft -= q2 - q ;
909914 if (!q2 || bytesleft < 0 ) {
915+ cli_dbgmsg ("cli_pdf: %u %u obj: no dictionary\n" , obj -> id >>8 , obj -> id & 0xff );
910916 return ;
911917 }
912918 q3 = memchr (q - 1 , '<' , q2 - q + 1 );
@@ -922,6 +928,7 @@ static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
922928 q2 = pdf_nextobject (q , bytesleft );
923929 bytesleft -= q2 - q ;
924930 if (!q2 || bytesleft < 0 ) {
931+ cli_dbgmsg ("cli_pdf: %u %u obj: broken dictionary\n" , obj -> id >>8 , obj -> id & 0xff );
925932 return ;
926933 }
927934 q3 = memchr (q - 1 , '>' , q2 - q + 1 );
@@ -1262,7 +1269,7 @@ static void check_user_password(struct pdf_struct *pdf, int R, const char *O,
12621269 password_empty = 1 ;
12631270 /* Algorithm 3.2a could be used to recover encryption key */
12641271 }
1265- } else {
1272+ } else if (( R >= 2 ) && ( R <= 4 )) {
12661273 /* 7.6.3.3 Algorithm 2 */
12671274 cli_md5_init (& md5 );
12681275 /* empty password, password == padding */
@@ -1276,9 +1283,9 @@ static void check_user_password(struct pdf_struct *pdf, int R, const char *O,
12761283 cli_md5_update (& md5 , & v , 4 );
12771284 }
12781285 cli_md5_final (result , & md5 );
1286+ if (length > 128 )
1287+ length = 128 ;
12791288 if (R >= 3 ) {
1280- if (length > 128 )
1281- length = 128 ;
12821289 for (i = 0 ;i < 50 ;i ++ ) {
12831290 cli_md5_init (& md5 );
12841291 cli_md5_update (& md5 , result , length /8 );
@@ -1329,6 +1336,11 @@ static void check_user_password(struct pdf_struct *pdf, int R, const char *O,
13291336 cli_dbgmsg ("cli_pdf: invalid revision %d\n" , R );
13301337 }
13311338 }
1339+ else {
1340+ /* Supported R is in {2,3,4,5} */
1341+ cli_dbgmsg ("cli_pdf: R value out of range\n" );
1342+ return ;
1343+ }
13321344 if (password_empty ) {
13331345 cli_dbgmsg ("cli_pdf: user password is empty\n" );
13341346 /* The key we computed above is the key used to encrypt the streams.
@@ -1395,6 +1407,10 @@ static void pdf_handle_enc(struct pdf_struct *pdf)
13951407 cli_dbgmsg ("cli_pdf: invalid R\n" );
13961408 break ;
13971409 }
1410+ if ((R > 5 ) || (R < 2 )) {
1411+ cli_dbgmsg ("cli_pdf: R value outside supported range [2..5]\n" );
1412+ break ;
1413+ }
13981414
13991415 if (R < 5 )
14001416 oulen = 32 ;
0 commit comments