diff --git a/bigbluebutton-web/pres-checker/.gitignore b/bigbluebutton-web/pres-checker/.gitignore new file mode 100644 index 0000000000..d203e12ec5 --- /dev/null +++ b/bigbluebutton-web/pres-checker/.gitignore @@ -0,0 +1,4 @@ +lib/ +build/ +.gradle + diff --git a/bigbluebutton-web/pres-checker/build.gradle b/bigbluebutton-web/pres-checker/build.gradle new file mode 100755 index 0000000000..37464055e3 --- /dev/null +++ b/bigbluebutton-web/pres-checker/build.gradle @@ -0,0 +1,38 @@ +apply plugin: 'java' + +sourceCompatibility=1.8 +targetCompatibility=1.8 + +version = '0.0.1' +archivesBaseName = 'bbb-pres-check' + +task resolveDeps(type: Copy) { + into('lib') + from configurations.default + from configurations.default.allArtifacts.file +} + +repositories { + mavenCentral() + mavenLocal() +} + +dependencies { + compile 'org.apache.poi:poi:3.15@jar' + compile 'org.apache.poi:poi-ooxml:3.15@jar' + compile 'org.apache.poi:poi-ooxml-schemas:3.15@jar' + compile 'commons-io:commons-io:2.4@jar' + compile 'org.apache.commons:commons-lang3:3.5@jar' + compile 'org.apache.commons:commons-collections4:4.1@jar' + compile 'org.apache.xmlbeans:xmlbeans:2.6.0@jar' +} + +jar { + manifest.mainAttributes("Permissions": "all-permissions") + manifest.mainAttributes("Codebase": "*") + manifest.mainAttributes("Application-Name": "BigBlueButton Presentation Checker") + manifest.mainAttributes("Application-Library-Allowable-Codebase": "*") + manifest.mainAttributes("Caller-Allowable-Codebase": "*") + manifest.mainAttributes("Trusted-Only": "true") +} + diff --git a/bigbluebutton-web/pres-checker/build.sh b/bigbluebutton-web/pres-checker/build.sh new file mode 100755 index 0000000000..1f5048f557 --- /dev/null +++ b/bigbluebutton-web/pres-checker/build.sh @@ -0,0 +1,4 @@ +gradle clean +gradle jar +cp build/lib/*.jar lib + diff --git a/bigbluebutton-web/pres-checker/run.sh b/bigbluebutton-web/pres-checker/run.sh new file mode 100755 index 0000000000..d549a81cef --- /dev/null +++ b/bigbluebutton-web/pres-checker/run.sh @@ -0,0 +1,2 @@ +java -cp "lib/*" org.bigbluebutton.prescheck.Main $@ + diff --git a/bigbluebutton-web/pres-checker/src/main/java/org/bigbluebutton/prescheck/Main.java b/bigbluebutton-web/pres-checker/src/main/java/org/bigbluebutton/prescheck/Main.java new file mode 100755 index 0000000000..f484d28031 --- /dev/null +++ b/bigbluebutton-web/pres-checker/src/main/java/org/bigbluebutton/prescheck/Main.java @@ -0,0 +1,94 @@ +package org.bigbluebutton.prescheck; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.Predicate; +import org.apache.commons.io.FilenameUtils; +import org.apache.poi.util.LittleEndian; +import org.apache.poi.xslf.usermodel.XMLSlideShow; +import org.apache.poi.xslf.usermodel.XSLFPictureData; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.ArrayList; + +public class Main { + + public static void main(String[] args) { + Main main = new Main(); + + String filepath; + try { + // Parse the string argument into an integer value. + filepath = args[0]; + boolean valid = main.check(main, filepath); + if (!valid) System.exit(2); + System.exit(0); + } + catch (Exception nfe) { + System.exit(1); + } + + } + + private boolean check(Main main, String file) { + boolean valid = true; + XMLSlideShow xmlSlideShow; + try { + xmlSlideShow = new XMLSlideShow(new FileInputStream(file)); + valid &= !main.embedsEmf(xmlSlideShow); + valid &= !main.containsTinyTileBackground(xmlSlideShow); + // Close the resource once we finished reading it + xmlSlideShow.close(); + } catch (IOException e) { + valid = false; + } + + return valid; + } + + /** + * Checks if the slide-show file embeds any EMF document + * + * @param xmlSlideShow + * @return + */ + private boolean embedsEmf(XMLSlideShow xmlSlideShow) { + EmfPredicate emfPredicate = new EmfPredicate(); + ArrayList embeddedEmfFiles = (ArrayList) CollectionUtils + .select(xmlSlideShow.getPictureData(), emfPredicate); + if (embeddedEmfFiles.size() > 0) { + return true; + } + return false; + } + + /** + * Checks if the slide-show contains a small background tile image + * + * @param xmlSlideShow + * @return + */ + private boolean containsTinyTileBackground(XMLSlideShow xmlSlideShow) { + TinyTileBackgroundPredicate tinyTileCondition = new TinyTileBackgroundPredicate(); + ArrayList tileImage = (ArrayList) CollectionUtils + .select(xmlSlideShow.getPictureData(), tinyTileCondition); + if (tileImage.size() > 0) { + return true; + } + return false; + } + + private final class EmfPredicate implements Predicate { + public boolean evaluate(XSLFPictureData img) { + return img.getContentType().equals("image/x-emf"); + } + } + + private final class TinyTileBackgroundPredicate + implements Predicate { + public boolean evaluate(XSLFPictureData img) { + return img.getContentType() != null + && img.getContentType().equals("image/jpeg") + && LittleEndian.getLong(img.getChecksum()) == 4114937224L; + } + } +}