diff options
author | Tor Lillqvist <tml@collabora.com> | 2013-09-30 15:23:35 +0300 |
---|---|---|
committer | Tor Lillqvist <tml@collabora.com> | 2013-09-30 17:40:53 +0300 |
commit | c1015fdd51909495cefdc0258c3899cd73d4d2df (patch) | |
tree | 901f0fb94a93dbd614c18d3320bcfa414672e441 /sw | |
parent | 32e0f451d69b68d69a4aa91c271b81ea6264d3c1 (diff) |
Add hack to optionally get stable ODF output from the same input
To be used in regression testing and similar scenarios, where the output ODF
is *not* intended to be further manipulated in LibreOffice. An environment
variable LIBO_ONEWAY_STABLE_ODF_EXPORT is used to toggle this behaviour. I am
not 100% sure whether the generated ODF with the hack toggled on is even fully
correct, but correctness is not the purpose of the hack anyway.
Two classes of issues handled: 1) Automatic style names and 2) use of
randomness.
For class 1), when the hack toggle is in effect, we generate the names at
first as strings based on all the properties of the style, and sort them based
on those, and then rename them (for brevity in the output) to the "normal"
form of a short prefix plus a number (like "P12").
Sure, it would have been better to just figure out *why* the automatic style
naming currently is not stable in the first place, but outputs the styles in
different order (with some styles being assigned different numbers) in
separate invokations of LibreOffice), but I was unable to understand that.
Possibly this code could be used in all cases, except that it does break some
unit test (can't recall which right now). I don't know whether that is simply
because the unit test assumes too much knowledge of the internal workings of
the automatic style name generation, or whether the generated ODF is actually
invalid.
For 2), I found a handful of places where randomness was used to generated
various kinds of identifiers in ODF output. I changed those to just use large
(64-bit) non-overlapping integers instead. I assume there *is* a point in the
original code in each case that explains why randomness is needed, so the hack
definitely needs to be optional and used only for the above mentioned
scenarios.
Change-Id: I17b657197e38bcf24abdfe61ad4a277f4339eeae
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/crsr/bookmrk.cxx | 32 | ||||
-rw-r--r-- | sw/source/core/doc/doc.cxx | 17 | ||||
-rw-r--r-- | sw/source/core/doc/docnew.cxx | 21 | ||||
-rw-r--r-- | sw/source/core/doc/docnum.cxx | 26 |
4 files changed, 65 insertions, 31 deletions
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx index 11e62108b71e..3a4ba43c6de4 100644 --- a/sw/source/core/crsr/bookmrk.cxx +++ b/sw/source/core/crsr/bookmrk.cxx @@ -172,19 +172,29 @@ namespace sw { namespace mark OUString MarkBase::GenerateNewName(const OUString& rPrefix) { - static rtlRandomPool aPool = rtl_random_createPool(); - static OUString sUniquePostfix; - static sal_Int32 nCount = SAL_MAX_INT32; - OUStringBuffer aResult(rPrefix); - if(nCount == SAL_MAX_INT32) + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); + + if (bHack) + { + static sal_Int64 nIdCounter = SAL_CONST_INT64(6000000000); + return rPrefix + OUString::number(nIdCounter++); + } + else { - sal_Int32 nRandom; - rtl_random_getBytes(aPool, &nRandom, sizeof(nRandom)); - sUniquePostfix = OUStringBuffer(13).append('_').append(static_cast<sal_Int32>(abs(nRandom))).makeStringAndClear(); - nCount = 0; + static rtlRandomPool aPool = rtl_random_createPool(); + static OUString sUniquePostfix; + static sal_Int32 nCount = SAL_MAX_INT32; + OUStringBuffer aResult(rPrefix); + if(nCount == SAL_MAX_INT32) + { + sal_Int32 nRandom; + rtl_random_getBytes(aPool, &nRandom, sizeof(nRandom)); + sUniquePostfix = OUStringBuffer(13).append('_').append(static_cast<sal_Int32>(abs(nRandom))).makeStringAndClear(); + nCount = 0; + } + // putting the counter in front of the random parts will speed up string comparisons + return aResult.append(nCount++).append(sUniquePostfix).makeStringAndClear(); } - // putting the counter in front of the random parts will speed up string comparisons - return aResult.append(nCount++).append(sUniquePostfix).makeStringAndClear(); } void MarkBase::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew ) diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index a4eef0e5ee96..e4bdbca0dfbd 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -476,13 +476,18 @@ sal_uInt32 SwDoc::getRsid() const void SwDoc::setRsid( sal_uInt32 nVal ) { - // Increase the rsid with a random number smaller than 2^17. This way we - // expect to be able to edit a document 2^12 times before rsid overflows. + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); + sal_uInt32 nIncrease = 0; - static rtlRandomPool aPool = rtl_random_createPool(); - rtl_random_getBytes( aPool, &nIncrease, sizeof ( nIncrease ) ); - nIncrease &= ( 1<<17 ) - 1; - nIncrease++; // make sure the new rsid is not the same + if (!bHack) + { + // Increase the rsid with a random number smaller than 2^17. This way we + // expect to be able to edit a document 2^12 times before rsid overflows. + static rtlRandomPool aPool = rtl_random_createPool(); + rtl_random_getBytes( aPool, &nIncrease, sizeof ( nIncrease ) ); + nIncrease &= ( 1<<17 ) - 1; + nIncrease++; // make sure the new rsid is not the same + } mnRsid = nVal + nIncrease; } diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx index 7c3b3c8435f1..1a2fb44c07cc 100644 --- a/sw/source/core/doc/docnew.cxx +++ b/sw/source/core/doc/docnew.cxx @@ -407,12 +407,21 @@ SwDoc::SwDoc() mpStyleAccess = createStyleManager( &aIgnorableParagraphItems ); } - // Initialize the session id of the current document to a random number - // smaller than 2^21. - static rtlRandomPool aPool = rtl_random_createPool(); - rtl_random_getBytes( aPool, &mnRsid, sizeof ( mnRsid ) ); - mnRsid &= ( 1<<21 ) - 1; - mnRsid++; + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); + + if (bHack) + { + mnRsid = 0; + } + else + { + // Initialize the session id of the current document to a random number + // smaller than 2^21. + static rtlRandomPool aPool = rtl_random_createPool(); + rtl_random_getBytes( aPool, &mnRsid, sizeof ( mnRsid ) ); + mnRsid &= ( 1<<21 ) - 1; + mnRsid++; + } mnRsidRoot = mnRsid; ResetModified(); diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx index 5df1a8094c99..80577647e8ae 100644 --- a/sw/source/core/doc/docnum.cxx +++ b/sw/source/core/doc/docnum.cxx @@ -2596,15 +2596,25 @@ namespace listfunc } const String CreateUniqueListId( const SwDoc& rDoc ) { - // #i92478# - OUString aNewListId( "list" ); - // #o12311627# - static rtlRandomPool s_RandomPool( rtl_random_createPool() ); - sal_Int64 n; - rtl_random_getBytes( s_RandomPool, &n, sizeof(n) ); - aNewListId += OUString::number( (n < 0 ? -n : n) ); + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); - return MakeListIdUnique( rDoc, aNewListId ); + if (bHack) + { + static sal_Int64 nIdCounter = SAL_CONST_INT64(7000000000); + return MakeListIdUnique( rDoc, OUString( "list" + OUString::number(nIdCounter++) ) ); + } + else + { + // #i92478# + OUString aNewListId( "list" ); + // #o12311627# + static rtlRandomPool s_RandomPool( rtl_random_createPool() ); + sal_Int64 n; + rtl_random_getBytes( s_RandomPool, &n, sizeof(n) ); + aNewListId += OUString::number( (n < 0 ? -n : n) ); + + return MakeListIdUnique( rDoc, aNewListId ); + } } } |