Author: kiwiwings
Date: Mon May 21 23:17:57 2018
New Revision: 1831992

URL: http://svn.apache.org/viewvc?rev=1831992&view=rev
Log:
sonar fixes - null dereference

Modified:
    
poi/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java
    poi/trunk/src/java/org/apache/poi/common/usermodel/fonts/FontGroup.java
    poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java
    poi/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java
    poi/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/HPBFPart.java
    
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java
    
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectShape.java
    
poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java

Modified: 
poi/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- 
poi/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java
 (original)
+++ 
poi/trunk/src/examples/src/org/apache/poi/hssf/usermodel/examples/AddDimensionedImage.java
 Mon May 21 23:17:57 2018
@@ -279,14 +279,19 @@ public class AddDimensionedImage {
         // The first two parameters are not used currently but could be if the
         // need arose to extend the functionality of this code by adding the
         // ability to specify that a clear 'border' be placed around the image.
-        anchor = new HSSFClientAnchor(0,
-                                      0,
-                                      colClientAnchorDetail.getInset(),
-                                      rowClientAnchorDetail.getInset(),
-                                      
(short)colClientAnchorDetail.getFromIndex(),
-                                      rowClientAnchorDetail.getFromIndex(),
-                                      
(short)colClientAnchorDetail.getToIndex(),
-                                      rowClientAnchorDetail.getToIndex());
+        int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0;
+        short col1 = 0, col2 = 0, row1 = 0, row2 = 0;
+        if (colClientAnchorDetail != null) {
+            dx2 = colClientAnchorDetail.getInset();
+            col1 = (short)colClientAnchorDetail.getFromIndex();
+            col2 = (short)colClientAnchorDetail.getToIndex();
+        }
+        if (rowClientAnchorDetail != null) {
+            dy2 = rowClientAnchorDetail.getInset();
+            row1 = (short)rowClientAnchorDetail.getFromIndex();
+            row2 = (short)rowClientAnchorDetail.getToIndex();
+        }
+        anchor = new HSSFClientAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, 
row2);
 
         // For now, set the anchor type to do not move or resize the
         // image as the size of the row/column is adjusted. This could easilly

Modified: 
poi/trunk/src/java/org/apache/poi/common/usermodel/fonts/FontGroup.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/common/usermodel/fonts/FontGroup.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/common/usermodel/fonts/FontGroup.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/common/usermodel/fonts/FontGroup.java Mon 
May 21 23:17:57 2018
@@ -110,8 +110,11 @@ public enum FontGroup {
      * @param runText the text which font groups are to be analyzed
      * @return the FontGroup
      */
-    public static List<FontGroupRange> getFontGroupRanges(String runText) {
+    public static List<FontGroupRange> getFontGroupRanges(final String 
runText) {
         List<FontGroupRange> ttrList = new ArrayList<>();
+        if (runText == null || runText.isEmpty()) {
+            return ttrList;
+        }
         FontGroupRange ttrLast = null;
         final int rlen = (runText != null) ? runText.length() : 0;
         for(int cp, i = 0, charCount; i < rlen; i += charCount) {

Modified: poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/model/InternalSheet.java Mon May 21 
23:17:57 2018
@@ -1377,7 +1377,9 @@ public final class InternalSheet {
             windowTwo.setFreezePanes(false);
             windowTwo.setFreezePanesNoSplit(false);
             SelectionRecord sel = (SelectionRecord) 
findFirstRecordBySid(SelectionRecord.sid);
-            sel.setPane(PaneInformation.PANE_UPPER_LEFT);
+            if (sel != null) {
+                sel.setPane(PaneInformation.PANE_UPPER_LEFT);
+            }
             return;
         }
 
@@ -1402,8 +1404,9 @@ public final class InternalSheet {
         windowTwo.setFreezePanesNoSplit(true);
 
         SelectionRecord sel = (SelectionRecord) 
findFirstRecordBySid(SelectionRecord.sid);
-        sel.setPane((byte)pane.getActivePane());
-
+        if (sel != null) {
+            sel.setPane((byte) pane.getActivePane());
+        }
     }
 
     /**
@@ -1437,7 +1440,9 @@ public final class InternalSheet {
         windowTwo.setFreezePanesNoSplit(false);
 
         SelectionRecord sel = (SelectionRecord) 
findFirstRecordBySid(SelectionRecord.sid);
-        sel.setPane(PANE_LOWER_RIGHT);
+        if (sel != null) {
+            sel.setPane(PANE_LOWER_RIGHT);
+        }
 
     }
 

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/EscherGraphics2d.java Mon 
May 21 23:17:57 2018
@@ -379,7 +379,8 @@ public final class EscherGraphics2d exte
     public Rectangle getClipBounds()
     {
         if(getDeviceclip() != null) {
-            return getClip().getBounds();
+            final Shape clip = getClip();
+            return clip != null ? clip.getBounds() : null;
         }
         return null;
     }

Modified: 
poi/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java 
Mon May 21 23:17:57 2018
@@ -218,9 +218,13 @@ public abstract class ChunkedCipherOutpu
         int ciLen = (doFinal)
             ? cipher.doFinal(chunk, 0, posInChunk, chunk)
             : cipher.update(chunk, 0, posInChunk, chunk);
-        
-        for (int i = plainByteFlags.nextSetBit(0); i >= 0 && i < posInChunk; i 
= plainByteFlags.nextSetBit(i+1)) {
-            chunk[i] = plain[i];
+
+        if (plain != null) {
+            int i = plainByteFlags.nextSetBit(0);
+            while (i >= 0 && i < posInChunk) {
+                chunk[i] = plain[i];
+                i = plainByteFlags.nextSetBit(i+1);
+            }
         }
         
         return ciLen;

Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/xor/XOREncryptor.java Mon May 
21 23:17:57 2018
@@ -164,8 +164,12 @@ public class XOREncryptor extends Encryp
                 chunk[i] = value;
             }
 
-            for (int i = plainBytes.nextSetBit(start); i >= 0 && i < 
posInChunk; i = plainBytes.nextSetBit(i+1)) {
-                chunk[i] = plain[i];
+            if (plain != null) {
+                int i = plainBytes.nextSetBit(start);
+                while (i >= 0 && i < posInChunk) {
+                    chunk[i] = plain[i];
+                    i = plainBytes.nextSetBit(i + 1);
+                }
             }
 
             return posInChunk;

Modified: 
poi/trunk/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- 
poi/trunk/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java 
(original)
+++ 
poi/trunk/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java 
Mon May 21 23:17:57 2018
@@ -18,6 +18,7 @@
 package org.apache.poi.poifs.filesystem;
 
 import java.io.IOException;
+import java.util.function.Function;
 
 import org.apache.poi.poifs.storage.DataInputBlock;
 import org.apache.poi.util.RecordFormatException;
@@ -214,40 +215,57 @@ public final class ODocumentInputStream
    @Override
        public void readFully(byte[] buf, int off, int len) {
                checkAvaliable(len);
-               int blockAvailable = _currentBlock.available();
+
+               Function<Integer,DataInputBlock> nextDataInputBlock = (offset) 
-> {
+                       if (offset >= _document_size) {
+                               _currentBlock = null;
+                       } else if (offset != _current_offset) {
+                               _currentBlock = getDataInputBlock(offset);
+                       }
+                       return _currentBlock;
+               };
+
+               _current_offset = readFullyInternal(buf, off, len, 
_current_offset, _document_size, nextDataInputBlock);
+       }
+
+       /* package */ static int readFullyInternal(byte[] buf, int off, int 
len, int currentOffset, int maxSize, Function<Integer,DataInputBlock> 
nextDataInputBlock) {
+               DataInputBlock currentBlock = 
nextDataInputBlock.apply(currentOffset);
+               if (currentBlock == null) {
+                       throw new IllegalStateException("reached end of 
document stream unexpectedly");
+               }
+               int blockAvailable = currentBlock.available();
                if (blockAvailable > len) {
-                       _currentBlock.readFully(buf, off, len);
-                       _current_offset += len;
-                       return;
+                       currentBlock.readFully(buf, off, len);
+                       return currentOffset + len;
                }
                // else read big amount in chunks
                int remaining = len;
                int writePos = off;
+               int offset = currentOffset;
                while (remaining > 0) {
-                       boolean blockIsExpiring = remaining >= blockAvailable;
-                       int reqSize;
-                       if (blockIsExpiring) {
-                               reqSize = blockAvailable;
-                       } else {
-                               reqSize = remaining;
-                       }
-                       _currentBlock.readFully(buf, writePos, reqSize);
+                       final boolean blockIsExpiring = remaining >= 
blockAvailable;
+                       final int reqSize = (blockIsExpiring) ? blockAvailable 
: remaining;
+                       currentBlock.readFully(buf, writePos, reqSize);
                        remaining -= reqSize;
                        writePos += reqSize;
-                       _current_offset += reqSize;
+                       offset += reqSize;
                        if (blockIsExpiring) {
-                               if (_current_offset == _document_size) {
+                               if (offset >= maxSize) {
                                        if (remaining > 0) {
                                                throw new IllegalStateException(
                                                                "reached end of 
document stream unexpectedly");
                                        }
-                                       _currentBlock = null;
                                        break;
                                }
-                               _currentBlock = 
getDataInputBlock(_current_offset);
-                               blockAvailable = _currentBlock.available();
+                               currentBlock = nextDataInputBlock.apply(offset);
+                               if (currentBlock == null) {
+                                       throw new IllegalStateException(
+                                                       "reached end of 
document stream unexpectedly");
+                               }
+                               blockAvailable = currentBlock.available();
                        }
                }
+               return offset;
        }
 
    @Override

Modified: poi/trunk/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java 
(original)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/OPOIFSDocument.java Mon 
May 21 23:17:57 2018
@@ -25,6 +25,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.function.Function;
 
 import org.apache.poi.poifs.common.POIFSBigBlockSize;
 import org.apache.poi.poifs.common.POIFSConstants;
@@ -228,43 +229,7 @@ public final class OPOIFSDocument implem
         * This method is currently (Oct 2008) only used by test code. Perhaps 
it can be deleted
         */
        void read(byte[] buffer, int offset) {
-               int len = buffer.length;
-
-               DataInputBlock currentBlock = getDataInputBlock(offset);
-
-               int blockAvailable = currentBlock.available();
-               if (blockAvailable > len) {
-                       currentBlock.readFully(buffer, 0, len);
-                       return;
-               }
-               // else read big amount in chunks
-               int remaining = len;
-               int writePos = 0;
-               int currentOffset = offset;
-               while (remaining > 0) {
-                       boolean blockIsExpiring = remaining >= blockAvailable;
-                       int reqSize;
-                       if (blockIsExpiring) {
-                               reqSize = blockAvailable;
-                       } else {
-                               reqSize = remaining;
-                       }
-                       currentBlock.readFully(buffer, writePos, reqSize);
-                       remaining-=reqSize;
-                       writePos+=reqSize;
-                       currentOffset += reqSize;
-                       if (blockIsExpiring) {
-                               if (currentOffset == _size) {
-                                       if (remaining > 0) {
-                                               throw new 
IllegalStateException("reached end of document stream unexpectedly");
-                                       }
-                                       currentBlock = null;
-                                       break;
-                               }
-                               currentBlock = getDataInputBlock(currentOffset);
-                               blockAvailable = currentBlock.available();
-                       }
-               }
+               ODocumentInputStream.readFullyInternal(buffer, 0, 
buffer.length, offset, _size, this::getDataInputBlock);
        }
 
        /**

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/HPBFPart.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/HPBFPart.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/HPBFPart.java 
(original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hpbf/model/HPBFPart.java Mon 
May 21 23:17:57 2018
@@ -64,6 +64,9 @@ public abstract class HPBFPart {
 
        public void writeOut(DirectoryNode baseDir) throws IOException {
                String[] path = getPath();
+               if (path == null) {
+                       return;
+               }
 
                // Ensure that all parent directories exist
                DirectoryNode dir = baseDir;

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java
 (original)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFFreeformShape.java
 Mon May 21 23:17:57 2018
@@ -301,44 +301,46 @@ public final class HSLFFreeformShape ext
         while (vertIter.hasNext() && segIter.hasNext()) {
             byte[] segElem = segIter.next();
             PathInfo pi = getPathInfo(segElem);
-            switch (pi) {
-                case escape: {
-                    // handleEscapeInfo(path, segElem, vertIter);
-                    break;
-                }
-                case moveTo: {
-                    fillPoint(vertIter.next(), xyPoints);
-                    double x = xyPoints[0];
-                    double y = xyPoints[1];
-                    path.moveTo(x,y);
-                    break;
-                }
-                case curveTo: {
-                    fillPoint(vertIter.next(), xyPoints);
-                    double x1 = xyPoints[0];
-                    double y1 = xyPoints[1];
-                    fillPoint(vertIter.next(), xyPoints);
-                    double x2 = xyPoints[0];
-                    double y2 = xyPoints[1];
-                    fillPoint(vertIter.next(), xyPoints);
-                    double x3 = xyPoints[0];
-                    double y3 = xyPoints[1];
-                    path.curveTo(x1,y1,x2,y2,x3,y3);
-                    break;
-                }
-                case lineTo:
-                    if (vertIter.hasNext()) {
+            if (pi != null) {
+                switch (pi) {
+                    case escape: {
+                        // handleEscapeInfo(path, segElem, vertIter);
+                        break;
+                    }
+                    case moveTo: {
                         fillPoint(vertIter.next(), xyPoints);
                         double x = xyPoints[0];
                         double y = xyPoints[1];
-                        path.lineTo(x,y);
+                        path.moveTo(x, y);
+                        break;
                     }
-                    break;
-                case close:
-                    path.closePath();
-                    break;
-                default:
-                    break;
+                    case curveTo: {
+                        fillPoint(vertIter.next(), xyPoints);
+                        double x1 = xyPoints[0];
+                        double y1 = xyPoints[1];
+                        fillPoint(vertIter.next(), xyPoints);
+                        double x2 = xyPoints[0];
+                        double y2 = xyPoints[1];
+                        fillPoint(vertIter.next(), xyPoints);
+                        double x3 = xyPoints[0];
+                        double y3 = xyPoints[1];
+                        path.curveTo(x1, y1, x2, y2, x3, y3);
+                        break;
+                    }
+                    case lineTo:
+                        if (vertIter.hasNext()) {
+                            fillPoint(vertIter.next(), xyPoints);
+                            double x = xyPoints[0];
+                            double y = xyPoints[1];
+                            path.lineTo(x, y);
+                        }
+                        break;
+                    case close:
+                        path.closePath();
+                        break;
+                    default:
+                        break;
+                }
             }
         }
 

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectShape.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectShape.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectShape.java 
(original)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFObjectShape.java 
Mon May 21 23:17:57 2018
@@ -212,7 +212,10 @@ public final class HSLFObjectShape exten
     }
 
     public void setFullName(final String fullName) {
-        getExEmbed(true).setClipboardName(fullName);
+        final ExEmbed ex = getExEmbed(true);
+        if (ex != null) {
+            ex.setClipboardName(fullName);
+        }
     }
 
     @Override
@@ -222,7 +225,10 @@ public final class HSLFObjectShape exten
     }
 
     public void setProgId(final String progId) {
-        getExEmbed(true).setProgId(progId);
+        final ExEmbed ex = getExEmbed(true);
+        if (ex != null) {
+            ex.setProgId(progId);
+        }
     }
 
     public OutputStream updateObjectData(final Application application, final 
ObjectMetaData metaData) throws IOException {
@@ -246,16 +252,18 @@ public final class HSLFObjectShape exten
 
                     poifs.getRoot().setStorageClsid(md.getClassID());
 
-
                     int oid = getObjectID();
                     if (oid == 0) {
                         // assign new embedding
                         oid = ppt.addEmbed(poifs);
                         setObjectID(oid);
                     } else {
-                        ByteArrayOutputStream bos = new 
ByteArrayOutputStream(this.size()+1000);
-                        poifs.writeFilesystem(bos);
-                        getObjectData().setData(bos.toByteArray());
+                        final HSLFObjectData od = getObjectData();
+                        if (od != null) {
+                            ByteArrayOutputStream bos = new 
ByteArrayOutputStream(this.size()+1000);
+                            poifs.writeFilesystem(bos);
+                            od.setData(bos.toByteArray());
+                        }
                     }
 
                     setProgId(md.getProgId());

Modified: 
poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java?rev=1831992&r1=1831991&r2=1831992&view=diff
==============================================================================
--- 
poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java 
(original)
+++ 
poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java 
Mon May 21 23:17:57 2018
@@ -208,15 +208,17 @@ public final class HeaderStories {
                // First page header is optional, only return
                //  if it's set
                if(pageNumber == 1) {
-                       if(getFirstHeader().length() > 0) {
-                               return getFirstHeader();
+            final String fh = getFirstHeader();
+                       if(fh != null && !fh.isEmpty()) {
+                               return fh;
                        }
                }
                // Even page header is optional, only return
                //  if it's set
                if(pageNumber % 2 == 0) {
-                       if(getEvenHeader().length() > 0) {
-                               return getEvenHeader();
+            final String eh = getEvenHeader();
+                       if(eh != null && !eh.isEmpty()) {
+                               return eh;
                        }
                }
                // Odd is the default
@@ -274,15 +276,17 @@ public final class HeaderStories {
                // First page footer is optional, only return
                //  if it's set
                if(pageNumber == 1) {
-                       if(getFirstFooter().length() > 0) {
-                               return getFirstFooter();
+                   final String ff = getFirstFooter();
+                       if(ff != null && !ff.isEmpty()) {
+                               return ff;
                        }
                }
                // Even page footer is optional, only return
                //  if it's set
                if(pageNumber % 2 == 0) {
-                       if(getEvenFooter().length() > 0) {
-                               return getEvenFooter();
+                   final String ef = getEvenFooter();
+                       if(ef != null && !ef.isEmpty()) {
+                               return ef;
                        }
                }
                // Odd is the default



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to