OLD | NEW |
---|---|
1 // Copyright 2016 PDFium Authors. All rights reserved. | 1 // Copyright 2016 PDFium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
6 | 6 |
7 #include "core/fpdfapi/parser/cpdf_parser.h" | 7 #include "core/fpdfapi/parser/cpdf_parser.h" |
8 | 8 |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
724 } else { | 724 } else { |
725 inside_index++; | 725 inside_index++; |
726 } | 726 } |
727 break; | 727 break; |
728 case 3: | 728 case 3: |
729 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { | 729 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { |
730 FX_FILESIZE obj_pos = start_pos - m_pSyntax->m_HeaderOffset; | 730 FX_FILESIZE obj_pos = start_pos - m_pSyntax->m_HeaderOffset; |
731 m_SortedOffset.insert(obj_pos); | 731 m_SortedOffset.insert(obj_pos); |
732 last_obj = start_pos; | 732 last_obj = start_pos; |
733 FX_FILESIZE obj_end = 0; | 733 FX_FILESIZE obj_end = 0; |
734 CPDF_Object* pObject = ParseIndirectObjectAtByStrict( | 734 std::unique_ptr<CPDF_Object> pObject = |
735 m_pDocument, obj_pos, objnum, &obj_end); | 735 ParseIndirectObjectAtByStrict(m_pDocument, obj_pos, objnum, |
736 if (CPDF_Stream* pStream = ToStream(pObject)) { | 736 &obj_end); |
737 if (CPDF_Stream* pStream = ToStream(pObject.get())) { | |
737 if (CPDF_Dictionary* pDict = pStream->GetDict()) { | 738 if (CPDF_Dictionary* pDict = pStream->GetDict()) { |
738 if ((pDict->KeyExist("Type")) && | 739 if ((pDict->KeyExist("Type")) && |
739 (pDict->GetStringFor("Type") == "XRef" && | 740 (pDict->GetStringFor("Type") == "XRef" && |
740 pDict->KeyExist("Size"))) { | 741 pDict->KeyExist("Size"))) { |
741 CPDF_Object* pRoot = pDict->GetObjectFor("Root"); | 742 CPDF_Object* pRoot = pDict->GetObjectFor("Root"); |
742 if (pRoot && pRoot->GetDict() && | 743 if (pRoot && pRoot->GetDict() && |
743 pRoot->GetDict()->GetObjectFor("Pages")) { | 744 pRoot->GetDict()->GetObjectFor("Pages")) { |
744 delete m_pTrailer; | 745 delete m_pTrailer; |
745 m_pTrailer = ToDictionary(pDict->Clone()); | 746 m_pTrailer = ToDictionary(pDict->Clone()); |
746 } | 747 } |
(...skipping 24 matching lines...) Expand all Loading... | |
771 m_ObjectInfo[objnum].pos = obj_pos; | 772 m_ObjectInfo[objnum].pos = obj_pos; |
772 m_ObjectInfo[objnum].gennum = gennum; | 773 m_ObjectInfo[objnum].gennum = gennum; |
773 if (oldgen != gennum) | 774 if (oldgen != gennum) |
774 m_bVersionUpdated = true; | 775 m_bVersionUpdated = true; |
775 } | 776 } |
776 } else { | 777 } else { |
777 m_ObjectInfo[objnum].pos = obj_pos; | 778 m_ObjectInfo[objnum].pos = obj_pos; |
778 m_ObjectInfo[objnum].type = 1; | 779 m_ObjectInfo[objnum].type = 1; |
779 m_ObjectInfo[objnum].gennum = gennum; | 780 m_ObjectInfo[objnum].gennum = gennum; |
780 } | 781 } |
781 | |
782 delete pObject; | |
783 } | 782 } |
784 --i; | 783 --i; |
785 state = ParserState::kDefault; | 784 state = ParserState::kDefault; |
786 break; | 785 break; |
787 } | 786 } |
788 break; | 787 break; |
789 | 788 |
790 case ParserState::kTrailer: | 789 case ParserState::kTrailer: |
791 if (inside_index == 7) { | 790 if (inside_index == 7) { |
792 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { | 791 if (PDFCharIsWhitespace(byte) || PDFCharIsDelimiter(byte)) { |
793 last_trailer = pos + i - 7; | 792 last_trailer = pos + i - 7; |
794 m_pSyntax->RestorePos(pos + i - m_pSyntax->m_HeaderOffset); | 793 m_pSyntax->RestorePos(pos + i - m_pSyntax->m_HeaderOffset); |
795 | 794 |
796 CPDF_Object* pObj = m_pSyntax->GetObject(m_pDocument, 0, 0, true); | 795 std::unique_ptr<CPDF_Object> pObj = |
796 m_pSyntax->GetObject(m_pDocument, 0, 0, true); | |
797 if (pObj) { | 797 if (pObj) { |
798 if (!pObj->IsDictionary() && !pObj->AsStream()) { | 798 if (pObj->IsDictionary() || pObj->AsStream()) { |
799 delete pObj; | |
800 } else { | |
801 CPDF_Stream* pStream = pObj->AsStream(); | 799 CPDF_Stream* pStream = pObj->AsStream(); |
802 if (CPDF_Dictionary* pTrailer = | 800 if (CPDF_Dictionary* pTrailer = |
803 pStream ? pStream->GetDict() : pObj->AsDictionary()) { | 801 pStream ? pStream->GetDict() : pObj->AsDictionary()) { |
804 if (m_pTrailer) { | 802 if (m_pTrailer) { |
805 CPDF_Object* pRoot = pTrailer->GetObjectFor("Root"); | 803 CPDF_Object* pRoot = pTrailer->GetObjectFor("Root"); |
806 CPDF_Reference* pRef = ToReference(pRoot); | 804 CPDF_Reference* pRef = ToReference(pRoot); |
807 if (!pRoot || | 805 if (!pRoot || |
808 (pRef && IsValidObjectNumber(pRef->GetRefObjNum()) && | 806 (pRef && IsValidObjectNumber(pRef->GetRefObjNum()) && |
809 m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) { | 807 m_ObjectInfo[pRef->GetRefObjNum()].pos != 0)) { |
810 auto it = pTrailer->begin(); | 808 auto it = pTrailer->begin(); |
811 while (it != pTrailer->end()) { | 809 while (it != pTrailer->end()) { |
812 const CFX_ByteString& key = it->first; | 810 const CFX_ByteString& key = it->first; |
813 CPDF_Object* pElement = it->second; | 811 CPDF_Object* pElement = it->second; |
814 ++it; | 812 ++it; |
815 uint32_t dwObjNum = | 813 uint32_t dwObjNum = |
816 pElement ? pElement->GetObjNum() : 0; | 814 pElement ? pElement->GetObjNum() : 0; |
817 if (dwObjNum) { | 815 if (dwObjNum) { |
818 m_pTrailer->SetReferenceFor(key, m_pDocument, | 816 m_pTrailer->SetReferenceFor(key, m_pDocument, |
819 dwObjNum); | 817 dwObjNum); |
820 } else { | 818 } else { |
821 m_pTrailer->SetFor(key, pElement->Clone()); | 819 m_pTrailer->SetFor(key, pElement->Clone()); |
822 } | 820 } |
823 } | 821 } |
824 } | 822 } |
825 delete pObj; | |
826 } else { | 823 } else { |
827 if (pObj->IsStream()) { | 824 if (pObj->IsStream()) { |
828 m_pTrailer = ToDictionary(pTrailer->Clone()); | 825 m_pTrailer = ToDictionary(pTrailer->Clone()); |
829 delete pObj; | |
830 } else { | 826 } else { |
827 pObj.release(); | |
Lei Zhang
2016/11/07 21:42:35
Maybe: m_pTrailer = ToDictionary(pObj.release()));
Tom Sepez
2016/11/07 21:48:37
I think it becomes a std::move at some point once
| |
831 m_pTrailer = pTrailer; | 828 m_pTrailer = pTrailer; |
832 } | 829 } |
833 | 830 |
834 FX_FILESIZE dwSavePos = m_pSyntax->SavePos(); | 831 FX_FILESIZE dwSavePos = m_pSyntax->SavePos(); |
835 CFX_ByteString strWord = m_pSyntax->GetKeyword(); | 832 CFX_ByteString strWord = m_pSyntax->GetKeyword(); |
836 if (!strWord.Compare("startxref")) { | 833 if (!strWord.Compare("startxref")) { |
837 bool bNumber; | 834 bool bNumber; |
838 CFX_ByteString bsOffset = | 835 CFX_ByteString bsOffset = |
839 m_pSyntax->GetNextWord(&bNumber); | 836 m_pSyntax->GetNextWord(&bNumber); |
840 if (bNumber) | 837 if (bNumber) |
841 m_LastXRefOffset = FXSYS_atoi(bsOffset.c_str()); | 838 m_LastXRefOffset = FXSYS_atoi(bsOffset.c_str()); |
842 } | 839 } |
843 m_pSyntax->RestorePos(dwSavePos); | 840 m_pSyntax->RestorePos(dwSavePos); |
844 } | 841 } |
845 } else { | |
846 delete pObj; | |
847 } | 842 } |
848 } | 843 } |
849 } | 844 } |
850 } | 845 } |
851 --i; | 846 --i; |
852 state = ParserState::kDefault; | 847 state = ParserState::kDefault; |
853 } else if (byte == "trailer"[inside_index]) { | 848 } else if (byte == "trailer"[inside_index]) { |
854 inside_index++; | 849 inside_index++; |
855 } else { | 850 } else { |
856 --i; | 851 --i; |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1080 } | 1075 } |
1081 return true; | 1076 return true; |
1082 } | 1077 } |
1083 | 1078 |
1084 CPDF_Array* CPDF_Parser::GetIDArray() { | 1079 CPDF_Array* CPDF_Parser::GetIDArray() { |
1085 CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetObjectFor("ID") : nullptr; | 1080 CPDF_Object* pID = m_pTrailer ? m_pTrailer->GetObjectFor("ID") : nullptr; |
1086 if (!pID) | 1081 if (!pID) |
1087 return nullptr; | 1082 return nullptr; |
1088 | 1083 |
1089 if (CPDF_Reference* pRef = pID->AsReference()) { | 1084 if (CPDF_Reference* pRef = pID->AsReference()) { |
1090 pID = ParseIndirectObject(nullptr, pRef->GetRefObjNum()); | 1085 pID = ParseIndirectObject(nullptr, pRef->GetRefObjNum()).release(); |
1091 m_pTrailer->SetFor("ID", pID); | 1086 m_pTrailer->SetFor("ID", pID); |
1092 } | 1087 } |
1093 return ToArray(pID); | 1088 return ToArray(pID); |
1094 } | 1089 } |
1095 | 1090 |
1096 uint32_t CPDF_Parser::GetRootObjNum() { | 1091 uint32_t CPDF_Parser::GetRootObjNum() { |
1097 CPDF_Reference* pRef = | 1092 CPDF_Reference* pRef = |
1098 ToReference(m_pTrailer ? m_pTrailer->GetObjectFor("Root") : nullptr); | 1093 ToReference(m_pTrailer ? m_pTrailer->GetObjectFor("Root") : nullptr); |
1099 return pRef ? pRef->GetRefObjNum() : 0; | 1094 return pRef ? pRef->GetRefObjNum() : 0; |
1100 } | 1095 } |
1101 | 1096 |
1102 uint32_t CPDF_Parser::GetInfoObjNum() { | 1097 uint32_t CPDF_Parser::GetInfoObjNum() { |
1103 CPDF_Reference* pRef = | 1098 CPDF_Reference* pRef = |
1104 ToReference(m_pTrailer ? m_pTrailer->GetObjectFor("Info") : nullptr); | 1099 ToReference(m_pTrailer ? m_pTrailer->GetObjectFor("Info") : nullptr); |
1105 return pRef ? pRef->GetRefObjNum() : 0; | 1100 return pRef ? pRef->GetRefObjNum() : 0; |
1106 } | 1101 } |
1107 | 1102 |
1108 CPDF_Object* CPDF_Parser::ParseIndirectObject( | 1103 std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObject( |
1109 CPDF_IndirectObjectHolder* pObjList, | 1104 CPDF_IndirectObjectHolder* pObjList, |
1110 uint32_t objnum) { | 1105 uint32_t objnum) { |
1111 if (!IsValidObjectNumber(objnum)) | 1106 if (!IsValidObjectNumber(objnum)) |
1112 return nullptr; | 1107 return nullptr; |
1113 | 1108 |
1114 // Prevent circular parsing the same object. | 1109 // Prevent circular parsing the same object. |
1115 if (pdfium::ContainsKey(m_ParsingObjNums, objnum)) | 1110 if (pdfium::ContainsKey(m_ParsingObjNums, objnum)) |
1116 return nullptr; | 1111 return nullptr; |
1117 | 1112 |
1118 pdfium::ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums, objnum); | 1113 pdfium::ScopedSetInsertion<uint32_t> local_insert(&m_ParsingObjNums, objnum); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1301 nextoff = m_pSyntax->SavePos(); | 1296 nextoff = m_pSyntax->SavePos(); |
1302 } | 1297 } |
1303 | 1298 |
1304 size = (uint32_t)(nextoff - pos); | 1299 size = (uint32_t)(nextoff - pos); |
1305 pBuffer = FX_Alloc(uint8_t, size); | 1300 pBuffer = FX_Alloc(uint8_t, size); |
1306 m_pSyntax->RestorePos(pos); | 1301 m_pSyntax->RestorePos(pos); |
1307 m_pSyntax->ReadBlock(pBuffer, size); | 1302 m_pSyntax->ReadBlock(pBuffer, size); |
1308 m_pSyntax->RestorePos(SavedPos); | 1303 m_pSyntax->RestorePos(SavedPos); |
1309 } | 1304 } |
1310 | 1305 |
1311 CPDF_Object* CPDF_Parser::ParseIndirectObjectAt( | 1306 std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAt( |
1312 CPDF_IndirectObjectHolder* pObjList, | 1307 CPDF_IndirectObjectHolder* pObjList, |
1313 FX_FILESIZE pos, | 1308 FX_FILESIZE pos, |
1314 uint32_t objnum) { | 1309 uint32_t objnum) { |
1315 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); | 1310 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); |
1316 m_pSyntax->RestorePos(pos); | 1311 m_pSyntax->RestorePos(pos); |
1317 bool bIsNumber; | 1312 bool bIsNumber; |
1318 CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber); | 1313 CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber); |
1319 if (!bIsNumber) { | 1314 if (!bIsNumber) { |
1320 m_pSyntax->RestorePos(SavedPos); | 1315 m_pSyntax->RestorePos(SavedPos); |
1321 return nullptr; | 1316 return nullptr; |
(...skipping 12 matching lines...) Expand all Loading... | |
1334 m_pSyntax->RestorePos(SavedPos); | 1329 m_pSyntax->RestorePos(SavedPos); |
1335 return nullptr; | 1330 return nullptr; |
1336 } | 1331 } |
1337 | 1332 |
1338 uint32_t parser_gennum = FXSYS_atoui(word.c_str()); | 1333 uint32_t parser_gennum = FXSYS_atoui(word.c_str()); |
1339 if (m_pSyntax->GetKeyword() != "obj") { | 1334 if (m_pSyntax->GetKeyword() != "obj") { |
1340 m_pSyntax->RestorePos(SavedPos); | 1335 m_pSyntax->RestorePos(SavedPos); |
1341 return nullptr; | 1336 return nullptr; |
1342 } | 1337 } |
1343 | 1338 |
1344 CPDF_Object* pObj = | 1339 std::unique_ptr<CPDF_Object> pObj = |
1345 m_pSyntax->GetObject(pObjList, objnum, parser_gennum, true); | 1340 m_pSyntax->GetObject(pObjList, objnum, parser_gennum, true); |
1346 m_pSyntax->SavePos(); | 1341 m_pSyntax->SavePos(); |
1347 | 1342 |
1348 CFX_ByteString bsWord = m_pSyntax->GetKeyword(); | 1343 CFX_ByteString bsWord = m_pSyntax->GetKeyword(); |
1349 if (bsWord == "endobj") | 1344 if (bsWord == "endobj") |
1350 m_pSyntax->SavePos(); | 1345 m_pSyntax->SavePos(); |
1351 | 1346 |
1352 m_pSyntax->RestorePos(SavedPos); | 1347 m_pSyntax->RestorePos(SavedPos); |
1353 if (pObj) { | 1348 if (pObj) { |
1354 if (!objnum) | 1349 if (!objnum) |
1355 pObj->m_ObjNum = parser_objnum; | 1350 pObj->m_ObjNum = parser_objnum; |
1356 pObj->m_GenNum = parser_gennum; | 1351 pObj->m_GenNum = parser_gennum; |
1357 } | 1352 } |
1358 return pObj; | 1353 return pObj; |
1359 } | 1354 } |
1360 | 1355 |
1361 CPDF_Object* CPDF_Parser::ParseIndirectObjectAtByStrict( | 1356 std::unique_ptr<CPDF_Object> CPDF_Parser::ParseIndirectObjectAtByStrict( |
1362 CPDF_IndirectObjectHolder* pObjList, | 1357 CPDF_IndirectObjectHolder* pObjList, |
1363 FX_FILESIZE pos, | 1358 FX_FILESIZE pos, |
1364 uint32_t objnum, | 1359 uint32_t objnum, |
1365 FX_FILESIZE* pResultPos) { | 1360 FX_FILESIZE* pResultPos) { |
1366 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); | 1361 FX_FILESIZE SavedPos = m_pSyntax->SavePos(); |
1367 m_pSyntax->RestorePos(pos); | 1362 m_pSyntax->RestorePos(pos); |
1368 | 1363 |
1369 bool bIsNumber; | 1364 bool bIsNumber; |
1370 CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber); | 1365 CFX_ByteString word = m_pSyntax->GetNextWord(&bIsNumber); |
1371 if (!bIsNumber) { | 1366 if (!bIsNumber) { |
(...skipping 12 matching lines...) Expand all Loading... | |
1384 m_pSyntax->RestorePos(SavedPos); | 1379 m_pSyntax->RestorePos(SavedPos); |
1385 return nullptr; | 1380 return nullptr; |
1386 } | 1381 } |
1387 | 1382 |
1388 uint32_t gennum = FXSYS_atoui(word.c_str()); | 1383 uint32_t gennum = FXSYS_atoui(word.c_str()); |
1389 if (m_pSyntax->GetKeyword() != "obj") { | 1384 if (m_pSyntax->GetKeyword() != "obj") { |
1390 m_pSyntax->RestorePos(SavedPos); | 1385 m_pSyntax->RestorePos(SavedPos); |
1391 return nullptr; | 1386 return nullptr; |
1392 } | 1387 } |
1393 | 1388 |
1394 CPDF_Object* pObj = m_pSyntax->GetObjectForStrict(pObjList, objnum, gennum); | 1389 std::unique_ptr<CPDF_Object> pObj = |
1390 m_pSyntax->GetObjectForStrict(pObjList, objnum, gennum); | |
1391 | |
1395 if (pResultPos) | 1392 if (pResultPos) |
1396 *pResultPos = m_pSyntax->m_Pos; | 1393 *pResultPos = m_pSyntax->m_Pos; |
1397 | 1394 |
1398 m_pSyntax->RestorePos(SavedPos); | 1395 m_pSyntax->RestorePos(SavedPos); |
1399 return pObj; | 1396 return pObj; |
1400 } | 1397 } |
1401 | 1398 |
1402 uint32_t CPDF_Parser::GetFirstPageNo() const { | 1399 uint32_t CPDF_Parser::GetFirstPageNo() const { |
1403 return m_pLinearized ? m_pLinearized->GetFirstPageNo() : 0; | 1400 return m_pLinearized ? m_pLinearized->GetFirstPageNo() : 0; |
1404 } | 1401 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1443 if (!bIsNumber) | 1440 if (!bIsNumber) |
1444 return false; | 1441 return false; |
1445 | 1442 |
1446 uint32_t gennum = FXSYS_atoui(word.c_str()); | 1443 uint32_t gennum = FXSYS_atoui(word.c_str()); |
1447 if (m_pSyntax->GetKeyword() != "obj") { | 1444 if (m_pSyntax->GetKeyword() != "obj") { |
1448 m_pSyntax->RestorePos(SavedPos); | 1445 m_pSyntax->RestorePos(SavedPos); |
1449 return false; | 1446 return false; |
1450 } | 1447 } |
1451 | 1448 |
1452 m_pLinearized = CPDF_LinearizedHeader::CreateForObject( | 1449 m_pLinearized = CPDF_LinearizedHeader::CreateForObject( |
1453 pdfium::WrapUnique(m_pSyntax->GetObject(nullptr, objnum, gennum, true))); | 1450 m_pSyntax->GetObject(nullptr, objnum, gennum, true)); |
1454 if (!m_pLinearized) | 1451 if (!m_pLinearized) |
1455 return false; | 1452 return false; |
1453 | |
1456 m_LastXRefOffset = m_pLinearized->GetLastXRefOffset(); | 1454 m_LastXRefOffset = m_pLinearized->GetLastXRefOffset(); |
1457 // Move parser onto first page xref table start. | 1455 // Move parser onto first page xref table start. |
1458 m_pSyntax->GetNextWord(nullptr); | 1456 m_pSyntax->GetNextWord(nullptr); |
1459 return true; | 1457 return true; |
1460 } | 1458 } |
1461 | 1459 |
1462 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( | 1460 CPDF_Parser::Error CPDF_Parser::StartLinearizedParse( |
1463 IFX_SeekableReadStream* pFileAccess, | 1461 IFX_SeekableReadStream* pFileAccess, |
1464 CPDF_Document* pDocument) { | 1462 CPDF_Document* pDocument) { |
1465 ASSERT(!m_bHasParsed); | 1463 ASSERT(!m_bHasParsed); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1586 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && | 1584 if (!LoadLinearizedAllCrossRefV4(m_LastXRefOffset, m_dwXrefStartObjNum) && |
1587 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { | 1585 !LoadLinearizedAllCrossRefV5(m_LastXRefOffset)) { |
1588 m_LastXRefOffset = 0; | 1586 m_LastXRefOffset = 0; |
1589 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1587 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
1590 return FORMAT_ERROR; | 1588 return FORMAT_ERROR; |
1591 } | 1589 } |
1592 | 1590 |
1593 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; | 1591 m_pSyntax->m_MetadataObjnum = dwSaveMetadataObjnum; |
1594 return SUCCESS; | 1592 return SUCCESS; |
1595 } | 1593 } |
OLD | NEW |