~ubuntu-branches/ubuntu/vivid/unrar-nonfree/vivid

« back to all changes in this revision

Viewing changes to arcread.cpp

  • Committer: Package Import Robot
  • Author(s): Martin Meredith
  • Date: 2015-02-03 12:58:01 UTC
  • mfrom: (1.1.18) (5.1.18 sid)
  • Revision ID: package-import@ubuntu.com-20150203125801-od6ev8cqy1er51vz
Tags: 1:5.2.5-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
44
44
    if ((++Count & 127)==0)
45
45
      Wait();
46
46
    if (GetHeaderType()==HeaderType)
47
 
      return(Size);
 
47
      return Size;
48
48
    SeekToNext();
49
49
  }
50
 
  return(0);
 
50
  return 0;
51
51
}
52
52
 
53
53
 
88
88
  // If block positions are equal to file size, this is not an error.
89
89
  // It can happen when we reached the end of older RAR 1.5 archive,
90
90
  // which did not have the end of archive block.
91
 
  if (CurBlockPos>ArcSize || NextBlockPos>ArcSize)
 
91
  if (CurBlockPos!=ArcSize || NextBlockPos!=ArcSize)
92
92
  {
93
 
#ifndef SHELL_EXT
94
 
    Log(FileName,St(MLogUnexpEOF));
95
 
#endif
 
93
    uiMsg(UIERROR_UNEXPEOF,FileName);
96
94
    ErrHandler.SetErrorCode(RARX_WARNING);
97
95
  }
98
96
}
100
98
 
101
99
void Archive::BrokenHeaderMsg()
102
100
{
103
 
#ifndef SHELL_EXT
104
 
  Log(FileName,St(MHeaderBroken));
105
 
#endif
 
101
  uiMsg(UIERROR_HEADERBROKEN,FileName);
106
102
  BrokenHeader=true;
107
103
  ErrHandler.SetErrorCode(RARX_CRC);
108
104
}
110
106
 
111
107
void Archive::UnkEncVerMsg(const wchar *Name)
112
108
{
113
 
#ifndef SHELL_EXT
114
 
  Log(FileName,St(MUnkEncMethod),Name);
115
 
#endif
 
109
  uiMsg(UIERROR_UNKNOWNENCMETHOD,FileName,Name);
116
110
  ErrHandler.SetErrorCode(RARX_WARNING);
117
111
}
118
112
 
134
128
    if (Read(Salt,SIZE_SALT30)!=SIZE_SALT30)
135
129
    {
136
130
      UnexpEndArcMsg();
137
 
      return(0);
 
131
      return 0;
138
132
    }
139
133
    HeadersCrypt.SetCryptKeys(false,CRYPT_RAR30,&Cmd->Password,Salt,NULL,0,NULL,NULL);
140
134
    Raw.SetCrypt(&HeadersCrypt);
161
155
  if (ShortBlock.HeadSize<SIZEOF_SHORTBLOCKHEAD)
162
156
  {
163
157
    BrokenHeaderMsg();
164
 
    return(0);
 
158
    return 0;
165
159
  }
166
160
 
167
161
  // For simpler further processing we map header types common
316
310
          {
317
311
            EncodeFileName NameCoder;
318
312
            size_t Length=strlen(FileName);
319
 
            if (Length==NameSize)
320
 
              UtfToWide(FileName,hd->FileName,ASIZE(hd->FileName)-1);
321
 
            else
322
 
            {
323
 
              Length++;
324
 
              NameCoder.Decode(FileName,(byte *)FileName+Length,
325
 
                               NameSize-Length,hd->FileName,
326
 
                               ASIZE(hd->FileName));
327
 
            }
 
313
            Length++;
 
314
            NameCoder.Decode(FileName,(byte *)FileName+Length,
 
315
                             NameSize-Length,hd->FileName,
 
316
                             ASIZE(hd->FileName));
328
317
          }
329
318
          else
330
319
            *hd->FileName=0;
365
354
                RecoveryPercent++;
366
355
            }
367
356
          }
 
357
 
 
358
          if (hd->CmpName(SUBHEAD_TYPE_CMT))
 
359
            MainComment=true;
368
360
        }
369
361
        if ((hd->Flags & LHD_SALT)!=0)
370
362
          Raw.GetB(hd->Salt,SIZE_SALT30);
416
408
          // to have anything sensible in file name field, so it is useless
417
409
          // to display the file name.
418
410
          if (!Decrypt)
419
 
          {
420
 
#ifndef SHELL_EXT
421
 
            Log(Archive::FileName,St(MLogFileHead),hd->FileName);
422
 
#endif
423
 
          }
 
411
            uiMsg(UIERROR_FHEADERBROKEN,Archive::FileName,hd->FileName);
424
412
        }
425
413
      }
426
414
      break;
548
536
 
549
537
      if (Decrypt)
550
538
      {
551
 
#ifndef SILENT
552
 
        Log(FileName,St(MEncrBadCRC),FileName);
553
 
#endif
 
539
        uiMsg(UIERROR_CHECKSUMENC,FileName,FileName);
554
540
        FailedHeaderDecryption=true;
555
541
        return 0;
556
542
      }
576
562
  if (Decrypt)
577
563
  {
578
564
#if defined(SHELL_EXT) || defined(RAR_NOCRYPT)
579
 
    return(0);
 
565
    return 0;
580
566
#else
581
567
    RequestArcPassword();
582
568
 
584
570
    if (Read(HeadersInitV,SIZE_INITV)!=SIZE_INITV)
585
571
    {
586
572
      UnexpEndArcMsg();
587
 
      return(0);
 
573
      return 0;
588
574
    }
589
575
 
590
576
    byte PswCheck[SIZE_PSWCHECK];
592
578
    // Verify password validity.
593
579
    if (CryptHead.UsePswCheck && memcmp(PswCheck,CryptHead.PswCheck,SIZE_PSWCHECK)!=0)
594
580
    {
595
 
      Log(FileName,St(MWrongPassword));
 
581
      uiMsg(UIERROR_BADPSW,FileName);
596
582
      FailedHeaderDecryption=true;
597
583
      ErrHandler.SetErrorCode(RARX_BADPWD);
598
584
      return 0;
605
591
  // Header size must not occupy more than 3 variable length integer bytes
606
592
  // resulting in 2 MB maximum header size, so here we read 4 byte CRC32
607
593
  // followed by 3 bytes or less of header size.
608
 
  const size_t FirstReadSize=7;
609
 
  Raw.Read(FirstReadSize);
 
594
  const size_t FirstReadSize=7; // Smallest possible block size.
 
595
  if (Raw.Read(FirstReadSize)<FirstReadSize)
 
596
  {
 
597
    UnexpEndArcMsg();
 
598
    return 0;
 
599
  }
610
600
 
611
601
  ShortBlock.Reset();
612
602
  ShortBlock.HeadCRC=Raw.Get4();
615
605
 
616
606
  if (BlockSize==0 || SizeBytes==0)
617
607
  {
618
 
    UnexpEndArcMsg(); // Incomplete or broken block size field.
 
608
    BrokenHeaderMsg();
619
609
    return 0;
620
610
  }
621
611
 
656
646
 
657
647
    if (Decrypt)
658
648
    {
659
 
#ifndef SILENT
660
 
      Log(FileName,St(MEncrBadCRC),FileName);
661
 
#endif
 
649
      uiMsg(UIERROR_CHECKSUMENC,FileName,FileName);
662
650
      FailedHeaderDecryption=true;
663
651
      return 0;
664
652
    }
741
729
 
742
730
        if (ExtraSize!=0)
743
731
          ProcessExtra50(&Raw,(size_t)ExtraSize,&MainHead);
 
732
 
 
733
#ifdef USE_QOPEN
 
734
        if (MainHead.Locator && MainHead.QOpenOffset>0 && Cmd->QOpenMode!=QOPEN_NONE)
 
735
        {
 
736
          // We seek to QO block in the end of archive when processing
 
737
          // QOpen.Load, so we need to preserve current block positions
 
738
          // to not break normal archive processing by calling function.
 
739
          int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
 
740
          HEADER_TYPE SaveCurHeaderType=CurHeaderType;
 
741
          
 
742
          QOpen.Init(this,false);
 
743
          QOpen.Load(MainHead.QOpenOffset);
 
744
 
 
745
          CurBlockPos=SaveCurBlockPos;
 
746
          NextBlockPos=SaveNextBlockPos;
 
747
          CurHeaderType=SaveCurHeaderType;
 
748
        }
 
749
#endif
744
750
      }
745
751
      break;
746
752
    case HEAD_FILE:
805
811
        Raw.GetB((byte *)FileName,ReadNameSize);
806
812
        FileName[ReadNameSize]=0;
807
813
 
808
 
        UtfToWide(FileName,hd->FileName,ASIZE(hd->FileName)-1);
 
814
        UtfToWide(FileName,hd->FileName,ASIZE(hd->FileName));
809
815
 
810
816
        // Should do it before converting names, because extra fields can
811
817
        // affect name processing, like in case of NTFS streams.
820
826
          ConvertFileHeader(hd);
821
827
        }
822
828
 
 
829
        if (!FileBlock && hd->CmpName(SUBHEAD_TYPE_CMT))
 
830
          MainComment=true;
 
831
 
823
832
          
824
 
        if (BadCRC)
825
 
        {
826
 
          // Add the file name to broken header message displayed above.
827
 
#ifndef SHELL_EXT
828
 
          Log(Archive::FileName,St(MLogFileHead),hd->FileName);
829
 
#endif
830
 
        }
 
833
        if (BadCRC) // Add the file name to broken header message displayed above.
 
834
          uiMsg(UIERROR_FHEADERBROKEN,Archive::FileName,hd->FileName);
831
835
      }
832
836
      break;
833
837
    case HEAD_ENDARC:
882
886
      ErrHandler.Exit(RARX_USERBREAK);
883
887
    }
884
888
#else
885
 
    if (!GetPassword(PASSWORD_ARCHIVE,FileName,&Cmd->Password))
 
889
    if (!uiGetPassword(UIPASSWORD_ARCHIVE,FileName,&Cmd->Password) ||
 
890
        !Cmd->Password.IsSet())
886
891
    {
887
892
      Close();
 
893
      uiMsg(UIERROR_INCERRCOUNT);
888
894
      ErrHandler.Exit(RARX_USERBREAK);
889
895
    }
890
896
#endif
 
897
    Cmd->ManualPassword=true;
891
898
  }
892
899
}
893
900
#endif
1044
1051
              Raw->GetB(UtfName,NameSize);
1045
1052
              UtfName[NameSize]=0;
1046
1053
            }
 
1054
#ifdef _WIN_ALL
 
1055
            UnixSlashToDos(UtfName,UtfName,ASIZE(UtfName));
 
1056
#endif
1047
1057
            UtfToWide(UtfName,hd->RedirName,ASIZE(hd->RedirName));
1048
1058
          }
1049
1059
          break;
1151
1161
    char FileName[NM];
1152
1162
    Raw.GetB((byte *)FileName,Min(NameSize,ASIZE(FileName)));
1153
1163
    FileName[NameSize]=0;
 
1164
    IntToExt(FileName,FileName,ASIZE(FileName));
1154
1165
    CharToWide(FileName,FileHead.FileName,ASIZE(FileHead.FileName));
1155
1166
    ConvertNameCase(FileHead.FileName);
1156
1167
 
1158
1169
      NextBlockPos=CurBlockPos+FileHead.HeadSize+FileHead.PackSize;
1159
1170
    CurHeaderType=HEAD_FILE;
1160
1171
  }
1161
 
  return(NextBlockPos>CurBlockPos ? Raw.Size():0);
 
1172
  return NextBlockPos>CurBlockPos ? Raw.Size() : 0;
1162
1173
}
1163
1174
#endif
1164
1175
 
1191
1202
  // when creating a file or directory. The typical default value
1192
1203
  // for the process umask is S_IWGRP | S_IWOTH (octal 022),
1193
1204
  // resulting in 0644 mode for new files.
 
1205
  // Normally umask is applied automatically when creating a file,
 
1206
  // but we set attributes with chmod later, so we need to calculate
 
1207
  // resulting attributes here. We do it only for non-Unix archives.
 
1208
  // We restore native Unix attributes as is, because it can be backup.
1194
1209
  static mode_t mask = (mode_t) -1;
1195
1210
 
1196
1211
  if (mask == (mode_t) -1)
1304
1319
{
1305
1320
  if (BrokenHeader)
1306
1321
  {
1307
 
#ifndef SHELL_EXT
1308
 
    Log(FileName,St(MSubHeadCorrupt));
1309
 
#endif
 
1322
    uiMsg(UIERROR_SUBHEADERBROKEN,FileName);
1310
1323
    ErrHandler.SetErrorCode(RARX_CRC);
1311
1324
    return false;
1312
1325
  }
1313
1326
  if (SubHead.Method>5 || SubHead.UnpVer>(Format==RARFMT50 ? VER_UNPACK5:VER_UNPACK))
1314
1327
  {
1315
 
#ifndef SHELL_EXT
1316
 
    Log(FileName,St(MSubHeadUnknown));
1317
 
#endif
 
1328
    uiMsg(UIERROR_SUBHEADERUNKNOWN,FileName);
1318
1329
    return false;
1319
1330
  }
1320
1331
 
1330
1341
    if (SubHead.UnpSize>0x1000000)
1331
1342
    {
1332
1343
      // So huge allocation must never happen in valid archives.
1333
 
#ifndef SHELL_EXT
1334
 
      Log(FileName,St(MSubHeadUnknown));
1335
 
#endif
 
1344
      uiMsg(UIERROR_SUBHEADERUNKNOWN,FileName);
1336
1345
      return false;
1337
1346
    }
1338
1347
    UnpData->Alloc((size_t)SubHead.UnpSize);
1359
1368
 
1360
1369
  if (!SubDataIO.UnpHash.Cmp(&SubHead.FileHash,SubHead.UseHashKey ? SubHead.HashKey:NULL))
1361
1370
  {
1362
 
#ifndef SHELL_EXT
1363
 
    Log(FileName,St(MSubHeadDataCRC),SubHead.FileName);
1364
 
#endif
 
1371
    uiMsg(UIERROR_SUBHEADERDATABROKEN,FileName,SubHead.FileName);
1365
1372
    ErrHandler.SetErrorCode(RARX_CRC);
1366
1373
    if (UnpData!=NULL)
1367
1374
      UnpData->Reset();