Path: blob/master/test/jdk/javax/swing/JPasswordField/CleanInternalStorageOnSetText.java
41152 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.awt.EventQueue;24import java.util.ArrayList;25import java.util.Arrays;2627import javax.swing.JPasswordField;28import javax.swing.text.BadLocationException;29import javax.swing.text.Document;30import javax.swing.text.GapContent;31import javax.swing.text.PlainDocument;32import javax.swing.text.Segment;33import javax.swing.text.StringContent;34import javax.swing.text.html.HTMLDocument;35import javax.swing.text.html.StyleSheet;3637/**38* @test39* @bug 825837340* @summary The JPasswordField#setText() should reset the old internal storage41*/42public final class CleanInternalStorageOnSetText {4344public static void main(String[] args) throws Exception {45EventQueue.invokeAndWait(() -> {46// default case47testStorage(false, new JPasswordField());48testStorage(true, new JPasswordField());4950// custom Plain String document51Document document = new PlainDocument(new StringContent());52testStorage(false, new JPasswordField(document, "", 10));53document = new PlainDocument(new StringContent());54testStorage(true, new JPasswordField(document, "", 10));5556// custom Plain GAP document57document = new PlainDocument(new GapContent());58testStorage(false, new JPasswordField(document, "", 10));59document = new PlainDocument(new GapContent());60testStorage(true, new JPasswordField(document, "", 10));6162// custom HTMLDocument String document63document = new HTMLDocument(new StringContent(), new StyleSheet());64testStorage(false, new JPasswordField(document, "", 10));65document = new HTMLDocument(new StringContent(), new StyleSheet());66testStorage(true, new JPasswordField(document, "", 10));6768// custom HTMLDocument GAP document69document = new HTMLDocument(new GapContent(), new StyleSheet());70testStorage(false, new JPasswordField(document, "", 10));71document = new HTMLDocument(new GapContent(), new StyleSheet());72testStorage(true, new JPasswordField(document, "", 10));73});74}7576private static void testStorage(boolean makeGap, JPasswordField pf) {77test(pf, "123", makeGap);78test(pf, "1234567", makeGap);79test(pf, "1234567890", makeGap);80test(pf, "1".repeat(100), makeGap);81test(pf, "1234567890", makeGap);82test(pf, "1234567", makeGap);83test(pf, "123", makeGap);84test(pf, "", makeGap);85}8687private static void test(JPasswordField pf, String text, boolean makeGap) {88pf.setText(text);89if (makeGap && text.length() > 3) {90try {91pf.getDocument().remove(1, 2);92} catch (BadLocationException e) {93throw new RuntimeException(e);94}95}96// if no gaps we can check whole array97char[] internalArray = getInternalArray(pf);98ArrayList<Segment> segments = new ArrayList<>();99if (makeGap) {100// if gaps exists we can check only part of the array101Document doc = pf.getDocument();102int nleft = doc.getLength();103Segment sgm = new Segment();104sgm.setPartialReturn(true);105int offs = 0;106try {107while (nleft > 0) {108doc.getText(offs, nleft, sgm);109segments.add(sgm);110nleft -= sgm.count;111offs += sgm.count;112}113} catch (BadLocationException e) {114throw new RuntimeException(e);115}116}117System.err.println("Before = " + Arrays.toString(internalArray));118pf.setText("");119System.err.println("After = " + Arrays.toString(internalArray));120121if (!makeGap) {122for (char c : internalArray) {123if (c != '\u0000' && c != '\n') {124throw new RuntimeException(Arrays.toString(internalArray));125}126}127} else {128for (Segment sgm : segments) {129for (int i = sgm.offset; i < sgm.count + sgm.offset; i++) {130char c = sgm.array[i];131if (c != '\u0000' && c != '\n') {132throw new RuntimeException(Arrays.toString(sgm.array));133}134}135}136}137}138139/**140* This method returns the reference to the internal data stored by the141* document inside JPasswordField.142*/143private static char[] getInternalArray(JPasswordField pf) {144Document doc = pf.getDocument();145int nleft = doc.getLength();146Segment text = new Segment();147int offs = 0;148text.setPartialReturn(true);149try {150doc.getText(offs, nleft, text);151} catch (BadLocationException e) {152throw new RuntimeException(e);153}154return text.array;155}156}157158159