"Fossies" - the Fresh Open Source Software Archive 
Member "unrar/arccmt.cpp" (4 May 2022, 4985 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "arccmt.cpp" see the
Fossies "Dox" file reference documentation.
1 static bool IsAnsiEscComment(const wchar *Data,size_t Size);
2
3 bool Archive::GetComment(Array<wchar> *CmtData)
4 {
5 if (!MainComment)
6 return false;
7 int64 SavePos=Tell();
8 bool Success=DoGetComment(CmtData);
9 Seek(SavePos,SEEK_SET);
10 return Success;
11 }
12
13
14 bool Archive::DoGetComment(Array<wchar> *CmtData)
15 {
16 #ifndef SFX_MODULE
17 uint CmtLength;
18 if (Format==RARFMT14)
19 {
20 Seek(SFXSize+SIZEOF_MAINHEAD14,SEEK_SET);
21 CmtLength=GetByte();
22 CmtLength+=(GetByte()<<8);
23 }
24 else
25 #endif
26 {
27 if (MainHead.CommentInHeader)
28 {
29 // Old style (RAR 2.9) archive comment embedded into the main
30 // archive header.
31 Seek(SFXSize+SIZEOF_MARKHEAD3+SIZEOF_MAINHEAD3,SEEK_SET);
32 if (!ReadHeader() || GetHeaderType()!=HEAD3_CMT)
33 return false;
34 }
35 else
36 {
37 // Current (RAR 3.0+) version of archive comment.
38 Seek(GetStartPos(),SEEK_SET);
39 return SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData);
40 }
41 #ifndef SFX_MODULE
42 // Old style (RAR 2.9) comment header embedded into the main
43 // archive header.
44 if (BrokenHeader || CommHead.HeadSize<SIZEOF_COMMHEAD)
45 {
46 uiMsg(UIERROR_CMTBROKEN,FileName);
47 return false;
48 }
49 CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD;
50 #endif
51 }
52 #ifndef SFX_MODULE
53 if (Format==RARFMT14 && MainHead.PackComment || Format!=RARFMT14 && CommHead.Method!=0x30)
54 {
55 if (Format!=RARFMT14 && (CommHead.UnpVer < 15 || CommHead.UnpVer > VER_UNPACK || CommHead.Method > 0x35))
56 return false;
57 ComprDataIO DataIO;
58 DataIO.SetTestMode(true);
59 uint UnpCmtLength;
60 if (Format==RARFMT14)
61 {
62 #ifdef RAR_NOCRYPT
63 return false;
64 #else
65 UnpCmtLength=GetByte();
66 UnpCmtLength+=(GetByte()<<8);
67 if (CmtLength<2)
68 return false;
69 CmtLength-=2;
70 DataIO.SetCmt13Encryption();
71 CommHead.UnpVer=15;
72 #endif
73 }
74 else
75 UnpCmtLength=CommHead.UnpSize;
76 DataIO.SetFiles(this,NULL);
77 DataIO.EnableShowProgress(false);
78 DataIO.SetPackedSizeToRead(CmtLength);
79 DataIO.UnpHash.Init(HASH_CRC32,1);
80 DataIO.SetNoFileHeader(true); // this->FileHead is not filled yet.
81
82 Unpack CmtUnpack(&DataIO);
83 CmtUnpack.Init(0x10000,false);
84 CmtUnpack.SetDestSize(UnpCmtLength);
85 CmtUnpack.DoUnpack(CommHead.UnpVer,false);
86
87 if (Format!=RARFMT14 && (DataIO.UnpHash.GetCRC32()&0xffff)!=CommHead.CommCRC)
88 {
89 uiMsg(UIERROR_CMTBROKEN,FileName);
90 return false;
91 }
92 else
93 {
94 byte *UnpData;
95 size_t UnpDataSize;
96 DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
97 if (UnpDataSize>0)
98 {
99 #ifdef _WIN_ALL
100 // If we ever decide to extend it to Android, we'll need to alloc
101 // 4x memory for OEM to UTF-8 output here.
102 OemToCharBuffA((char *)UnpData,(char *)UnpData,(DWORD)UnpDataSize);
103 #endif
104 CmtData->Alloc(UnpDataSize+1);
105 memset(CmtData->Addr(0),0,CmtData->Size()*sizeof(wchar));
106 CharToWide((char *)UnpData,CmtData->Addr(0),CmtData->Size());
107 CmtData->Alloc(wcslen(CmtData->Addr(0)));
108 }
109 }
110 }
111 else
112 {
113 if (CmtLength==0)
114 return false;
115 Array<byte> CmtRaw(CmtLength);
116 int ReadSize=Read(&CmtRaw[0],CmtLength);
117 if (ReadSize>=0 && (uint)ReadSize<CmtLength) // Comment is shorter than declared.
118 {
119 CmtLength=ReadSize;
120 CmtRaw.Alloc(CmtLength);
121 }
122
123 if (Format!=RARFMT14 && CommHead.CommCRC!=(~CRC32(0xffffffff,&CmtRaw[0],CmtLength)&0xffff))
124 {
125 uiMsg(UIERROR_CMTBROKEN,FileName);
126 return false;
127 }
128 CmtData->Alloc(CmtLength+1);
129 CmtRaw.Push(0);
130 #ifdef _WIN_ALL
131 // If we ever decide to extend it to Android, we'll need to alloc
132 // 4x memory for OEM to UTF-8 output here.
133 OemToCharA((char *)&CmtRaw[0],(char *)&CmtRaw[0]);
134 #endif
135 CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
136 CmtData->Alloc(wcslen(CmtData->Addr(0)));
137 }
138 #endif
139 return CmtData->Size() > 0;
140 }
141
142
143 bool Archive::ReadCommentData(Array<wchar> *CmtData)
144 {
145 Array<byte> CmtRaw;
146 if (!ReadSubData(&CmtRaw,NULL,false))
147 return false;
148 size_t CmtSize=CmtRaw.Size();
149 CmtRaw.Push(0);
150 CmtData->Alloc(CmtSize+1);
151 if (Format==RARFMT50)
152 UtfToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
153 else
154 if ((SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE)!=0)
155 {
156 RawToWide(&CmtRaw[0],CmtData->Addr(0),CmtSize/2);
157 (*CmtData)[CmtSize/2]=0;
158
159 }
160 else
161 {
162 CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
163 }
164 CmtData->Alloc(wcslen(CmtData->Addr(0))); // Set buffer size to actual comment length.
165 return true;
166 }
167
168
169 void Archive::ViewComment()
170 {
171 if (Cmd->DisableComment)
172 return;
173 Array<wchar> CmtBuf;
174 if (GetComment(&CmtBuf)) // In GUI too, so "Test" command detects broken comments.
175 {
176 size_t CmtSize=CmtBuf.Size();
177 wchar *ChPtr=wcschr(&CmtBuf[0],0x1A);
178 if (ChPtr!=NULL)
179 CmtSize=ChPtr-&CmtBuf[0];
180 mprintf(L"\n");
181 OutComment(&CmtBuf[0],CmtSize);
182 }
183 }
184
185