@Override
    public void visitFromDictionary(COSDictionary obj) throws IOException {
        if (!reachedSignature) {
            COSBase itemType = obj.getItem(COSName.TYPE);
            if (COSName.SIG.equals(itemType) || COSName.DOC_TIME_STAMP.equals(itemType)) {
                reachedSignature = true;
            }
        }
        getStandardOutput().write(DICT_OPEN);
        getStandardOutput().writeEOL();
        for (Map.Entry<COSName, COSBase> entry : obj.entrySet()) {
            COSBase value = entry.getValue();
            if (value != null) {
                entry.getKey().accept(this);
                getStandardOutput().write(SPACE);
                if (value instanceof COSDictionary) {
                    COSDictionary dict = (COSDictionary) value;

                    if (!incrementalUpdate) {
                        // write all XObjects as direct objects, this will save some size
                        // PDFBOX-3684: but avoid dictionary that references itself
                        COSBase item = dict.getItem(COSName.XOBJECT);
                        if (item != null && !COSName.XOBJECT.equals(entry.getKey())) {
                            item.setDirect(true);
                        }
                        item = dict.getItem(COSName.RESOURCES);
                        if (item != null && !COSName.RESOURCES.equals(entry.getKey())) {
                            item.setDirect(true);
                        }
                    }

                    if (dict.isDirect()) {
                        // If the object should be written direct, we need
                        // to pass the dictionary to the visitor again.
                        visitFromDictionary(dict);
                    } else {
                        addObjectToWrite(dict);
                        writeReference(dict);
                    }
                } else if (value instanceof COSObject) {
                    COSBase subValue = ((COSObject) value).getObject();
                    if (willEncrypt || incrementalUpdate || subValue instanceof COSDictionary ||
                            subValue == null) {
                        // PDFBOX-4308: added willEncrypt to prevent an object
                        // that is referenced several times from being written
                        // direct and indirect, thus getting encrypted
                        // with wrong object number or getting encrypted twice
                        addObjectToWrite(value);
                        writeReference(value);
                    } else {
                        subValue.accept(this);
                    }
                } else {
                    // If we reach the pdf signature, we need to determinate the position of the
                    // content and byterange
                    if (reachedSignature && COSName.CONTENTS.equals(entry.getKey())) {
                        signatureOffset = getStandardOutput().getPos();
                        value.accept(this);
                        signatureLength = getStandardOutput().getPos() - signatureOffset;
                    } else if (reachedSignature && COSName.BYTERANGE.equals(entry.getKey())) {
                        byteRangeArray = (COSArray) entry.getValue();
                        byteRangeOffset = getStandardOutput().getPos() + 1;
                        value.accept(this);
                        byteRangeLength = getStandardOutput().getPos() - 1 - byteRangeOffset;
                        reachedSignature = false;
                    } else {
                        value.accept(this);
                    }
                }
                getStandardOutput().writeEOL();

            } else {
                //then we won't write anything, there are a couple cases
                //were the value of an entry in the COSDictionary will
                //be a dangling reference that points to nothing
                //so we will just not write out the entry if that is the case
            }
        }
        getStandardOutput().write(DICT_CLOSE);
        getStandardOutput().writeEOL();
    }
This will get the object key for the object.

@param obj The object to get the key for.
@return The object key for the object.
tika-fuzzing/src/main/java/org/apache/tika/fuzzing/pdf/EvilCOSWriter.java