[ 
https://issues.apache.org/jira/browse/TIKA-5057?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18142036#comment-18142036
 ] 

ASF GitHub Bot commented on TIKA-5057:
--------------------------------------

Copilot commented on code in PR #3564:
URL: https://github.com/apache/tika/pull/3564#discussion_r4525711673


##########
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/onenote/OneNoteDocument.java:
##########
@@ -50,6 +59,26 @@ void setAssocGuidToRef(ExtendedGUID guid, FileChunkReference 
ref) {
         guidToRef.put(guid, ref);
     }
 
+    void putObject(ExtendedGUID oid, FileNodePtr ptr) {
+        guidToObject.put(oid, ptr);
+        revisionObjects.computeIfAbsent(currentRevision, k -> new 
HashMap<>()).put(oid, ptr);
+    }
+
+    /** The object as revision {@code rid} has it: declared there or in a 
dependency. */
+    FileNodePtr objectIn(ExtendedGUID rid, ExtendedGUID oid) {
+        ExtendedGUID r = rid;
+        for (int i = 0; r != null && i <= revisionMap.size(); i++) {
+            Map<ExtendedGUID, FileNodePtr> objects = revisionObjects.get(r);
+            FileNodePtr ptr = objects == null ? null : objects.get(oid);

Review Comment:
   Each object lookup restarts the dependency walk, so resolving M unchanged 
objects declared near the base of an R-revision chain takes O(M × R) map 
lookups. Extraction can become quadratic as both content and revision history 
grow, and the file-node visit budget does not count these scans. Build a 
cycle-safe effective-object index for the selected revision, or cache inherited 
resolutions along the dependency chain.



##########
tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-microsoft-module/src/main/java/org/apache/tika/parser/microsoft/onenote/OneNoteParserConfig.java:
##########
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tika.parser.microsoft.onenote;
+
+import java.io.Serializable;
+
+/**
+ * Configuration for {@link OneNoteParser}, set in the parser's JSON config or 
per parse in the
+ * {@link org.apache.tika.parser.ParseContext}.
+ */
+public class OneNoteParserConfig implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private boolean includePageHistory = false;
+    private boolean includeDeletedContent = false;
+
+    /**
+     * Whether text includes every earlier revision and saved page version, 
not only each page's
+     * current one.
+     */
+    public boolean isIncludePageHistory() {
+        return includePageHistory;
+    }
+
+    public void setIncludePageHistory(boolean includePageHistory) {
+        this.includePageHistory = includePageHistory;

Review Comment:
   With `includePageHistory=true`, `OneNoteParser` enables 
`crawlAllFileNodesFromRoot` but leaves `onlyLatestRevision=true`, so the 
classic walker's history filter still suppresses marked saved-page versions. 
Set `onlyLatestRevision` to `!config.isIncludePageHistory()` when constructing 
the walker options, and add a regression case for text beneath 
`VersionHistoryGraphSpaceContextNodes` or `VERSION_HISTORY_CONTENT`.





> General improvements to onenote parser
> --------------------------------------
>
>                 Key: TIKA-5057
>                 URL: https://issues.apache.org/jira/browse/TIKA-5057
>             Project: Tika
>          Issue Type: Task
>            Reporter: Tim Allison
>            Priority: Trivial
>
> When I have extra tokens, I'll have an agent focus on a parser at a time for 
> robustness and simplicity. Let's start with onenote. CC [~henrylindemanglean]
> :robot: swarm recommends:
> {noformat}
>   Native .one path (the common format, unrelated to TIKA-5055):
>   1. Exponential parse on shared child lists (OneNotePtr:714). A file-node 
> list referenced twice is parsed twice. Only the current path is checked for 
> cycles, so a crafted file of a few KB blows up as 2^depth. Three reviewers 
> found this independently.
>   2. Exponential tree walk (OneNoteTreeWalker:648). The same shape: shared 
> objects are walked once per reference path. Each visit also builds and keeps 
> a HashMap of decoded properties, which OneNoteParser:144 throws away.
>   3. Wrong references, lost text (OneNotePtr:1185). The OID/OSID/ContextID 
> stream position is copied to a local variable and never written back. Every 
> reference property starts again at stream[0], so later references are never 
> walked. It also removes the
>      cap on reference counts.
>   4. Duplicate text in real files (OneNoteTreeWalker:569-592). Reproduced: 
> testOneNote2.one produces 176 paragraphs, 105 of them "Untitled picture.png". 
> Image filenames and TextExtendedAscii text are never deduplicated and ignore 
> the revision filter.
>   5. Unchecked counts and budgets (OneNotePtr:838, :518, :809):
>      - ObjectInfoDependencyOverrideData counts are unbounded.
>      - The global-ID cap applies per node, with no total.
>      - A negative FileDataStoreObject length gets through.
>   6. Smaller issues:
>      - Embedded file data is read in full before shouldParseEmbedded is asked 
> (OneNoteTreeWalker:435).
>      - The UTF-16 NUL terminator stays in author names and image filenames.
>   Legacy string dump, used whenever a parse falls back 
> (OneNoteLegacyDumpStrings:95):
>   - Never resets its buffer at 1 MB boundaries. A long run is emitted again 
> at every boundary, so work grows quadratically and normal files over 1 MB get 
> duplicated text.
>   - Small bugs: it drops the last byte of each buffer, 
> Character.isWhitespace(i) tests the loop index instead of the character, and 
> split(" ") allocates one String per word.
>   Fallback after a partial walk (OneNoteParser:172, :197): on both paths, the 
> full legacy dump is added after whatever the failed walk already wrote, so 
> content appears twice.
>   FSSHTTPB:
>   - GUIDs are MD5 hashes, not decoded (BitReader:140, AdapterHelper:37). They 
> come from UUID.nameUUIDFromBytes. As a result:
>     - Encrypted sections are never detected; the check at 
> MSOneStoreParser:328 can't match.
>     - Embedded relationship IDs contain hashed GUIDs.
>   - Every cell mapping copies its whole revision chain 
> (MSOneStoreParser:362), so the cost grows with mappings × objects.
>   - Slow spots:
>     - removeSupersededObjects is O(n²) (:393).
>     - resourceInfoFromReferencingObject scans every object for each unnamed 
> blob (MSOneStorePackage:1140).
>     - hasUsablePicture copies a whole blob just to check it's non-empty 
> (:1118).
>   - Small port bugs:
>     - cProperties is read as signed, so values ≥ 0x8000 abort the parse.
>     - An undefined property type throws an NPE.
>     - StorageManifestSchemaGUID reads from offset 0 instead of the current 
> position.
>     - BitConverter's bounds check ignores the index.
>   Dead code:
>   - The serialize/write path: 65 files, about 970 lines.
>   - The FSSHTTPD chunking/build side.
>   - getContent() and its builders.
>   - Unreferenced classes: Error, PropertyIDType, RequestTypes, UMath.
>   - Debug print() methods and option branches that are never set.
> {noformat}



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to