1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_comphelper.hxx" 26 #include <com/sun/star/embed/ElementModes.hpp> 27 #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp> 28 #include <com/sun/star/ucb/XSimpleFileAccess.hpp> 29 #include <com/sun/star/beans/XPropertySet.hpp> 30 #include <com/sun/star/beans/PropertyValue.hpp> 31 #include <com/sun/star/beans/NamedValue.hpp> 32 #include <com/sun/star/beans/IllegalTypeException.hpp> 33 #include <com/sun/star/xml/crypto/XDigestContext.hpp> 34 #include <com/sun/star/xml/crypto/XDigestContextSupplier.hpp> 35 #include <com/sun/star/xml/crypto/DigestID.hpp> 36 37 #include <rtl/digest.h> 38 39 #include <ucbhelper/content.hxx> 40 41 #include <comphelper/fileformat.h> 42 #include <comphelper/processfactory.hxx> 43 #include <comphelper/documentconstants.hxx> 44 45 #include <comphelper/storagehelper.hxx> 46 47 48 using namespace ::com::sun::star; 49 50 namespace comphelper { 51 52 // ---------------------------------------------------------------------- 53 uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetStorageFactory( 54 const uno::Reference< lang::XMultiServiceFactory >& xSF ) 55 { 56 uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory(); 57 if ( !xFactory.is() ) 58 throw uno::RuntimeException(); 59 60 uno::Reference < lang::XSingleServiceFactory > xStorageFactory( 61 xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.StorageFactory" ) ), 62 uno::UNO_QUERY ); 63 64 if ( !xStorageFactory.is() ) 65 throw uno::RuntimeException(); 66 67 return xStorageFactory; 68 } 69 70 // ---------------------------------------------------------------------- 71 uno::Reference< lang::XSingleServiceFactory > OStorageHelper::GetFileSystemStorageFactory( 72 const uno::Reference< lang::XMultiServiceFactory >& xSF ) 73 { 74 uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory(); 75 if ( !xFactory.is() ) 76 throw uno::RuntimeException(); 77 78 uno::Reference < lang::XSingleServiceFactory > xStorageFactory( 79 xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.embed.FileSystemStorageFactory" ) ), 80 uno::UNO_QUERY ); 81 82 if ( !xStorageFactory.is() ) 83 throw uno::RuntimeException(); 84 85 return xStorageFactory; 86 } 87 88 // ---------------------------------------------------------------------- 89 uno::Reference< embed::XStorage > OStorageHelper::GetTemporaryStorage( 90 const uno::Reference< lang::XMultiServiceFactory >& xFactory ) 91 { 92 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstance(), 93 uno::UNO_QUERY ); 94 if ( !xTempStorage.is() ) 95 throw uno::RuntimeException(); 96 97 return xTempStorage; 98 } 99 100 // ---------------------------------------------------------------------- 101 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL( 102 const ::rtl::OUString& aURL, 103 sal_Int32 nStorageMode, 104 const uno::Reference< lang::XMultiServiceFactory >& xFactory ) 105 { 106 uno::Sequence< uno::Any > aArgs( 2 ); 107 aArgs[0] <<= aURL; 108 aArgs[1] <<= nStorageMode; 109 110 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), 111 uno::UNO_QUERY ); 112 if ( !xTempStorage.is() ) 113 throw uno::RuntimeException(); 114 115 return xTempStorage; 116 } 117 118 // ---------------------------------------------------------------------- 119 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromURL2( 120 const ::rtl::OUString& aURL, 121 sal_Int32 nStorageMode, 122 const uno::Reference< lang::XMultiServiceFactory >& xFactory ) 123 { 124 uno::Sequence< uno::Any > aArgs( 2 ); 125 aArgs[0] <<= aURL; 126 aArgs[1] <<= nStorageMode; 127 128 uno::Reference< lang::XSingleServiceFactory > xFact; 129 try { 130 ::ucbhelper::Content aCntnt( aURL, 131 uno::Reference< ::com::sun::star::ucb::XCommandEnvironment > () ); 132 if (aCntnt.isDocument()) { 133 xFact = GetStorageFactory( xFactory ); 134 } else { 135 xFact = GetFileSystemStorageFactory( xFactory ); 136 } 137 } catch (uno::Exception &) { } 138 139 if (!xFact.is()) throw uno::RuntimeException(); 140 141 uno::Reference< embed::XStorage > xTempStorage( 142 xFact->createInstanceWithArguments( aArgs ), uno::UNO_QUERY ); 143 if ( !xTempStorage.is() ) 144 throw uno::RuntimeException(); 145 146 return xTempStorage; 147 } 148 149 // ---------------------------------------------------------------------- 150 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromInputStream( 151 const uno::Reference < io::XInputStream >& xStream, 152 const uno::Reference< lang::XMultiServiceFactory >& xFactory ) 153 { 154 uno::Sequence< uno::Any > aArgs( 2 ); 155 aArgs[0] <<= xStream; 156 aArgs[1] <<= embed::ElementModes::READ; 157 158 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), 159 uno::UNO_QUERY ); 160 if ( !xTempStorage.is() ) 161 throw uno::RuntimeException(); 162 163 return xTempStorage; 164 } 165 166 // ---------------------------------------------------------------------- 167 uno::Reference< embed::XStorage > OStorageHelper::GetStorageFromStream( 168 const uno::Reference < io::XStream >& xStream, 169 sal_Int32 nStorageMode, 170 const uno::Reference< lang::XMultiServiceFactory >& xFactory ) 171 { 172 uno::Sequence< uno::Any > aArgs( 2 ); 173 aArgs[0] <<= xStream; 174 aArgs[1] <<= nStorageMode; 175 176 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), 177 uno::UNO_QUERY ); 178 if ( !xTempStorage.is() ) 179 throw uno::RuntimeException(); 180 181 return xTempStorage; 182 } 183 184 // ---------------------------------------------------------------------- 185 void OStorageHelper::CopyInputToOutput( 186 const uno::Reference< io::XInputStream >& xInput, 187 const uno::Reference< io::XOutputStream >& xOutput ) 188 { 189 static const sal_Int32 nConstBufferSize = 32000; 190 191 sal_Int32 nRead; 192 uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize ); 193 194 do 195 { 196 nRead = xInput->readBytes ( aSequence, nConstBufferSize ); 197 if ( nRead < nConstBufferSize ) 198 { 199 uno::Sequence < sal_Int8 > aTempBuf ( aSequence.getConstArray(), nRead ); 200 xOutput->writeBytes ( aTempBuf ); 201 } 202 else 203 xOutput->writeBytes ( aSequence ); 204 } 205 while ( nRead == nConstBufferSize ); 206 } 207 208 // ---------------------------------------------------------------------- 209 uno::Reference< io::XInputStream > OStorageHelper::GetInputStreamFromURL( 210 const ::rtl::OUString& aURL, 211 const uno::Reference< lang::XMultiServiceFactory >& xSF ) 212 { 213 uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory(); 214 if ( !xFactory.is() ) 215 throw uno::RuntimeException(); 216 217 uno::Reference < ::com::sun::star::ucb::XSimpleFileAccess > xTempAccess( 218 xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ) ), 219 uno::UNO_QUERY ); 220 221 if ( !xTempAccess.is() ) 222 throw uno::RuntimeException(); 223 224 uno::Reference< io::XInputStream > xInputStream = xTempAccess->openFileRead( aURL ); 225 if ( !xInputStream.is() ) 226 throw uno::RuntimeException(); 227 228 return xInputStream; 229 } 230 231 // ---------------------------------------------------------------------- 232 void OStorageHelper::SetCommonStorageEncryptionData( 233 const uno::Reference< embed::XStorage >& xStorage, 234 const uno::Sequence< beans::NamedValue >& aEncryptionData ) 235 { 236 uno::Reference< embed::XEncryptionProtectedSource2 > xEncrSet( xStorage, uno::UNO_QUERY ); 237 if ( !xEncrSet.is() ) 238 throw io::IOException(); // TODO 239 240 xEncrSet->setEncryptionData( aEncryptionData ); 241 } 242 243 // ---------------------------------------------------------------------- 244 sal_Int32 OStorageHelper::GetXStorageFormat( 245 const uno::Reference< embed::XStorage >& xStorage ) 246 { 247 uno::Reference< beans::XPropertySet > xStorProps( xStorage, uno::UNO_QUERY_THROW ); 248 249 ::rtl::OUString aMediaType; 250 xStorProps->getPropertyValue( ::rtl::OUString::createFromAscii( "MediaType" ) ) >>= aMediaType; 251 252 sal_Int32 nResult = 0; 253 254 // TODO/LATER: the filter configuration could be used to detect it later, or batter a special service 255 if ( 256 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_ASCII ) || 257 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_WEB_ASCII ) || 258 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_WRITER_GLOBAL_ASCII) || 259 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_DRAW_ASCII ) || 260 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_IMPRESS_ASCII ) || 261 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CALC_ASCII ) || 262 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_CHART_ASCII ) || 263 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_VND_SUN_XML_MATH_ASCII ) 264 ) 265 { 266 nResult = SOFFICE_FILEFORMAT_60; 267 } 268 else 269 if ( 270 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_ASCII ) || 271 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_WEB_ASCII ) || 272 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_GLOBAL_ASCII ) || 273 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_ASCII ) || 274 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_ASCII) || 275 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_ASCII ) || 276 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_ASCII ) || 277 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_ASCII ) || 278 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DATABASE_ASCII ) || 279 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_ASCII ) || 280 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_REPORT_CHART_ASCII ) || 281 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_TEXT_TEMPLATE_ASCII ) || 282 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_DRAWING_TEMPLATE_ASCII ) || 283 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_PRESENTATION_TEMPLATE_ASCII) || 284 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_SPREADSHEET_TEMPLATE_ASCII ) || 285 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_CHART_TEMPLATE_ASCII ) || 286 aMediaType.equalsIgnoreAsciiCaseAscii(MIMETYPE_OASIS_OPENDOCUMENT_FORMULA_TEMPLATE_ASCII ) 287 ) 288 { 289 nResult = SOFFICE_FILEFORMAT_8; 290 } 291 else 292 { 293 // the mediatype is not known 294 throw beans::IllegalTypeException(); 295 } 296 297 return nResult; 298 } 299 300 // ---------------------------------------------------------------------- 301 uno::Reference< embed::XStorage > OStorageHelper::GetTemporaryStorageOfFormat( 302 const ::rtl::OUString& aFormat, 303 const uno::Reference< lang::XMultiServiceFactory >& xFactory ) 304 { 305 uno::Reference< lang::XMultiServiceFactory > xFactoryToUse = xFactory.is() ? xFactory : ::comphelper::getProcessServiceFactory(); 306 if ( !xFactoryToUse.is() ) 307 throw uno::RuntimeException(); 308 309 uno::Reference< io::XStream > xTmpStream( 310 xFactoryToUse->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.io.TempFile" ) ) ), 311 uno::UNO_QUERY_THROW ); 312 313 return GetStorageOfFormatFromStream( aFormat, xTmpStream, embed::ElementModes::READWRITE, xFactoryToUse ); 314 } 315 316 // ---------------------------------------------------------------------- 317 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromURL( 318 const ::rtl::OUString& aFormat, 319 const ::rtl::OUString& aURL, 320 sal_Int32 nStorageMode, 321 const uno::Reference< lang::XMultiServiceFactory >& xFactory, 322 sal_Bool bRepairStorage ) 323 { 324 uno::Sequence< beans::PropertyValue > aProps( 1 ); 325 aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); 326 aProps[0].Value <<= aFormat; 327 if ( bRepairStorage ) 328 { 329 aProps.realloc( 2 ); 330 aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) ); 331 aProps[1].Value <<= bRepairStorage; 332 } 333 334 uno::Sequence< uno::Any > aArgs( 3 ); 335 aArgs[0] <<= aURL; 336 aArgs[1] <<= nStorageMode; 337 aArgs[2] <<= aProps; 338 339 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), 340 uno::UNO_QUERY ); 341 if ( !xTempStorage.is() ) 342 throw uno::RuntimeException(); 343 344 return xTempStorage; 345 } 346 347 // ---------------------------------------------------------------------- 348 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromInputStream( 349 const ::rtl::OUString& aFormat, 350 const uno::Reference < io::XInputStream >& xStream, 351 const uno::Reference< lang::XMultiServiceFactory >& xFactory, 352 sal_Bool bRepairStorage ) 353 { 354 uno::Sequence< beans::PropertyValue > aProps( 1 ); 355 aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); 356 aProps[0].Value <<= aFormat; 357 if ( bRepairStorage ) 358 { 359 aProps.realloc( 2 ); 360 aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) ); 361 aProps[1].Value <<= bRepairStorage; 362 } 363 364 uno::Sequence< uno::Any > aArgs( 3 ); 365 aArgs[0] <<= xStream; 366 aArgs[1] <<= embed::ElementModes::READ; 367 aArgs[2] <<= aProps; 368 369 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), 370 uno::UNO_QUERY ); 371 if ( !xTempStorage.is() ) 372 throw uno::RuntimeException(); 373 374 return xTempStorage; 375 } 376 377 // ---------------------------------------------------------------------- 378 uno::Reference< embed::XStorage > OStorageHelper::GetStorageOfFormatFromStream( 379 const ::rtl::OUString& aFormat, 380 const uno::Reference < io::XStream >& xStream, 381 sal_Int32 nStorageMode, 382 const uno::Reference< lang::XMultiServiceFactory >& xFactory, 383 sal_Bool bRepairStorage ) 384 { 385 uno::Sequence< beans::PropertyValue > aProps( 1 ); 386 aProps[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StorageFormat" ) ); 387 aProps[0].Value <<= aFormat; 388 if ( bRepairStorage ) 389 { 390 aProps.realloc( 2 ); 391 aProps[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RepairPackage" ) ); 392 aProps[1].Value <<= bRepairStorage; 393 } 394 395 uno::Sequence< uno::Any > aArgs( 3 ); 396 aArgs[0] <<= xStream; 397 aArgs[1] <<= nStorageMode; 398 aArgs[2] <<= aProps; 399 400 uno::Reference< embed::XStorage > xTempStorage( GetStorageFactory( xFactory )->createInstanceWithArguments( aArgs ), 401 uno::UNO_QUERY ); 402 if ( !xTempStorage.is() ) 403 throw uno::RuntimeException(); 404 405 return xTempStorage; 406 } 407 408 // ---------------------------------------------------------------------- 409 uno::Sequence< beans::NamedValue > OStorageHelper::CreatePackageEncryptionData( const ::rtl::OUString& aPassword, const uno::Reference< lang::XMultiServiceFactory >& xSF ) 410 { 411 // TODO/LATER: Should not the method be part of DocPasswordHelper? 412 uno::Sequence< beans::NamedValue > aEncryptionData; 413 sal_Int32 nSha1Ind = 0; 414 if ( !aPassword.isEmpty() ) 415 { 416 // generate SHA256 start key 417 try 418 { 419 uno::Reference< lang::XMultiServiceFactory > xFactory = xSF.is() ? xSF : ::comphelper::getProcessServiceFactory(); 420 if ( !xFactory.is() ) 421 throw uno::RuntimeException(); 422 423 uno::Reference< xml::crypto::XDigestContextSupplier > xDigestContextSupplier( xFactory->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.crypto.NSSInitializer" ) ) ), uno::UNO_QUERY_THROW ); 424 uno::Reference< xml::crypto::XDigestContext > xDigestContext( xDigestContextSupplier->getDigestContext( xml::crypto::DigestID::SHA256, uno::Sequence< beans::NamedValue >() ), uno::UNO_SET_THROW ); 425 426 ::rtl::OString aUTF8Password( ::rtl::OUStringToOString( aPassword, RTL_TEXTENCODING_UTF8 ) ); 427 xDigestContext->updateDigest( uno::Sequence< sal_Int8 >( reinterpret_cast< const sal_Int8* >( aUTF8Password.getStr() ), aUTF8Password.getLength() ) ); 428 uno::Sequence< sal_Int8 > aDigest = xDigestContext->finalizeDigestAndDispose(); 429 430 aEncryptionData.realloc( ++nSha1Ind ); 431 aEncryptionData[0].Name = PACKAGE_ENCRYPTIONDATA_SHA256UTF8; 432 aEncryptionData[0].Value <<= aDigest; 433 } 434 catch ( uno::Exception& ) 435 { 436 OSL_ENSURE( false, "Can not create SHA256 digest!" ); 437 } 438 439 // MS_1252 encoding was used for SO60 document format password encoding, 440 // this encoding supports only a minor subset of nonascii characters, 441 // but for compatibility reasons it has to be used for old document formats 442 aEncryptionData.realloc( nSha1Ind + 2 ); 443 aEncryptionData[nSha1Ind].Name = PACKAGE_ENCRYPTIONDATA_SHA1UTF8; 444 aEncryptionData[nSha1Ind + 1].Name = PACKAGE_ENCRYPTIONDATA_SHA1MS1252; 445 446 rtl_TextEncoding pEncoding[2] = { RTL_TEXTENCODING_UTF8, RTL_TEXTENCODING_MS_1252 }; 447 448 for ( sal_Int32 nInd = 0; nInd < 2; nInd++ ) 449 { 450 ::rtl::OString aByteStrPass = ::rtl::OUStringToOString( aPassword, pEncoding[nInd] ); 451 452 sal_uInt8 pBuffer[RTL_DIGEST_LENGTH_SHA1]; 453 rtlDigestError nError = rtl_digest_SHA1( aByteStrPass.getStr(), 454 aByteStrPass.getLength(), 455 pBuffer, 456 RTL_DIGEST_LENGTH_SHA1 ); 457 458 if ( nError != rtl_Digest_E_None ) 459 { 460 aEncryptionData.realloc( nSha1Ind ); 461 break; 462 } 463 464 aEncryptionData[nSha1Ind+nInd].Value <<= uno::Sequence< sal_Int8 >( (sal_Int8*)pBuffer, RTL_DIGEST_LENGTH_SHA1 ); 465 } 466 } 467 468 return aEncryptionData; 469 } 470 471 // ---------------------------------------------------------------------- 472 sal_Bool OStorageHelper::IsValidZipEntryFileName( const ::rtl::OUString& aName, sal_Bool bSlashAllowed ) 473 { 474 return IsValidZipEntryFileName( aName.getStr(), aName.getLength(), bSlashAllowed ); 475 } 476 477 // ---------------------------------------------------------------------- 478 sal_Bool OStorageHelper::IsValidZipEntryFileName( 479 const sal_Unicode *pChar, sal_Int32 nLength, sal_Bool bSlashAllowed ) 480 { 481 for ( sal_Int32 i = 0; i < nLength; i++ ) 482 { 483 switch ( pChar[i] ) 484 { 485 case '\\': 486 case '?': 487 case '<': 488 case '>': 489 case '\"': 490 case '|': 491 case ':': 492 return sal_False; 493 case '/': 494 if ( ( i == 0 ) || !bSlashAllowed ) 495 return sal_False; 496 break; 497 default: 498 if ( pChar[i] < 32 || (pChar[i] >= 0xD800 && pChar[i] <= 0xDFFF) ) 499 return sal_False; 500 } 501 } 502 return sal_True; 503 } 504 505 // ---------------------------------------------------------------------- 506 sal_Bool OStorageHelper::PathHasSegment( const ::rtl::OUString& aPath, const ::rtl::OUString& aSegment ) 507 { 508 sal_Bool bResult = sal_False; 509 const sal_Int32 nPathLen = aPath.getLength(); 510 const sal_Int32 nSegLen = aSegment.getLength(); 511 512 if ( nSegLen && nPathLen >= nSegLen ) 513 { 514 ::rtl::OUString aEndSegment( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); 515 aEndSegment += aSegment; 516 517 ::rtl::OUString aInternalSegment( aEndSegment ); 518 aInternalSegment += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/" ) ); 519 520 if ( aPath.indexOf( aInternalSegment ) >= 0 ) 521 bResult = sal_True; 522 523 if ( !bResult && !aPath.compareTo( aSegment, nSegLen ) ) 524 { 525 if ( nPathLen == nSegLen || aPath.getStr()[nSegLen] == (sal_Unicode)'/' ) 526 bResult = sal_True; 527 } 528 529 if ( !bResult && nPathLen > nSegLen && aPath.copy( nPathLen - nSegLen - 1, nSegLen + 1 ).equals( aEndSegment ) ) 530 bResult = sal_True; 531 } 532 533 return bResult; 534 } 535 536 } 537