Autopsy  4.14.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
HtmlPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.contentviewers;
20 
21 import java.io.IOException;
22 import java.io.StringReader;
23 import java.util.List;
24 import java.util.logging.Level;
26 import javafx.application.Platform;
27 import javafx.beans.value.ChangeListener;
28 import javafx.beans.value.ObservableValue;
29 import javafx.concurrent.Worker;
30 import javafx.scene.web.WebView;
31 import javafx.embed.swing.JFXPanel;
32 import javafx.scene.Scene;
33 import net.htmlparser.jericho.Attribute;
34 import net.htmlparser.jericho.OutputDocument;
35 import net.htmlparser.jericho.Source;
36 import org.openide.util.NbBundle.Messages;
37 import org.w3c.dom.Document;
38 import org.w3c.dom.NodeList;
39 import org.w3c.dom.events.EventTarget;
40 
44 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
45 final class HtmlPanel extends javax.swing.JPanel {
46 
47  private static final Logger logger = Logger.getLogger(HtmlPanel.class.getName());
48  private static final long serialVersionUID = 1L;
49  private static final String TEXT_TYPE = "text/plain";
50  private final JFXPanel jfxPanel = new JFXPanel();
51  private WebView webView;
52  private String htmlText;
53 
57  HtmlPanel() {
58  initComponents();
59  Platform.runLater(() -> {
60  webView = new WebView();
61  //disable the context menu so they can't open linked pages by right clicking
62  webView.setContextMenuEnabled(false);
63  //disable java script
64  webView.getEngine().setJavaScriptEnabled(false);
65  //disable clicking on links
66  webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
67  @Override
68  public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue) {
69  if (newValue == Worker.State.SUCCEEDED) {
70  disableHyperLinks();
71  }
72  }
73  });
74  Scene scene = new Scene(webView);
75  jfxPanel.setScene(scene);
76  jfxPanel.setPreferredSize(htmlJPanel.getPreferredSize());
77  htmlJPanel.add(jfxPanel);
78  });
79  }
80 
86  void setHtmlText(String htmlText) {
87  this.htmlText = htmlText;
88  refresh();
89  }
90 
94  void reset() {
95  Platform.runLater(() -> {
96  webView.getEngine().loadContent("", TEXT_TYPE);
97  });
98  showImagesToggleButton.setEnabled(false);
99  }
100 
108  private String cleanseHTML(String htmlInString) {
109  String returnString = "";
110  try {
111  Source source = new Source(new StringReader(htmlInString));
112  OutputDocument document = new OutputDocument(source);
113  //remove background images
114  source.getAllTags().stream().filter((tag) -> (tag.toString().contains("background-image"))).forEachOrdered((tag) -> {
115  document.remove(tag);
116  });
117  //remove images
118  source.getAllElements("img").forEach((element) -> {
119  document.remove(element.getAllTags());
120  });
121  //remove frames
122  source.getAllElements("frame").forEach((element) -> {
123  document.remove(element.getAllTags());
124  });
125  //remove iframes
126  source.getAllElements("iframe").forEach((element) -> {
127  document.remove(element.getAllTags());
128  });
129  //remove pictures
130  source.getAllElements("picture").forEach((element) -> {
131  document.remove(element.getAllTags());
132  });
133  //remove svg
134  source.getAllElements("svg").forEach((element) -> {
135  document.remove(element.getAllTags());
136  });
137  //remove audio
138  source.getAllElements("audio").forEach((element) -> {
139  document.remove(element.getAllTags());
140  });
141  //remove video
142  source.getAllElements("video").forEach((element) -> {
143  document.remove(element.getAllTags());
144  });
145  //remove tracks
146  source.getAllElements("track").forEach((element) -> {
147  document.remove(element.getAllTags());
148  });
149  //remove embeded external elements
150  source.getAllElements("embed").forEach((element) -> {
151  document.remove(element.getAllTags());
152  });
153  //remove linked elements
154  source.getAllElements("link").forEach((element) -> {
155  document.remove(element.getAllTags());
156  });
157  //remove other URI elements such as input boxes
158  List<Attribute> attributesToRemove = source.getURIAttributes();
159  document.remove(attributesToRemove);
160  returnString = document.toString();
161  } catch (IOException ex) {
162  logger.log(Level.WARNING, "Unable to read html for cleaning out URI elements with Jericho", ex);
163  }
164  return returnString;
165  }
166 
170  @Messages({
171  "HtmlPanel_showImagesToggleButton_show=Download Images",
172  "HtmlPanel_showImagesToggleButton_hide=Hide Images",
173  "Html_text_display_error=The HTML text cannot be displayed, it may not be correctly formed HTML.",})
174  private void refresh() {
175  if (false == htmlText.isEmpty()) {
176  try {
177  if (showImagesToggleButton.isSelected()) {
178  showImagesToggleButton.setText(Bundle.HtmlPanel_showImagesToggleButton_hide());
179  Platform.runLater(() -> {
180  webView.getEngine().loadContent(htmlText);
181  });
182  } else {
183  showImagesToggleButton.setText(Bundle.HtmlPanel_showImagesToggleButton_show());
184  Platform.runLater(() -> {
185  webView.getEngine().loadContent(cleanseHTML(htmlText));
186  });
187  }
188  showImagesToggleButton.setEnabled(true);
189  } catch (Exception ignored) {
190  Platform.runLater(() -> {
191  webView.getEngine().loadContent(Bundle.Html_text_display_error(), TEXT_TYPE);
192  });
193  }
194  }
195  }
196 
202  @SuppressWarnings("unchecked")
203  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
204  private void initComponents() {
205 
206  showImagesToggleButton = new javax.swing.JToggleButton();
207  htmlJPanel = new javax.swing.JPanel();
208 
209  org.openide.awt.Mnemonics.setLocalizedText(showImagesToggleButton, org.openide.util.NbBundle.getMessage(HtmlPanel.class, "HtmlPanel.showImagesToggleButton.text")); // NOI18N
210  showImagesToggleButton.addActionListener(new java.awt.event.ActionListener() {
211  public void actionPerformed(java.awt.event.ActionEvent evt) {
212  showImagesToggleButtonActionPerformed(evt);
213  }
214  });
215 
216  htmlJPanel.setLayout(new java.awt.BorderLayout());
217 
218  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
219  this.setLayout(layout);
220  layout.setHorizontalGroup(
221  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
222  .addGroup(layout.createSequentialGroup()
223  .addComponent(showImagesToggleButton)
224  .addGap(0, 75, Short.MAX_VALUE))
225  .addComponent(htmlJPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
226  );
227  layout.setVerticalGroup(
228  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
229  .addGroup(layout.createSequentialGroup()
230  .addComponent(showImagesToggleButton)
231  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
232  .addComponent(htmlJPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 33, Short.MAX_VALUE))
233  );
234  }// </editor-fold>//GEN-END:initComponents
235 
236  private void showImagesToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showImagesToggleButtonActionPerformed
237  refresh();
238  }//GEN-LAST:event_showImagesToggleButtonActionPerformed
239 
244  private void disableHyperLinks() {
245  Platform.runLater(() -> {
246  Document document = webView.getEngine().getDocument();
247  if (document != null) {
248  NodeList nodeList = document.getElementsByTagName("a");
249  for (int i = 0; i < nodeList.getLength(); i++) {
250  ((EventTarget) nodeList.item(i)).addEventListener("click", (evt) -> {
251  evt.preventDefault();
252  evt.stopPropagation();
253  }, true);
254  }
255  }
256  });
257  }
258 
259  // Variables declaration - do not modify//GEN-BEGIN:variables
260  private javax.swing.JPanel htmlJPanel;
261  private javax.swing.JToggleButton showImagesToggleButton;
262  // End of variables declaration//GEN-END:variables
263 }

Copyright © 2012-2020 Basis Technology. Generated on: Wed Apr 8 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.