提交 8a936420 编写于 作者: C chegar

Merge

......@@ -106,7 +106,21 @@ FILES_cpp_shared = \
OpenTypeLayoutEngine.cpp \
ThaiLayoutEngine.cpp \
ScriptAndLanguageTags.cpp \
FontInstanceAdapter.cpp
FontInstanceAdapter.cpp \
ContextualGlyphInsertionProc2.cpp \
ContextualGlyphSubstProc2.cpp \
GXLayoutEngine2.cpp \
IndicRearrangementProcessor2.cpp \
LigatureSubstProc2.cpp \
MorphTables2.cpp \
NonContextualGlyphSubstProc2.cpp \
SegmentArrayProcessor2.cpp \
SegmentSingleProcessor2.cpp \
SimpleArrayProcessor2.cpp \
SingleTableProcessor2.cpp \
StateTableProcessor2.cpp \
SubtableProcessor2.cpp \
TrimmedArrayProcessor2.cpp
ifeq ($(PLATFORM),windows)
......
......@@ -170,7 +170,7 @@ public class LWWindowPeer
setTitle(((Dialog) getTarget()).getTitle());
}
setAlwaysOnTop(getTarget().isAlwaysOnTop());
updateAlwaysOnTopState();
updateMinimumSize();
final Shape shape = getTarget().getShape();
......@@ -357,8 +357,8 @@ public class LWWindowPeer
}
@Override
public void setAlwaysOnTop(boolean value) {
platformWindow.setAlwaysOnTop(value);
public void updateAlwaysOnTopState() {
platformWindow.setAlwaysOnTop(getTarget().isAlwaysOnTop());
}
@Override
......
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -180,7 +180,7 @@ class CFileDialog implements FileDialogPeer {
}
@Override
public void setAlwaysOnTop(boolean alwaysOnTop) {
public void updateAlwaysOnTopState() {
}
@Override
......
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -87,7 +87,7 @@ public class CPrinterDialogPeer extends LWWindowPeer {
}
// 1.6 peer method
public void setAlwaysOnTop(boolean value) {
public void updateAlwaysOnTopState() {
// no-op, since we just show the native print dialog
}
......
......@@ -243,12 +243,17 @@ public class JPEGImageReader extends ImageReader {
* sending warnings to listeners.
*/
protected void warningOccurred(int code) {
if ((code < 0) || (code > MAX_WARNING)){
throw new InternalError("Invalid warning index");
cbLock.lock();
try {
if ((code < 0) || (code > MAX_WARNING)){
throw new InternalError("Invalid warning index");
}
processWarningOccurred
("com.sun.imageio.plugins.jpeg.JPEGImageReaderResources",
Integer.toString(code));
} finally {
cbLock.unlock();
}
processWarningOccurred
("com.sun.imageio.plugins.jpeg.JPEGImageReaderResources",
Integer.toString(code));
}
/**
......@@ -265,7 +270,12 @@ public class JPEGImageReader extends ImageReader {
* library warnings from being printed to stderr.
*/
protected void warningWithMessage(String msg) {
processWarningOccurred(msg);
cbLock.lock();
try {
processWarningOccurred(msg);
} finally {
cbLock.unlock();
}
}
public void setInput(Object input,
......@@ -274,18 +284,55 @@ public class JPEGImageReader extends ImageReader {
{
setThreadLock();
try {
cbLock.check();
super.setInput(input, seekForwardOnly, ignoreMetadata);
this.ignoreMetadata = ignoreMetadata;
resetInternalState();
iis = (ImageInputStream) input; // Always works
setSource(structPointer, iis);
setSource(structPointer);
} finally {
clearThreadLock();
}
}
private native void setSource(long structPointer,
ImageInputStream source);
/**
* This method is called from native code in order to fill
* native input buffer.
*
* We block any attempt to change the reading state during this
* method, in order to prevent a corruption of the native decoder
* state.
*
* @return number of bytes read from the stream.
*/
private int readInputData(byte[] buf, int off, int len) throws IOException {
cbLock.lock();
try {
return iis.read(buf, off, len);
} finally {
cbLock.unlock();
}
}
/**
* This method is called from the native code in order to
* skip requested number of bytes in the input stream.
*
* @param n
* @return
* @throws IOException
*/
private long skipInputBytes(long n) throws IOException {
cbLock.lock();
try {
return iis.skipBytes(n);
} finally {
cbLock.unlock();
}
}
private native void setSource(long structPointer);
private void checkTablesOnly() throws IOException {
if (debug) {
......@@ -337,6 +384,8 @@ public class JPEGImageReader extends ImageReader {
public int getNumImages(boolean allowSearch) throws IOException {
setThreadLock();
try { // locked thread
cbLock.check();
return getNumImagesOnThread(allowSearch);
} finally {
clearThreadLock();
......@@ -536,8 +585,13 @@ public class JPEGImageReader extends ImageReader {
if (debug) {
System.out.println("pushing back " + num + " bytes");
}
iis.seek(iis.getStreamPosition()-num);
// The buffer is clear after this, so no need to set haveSeeked.
cbLock.lock();
try {
iis.seek(iis.getStreamPosition()-num);
// The buffer is clear after this, so no need to set haveSeeked.
} finally {
cbLock.unlock();
}
}
/**
......@@ -644,7 +698,12 @@ public class JPEGImageReader extends ImageReader {
* Ignore this profile.
*/
iccCS = null;
warningOccurred(WARNING_IGNORE_INVALID_ICC);
cbLock.lock();
try {
warningOccurred(WARNING_IGNORE_INVALID_ICC);
} finally {
cbLock.unlock();
}
}
}
}
......@@ -653,6 +712,7 @@ public class JPEGImageReader extends ImageReader {
setThreadLock();
try {
if (currentImage != imageIndex) {
cbLock.check();
readHeader(imageIndex, true);
}
return width;
......@@ -665,6 +725,7 @@ public class JPEGImageReader extends ImageReader {
setThreadLock();
try {
if (currentImage != imageIndex) {
cbLock.check();
readHeader(imageIndex, true);
}
return height;
......@@ -693,6 +754,8 @@ public class JPEGImageReader extends ImageReader {
setThreadLock();
try {
if (currentImage != imageIndex) {
cbLock.check();
readHeader(imageIndex, true);
}
......@@ -716,6 +779,7 @@ public class JPEGImageReader extends ImageReader {
private Iterator getImageTypesOnThread(int imageIndex)
throws IOException {
if (currentImage != imageIndex) {
cbLock.check();
readHeader(imageIndex, true);
}
......@@ -931,6 +995,7 @@ public class JPEGImageReader extends ImageReader {
setThreadLock();
try {
if (!tablesOnlyChecked) {
cbLock.check();
checkTablesOnly();
}
return streamMetadata;
......@@ -951,6 +1016,8 @@ public class JPEGImageReader extends ImageReader {
return imageMetadata;
}
cbLock.check();
gotoImage(imageIndex);
imageMetadata = new JPEGMetadata(false, false, iis, this);
......@@ -967,6 +1034,7 @@ public class JPEGImageReader extends ImageReader {
throws IOException {
setThreadLock();
try {
cbLock.check();
try {
readInternal(imageIndex, param, false);
} catch (RuntimeException e) {
......@@ -1196,58 +1264,63 @@ public class JPEGImageReader extends ImageReader {
}
target.setRect(destROI.x, destROI.y + y, raster);
processImageUpdate(image,
destROI.x, destROI.y+y,
raster.getWidth(), 1,
1, 1,
destinationBands);
if ((y > 0) && (y%progInterval == 0)) {
int height = target.getHeight()-1;
float percentOfPass = ((float)y)/height;
if (progressive) {
if (knownPassCount != UNKNOWN) {
processImageProgress((pass + percentOfPass)*100.0F
/ knownPassCount);
} else if (maxProgressivePass != Integer.MAX_VALUE) {
// Use the range of allowed progressive passes
processImageProgress((pass + percentOfPass)*100.0F
/ (maxProgressivePass - minProgressivePass + 1));
} else {
// Assume there are a minimum of MIN_ESTIMATED_PASSES
// and that there is always one more pass
// Compute the percentage as the percentage at the end
// of the previous pass, plus the percentage of this
// pass scaled to be the percentage of the total remaining,
// assuming a minimum of MIN_ESTIMATED_PASSES passes and
// that there is always one more pass. This is monotonic
// and asymptotic to 1.0, which is what we need.
int remainingPasses = // including this one
Math.max(2, MIN_ESTIMATED_PASSES-pass);
int totalPasses = pass + remainingPasses-1;
progInterval = Math.max(height/20*totalPasses,
totalPasses);
if (y%progInterval == 0) {
percentToDate = previousPassPercentage +
(1.0F - previousPassPercentage)
* (percentOfPass)/remainingPasses;
if (debug) {
System.out.print("pass= " + pass);
System.out.print(", y= " + y);
System.out.print(", progInt= " + progInterval);
System.out.print(", % of pass: " + percentOfPass);
System.out.print(", rem. passes: "
+ remainingPasses);
System.out.print(", prev%: "
+ previousPassPercentage);
System.out.print(", %ToDate: " + percentToDate);
System.out.print(" ");
cbLock.lock();
try {
processImageUpdate(image,
destROI.x, destROI.y+y,
raster.getWidth(), 1,
1, 1,
destinationBands);
if ((y > 0) && (y%progInterval == 0)) {
int height = target.getHeight()-1;
float percentOfPass = ((float)y)/height;
if (progressive) {
if (knownPassCount != UNKNOWN) {
processImageProgress((pass + percentOfPass)*100.0F
/ knownPassCount);
} else if (maxProgressivePass != Integer.MAX_VALUE) {
// Use the range of allowed progressive passes
processImageProgress((pass + percentOfPass)*100.0F
/ (maxProgressivePass - minProgressivePass + 1));
} else {
// Assume there are a minimum of MIN_ESTIMATED_PASSES
// and that there is always one more pass
// Compute the percentage as the percentage at the end
// of the previous pass, plus the percentage of this
// pass scaled to be the percentage of the total remaining,
// assuming a minimum of MIN_ESTIMATED_PASSES passes and
// that there is always one more pass. This is monotonic
// and asymptotic to 1.0, which is what we need.
int remainingPasses = // including this one
Math.max(2, MIN_ESTIMATED_PASSES-pass);
int totalPasses = pass + remainingPasses-1;
progInterval = Math.max(height/20*totalPasses,
totalPasses);
if (y%progInterval == 0) {
percentToDate = previousPassPercentage +
(1.0F - previousPassPercentage)
* (percentOfPass)/remainingPasses;
if (debug) {
System.out.print("pass= " + pass);
System.out.print(", y= " + y);
System.out.print(", progInt= " + progInterval);
System.out.print(", % of pass: " + percentOfPass);
System.out.print(", rem. passes: "
+ remainingPasses);
System.out.print(", prev%: "
+ previousPassPercentage);
System.out.print(", %ToDate: " + percentToDate);
System.out.print(" ");
}
processImageProgress(percentToDate*100.0F);
}
processImageProgress(percentToDate*100.0F);
}
} else {
processImageProgress(percentOfPass * 100.0F);
}
} else {
processImageProgress(percentOfPass * 100.0F);
}
} finally {
cbLock.unlock();
}
}
......@@ -1260,33 +1333,58 @@ public class JPEGImageReader extends ImageReader {
}
private void passStarted (int pass) {
this.pass = pass;
previousPassPercentage = percentToDate;
processPassStarted(image,
pass,
minProgressivePass,
maxProgressivePass,
0, 0,
1,1,
destinationBands);
cbLock.lock();
try {
this.pass = pass;
previousPassPercentage = percentToDate;
processPassStarted(image,
pass,
minProgressivePass,
maxProgressivePass,
0, 0,
1,1,
destinationBands);
} finally {
cbLock.unlock();
}
}
private void passComplete () {
processPassComplete(image);
cbLock.lock();
try {
processPassComplete(image);
} finally {
cbLock.unlock();
}
}
void thumbnailStarted(int thumbnailIndex) {
processThumbnailStarted(currentImage, thumbnailIndex);
cbLock.lock();
try {
processThumbnailStarted(currentImage, thumbnailIndex);
} finally {
cbLock.unlock();
}
}
// Provide access to protected superclass method
void thumbnailProgress(float percentageDone) {
processThumbnailProgress(percentageDone);
cbLock.lock();
try {
processThumbnailProgress(percentageDone);
} finally {
cbLock.unlock();
}
}
// Provide access to protected superclass method
void thumbnailComplete() {
processThumbnailComplete();
cbLock.lock();
try {
processThumbnailComplete();
} finally {
cbLock.unlock();
}
}
/**
......@@ -1310,6 +1408,11 @@ public class JPEGImageReader extends ImageReader {
public void abort() {
setThreadLock();
try {
/**
* NB: we do not check the call back lock here,
* we allow to abort the reader any time.
*/
super.abort();
abortRead(structPointer);
} finally {
......@@ -1332,6 +1435,7 @@ public class JPEGImageReader extends ImageReader {
setThreadLock();
Raster retval = null;
try {
cbLock.check();
/*
* This could be further optimized by not resetting the dest.
* offset and creating a translated raster in readInternal()
......@@ -1371,6 +1475,8 @@ public class JPEGImageReader extends ImageReader {
public int getNumThumbnails(int imageIndex) throws IOException {
setThreadLock();
try {
cbLock.check();
getImageMetadata(imageIndex); // checks iis state for us
// Now check the jfif segments
JFIFMarkerSegment jfif =
......@@ -1391,6 +1497,8 @@ public class JPEGImageReader extends ImageReader {
throws IOException {
setThreadLock();
try {
cbLock.check();
if ((thumbnailIndex < 0)
|| (thumbnailIndex >= getNumThumbnails(imageIndex))) {
throw new IndexOutOfBoundsException("No such thumbnail");
......@@ -1409,6 +1517,8 @@ public class JPEGImageReader extends ImageReader {
throws IOException {
setThreadLock();
try {
cbLock.check();
if ((thumbnailIndex < 0)
|| (thumbnailIndex >= getNumThumbnails(imageIndex))) {
throw new IndexOutOfBoundsException("No such thumbnail");
......@@ -1428,6 +1538,8 @@ public class JPEGImageReader extends ImageReader {
throws IOException {
setThreadLock();
try {
cbLock.check();
if ((thumbnailIndex < 0)
|| (thumbnailIndex >= getNumThumbnails(imageIndex))) {
throw new IndexOutOfBoundsException("No such thumbnail");
......@@ -1468,6 +1580,7 @@ public class JPEGImageReader extends ImageReader {
public void reset() {
setThreadLock();
try {
cbLock.check();
super.reset();
} finally {
clearThreadLock();
......@@ -1479,6 +1592,8 @@ public class JPEGImageReader extends ImageReader {
public void dispose() {
setThreadLock();
try {
cbLock.check();
if (structPointer != 0) {
disposerRecord.dispose();
structPointer = 0;
......@@ -1540,6 +1655,36 @@ public class JPEGImageReader extends ImageReader {
theThread = null;
}
}
private CallBackLock cbLock = new CallBackLock();
private static class CallBackLock {
private State lockState;
CallBackLock() {
lockState = State.Unlocked;
}
void check() {
if (lockState != State.Unlocked) {
throw new IllegalStateException("Access to the reader is not allowed");
}
}
private void lock() {
lockState = State.Locked;
}
private void unlock() {
lockState = State.Unlocked;
}
private static enum State {
Unlocked,
Locked
}
}
}
/**
......
......@@ -183,8 +183,7 @@ public class JPEGImageWriter extends ImageWriter {
return null;
}
});
initWriterIDs(ImageOutputStream.class,
JPEGQTable.class,
initWriterIDs(JPEGQTable.class,
JPEGHuffmanTable.class);
}
......@@ -200,11 +199,13 @@ public class JPEGImageWriter extends ImageWriter {
public void setOutput(Object output) {
setThreadLock();
try {
cbLock.check();
super.setOutput(output); // validates output
resetInternalState();
ios = (ImageOutputStream) output; // so this will always work
// Set the native destination
setDest(structPointer, ios);
setDest(structPointer);
} finally {
clearThreadLock();
}
......@@ -359,6 +360,8 @@ public class JPEGImageWriter extends ImageWriter {
ImageWriteParam param) throws IOException {
setThreadLock();
try {
cbLock.check();
writeOnThread(streamMetadata, image, param);
} finally {
clearThreadLock();
......@@ -1082,13 +1085,18 @@ public class JPEGImageWriter extends ImageWriter {
haveMetadata,
restartInterval);
if (aborted) {
processWriteAborted();
} else {
processImageComplete();
}
cbLock.lock();
try {
if (aborted) {
processWriteAborted();
} else {
processImageComplete();
}
ios.flush();
ios.flush();
} finally {
cbLock.unlock();
}
currentImage++; // After a successful write
}
......@@ -1096,6 +1104,8 @@ public class JPEGImageWriter extends ImageWriter {
throws IOException {
setThreadLock();
try {
cbLock.check();
prepareWriteSequenceOnThread(streamMetadata);
} finally {
clearThreadLock();
......@@ -1175,6 +1185,8 @@ public class JPEGImageWriter extends ImageWriter {
throws IOException {
setThreadLock();
try {
cbLock.check();
if (sequencePrepared == false) {
throw new IllegalStateException("sequencePrepared not called!");
}
......@@ -1188,6 +1200,8 @@ public class JPEGImageWriter extends ImageWriter {
public void endWriteSequence() throws IOException {
setThreadLock();
try {
cbLock.check();
if (sequencePrepared == false) {
throw new IllegalStateException("sequencePrepared not called!");
}
......@@ -1200,6 +1214,10 @@ public class JPEGImageWriter extends ImageWriter {
public synchronized void abort() {
setThreadLock();
try {
/**
* NB: we do not check the call back lock here, we allow to abort
* the reader any time.
*/
super.abort();
abortWrite(structPointer);
} finally {
......@@ -1223,6 +1241,8 @@ public class JPEGImageWriter extends ImageWriter {
public void reset() {
setThreadLock();
try {
cbLock.check();
super.reset();
} finally {
clearThreadLock();
......@@ -1232,6 +1252,8 @@ public class JPEGImageWriter extends ImageWriter {
public void dispose() {
setThreadLock();
try {
cbLock.check();
if (structPointer != 0) {
disposerRecord.dispose();
structPointer = 0;
......@@ -1251,13 +1273,18 @@ public class JPEGImageWriter extends ImageWriter {
* sending warnings to listeners.
*/
void warningOccurred(int code) {
if ((code < 0) || (code > MAX_WARNING)){
throw new InternalError("Invalid warning index");
cbLock.lock();
try {
if ((code < 0) || (code > MAX_WARNING)){
throw new InternalError("Invalid warning index");
}
processWarningOccurred
(currentImage,
"com.sun.imageio.plugins.jpeg.JPEGImageWriterResources",
Integer.toString(code));
} finally {
cbLock.unlock();
}
processWarningOccurred
(currentImage,
"com.sun.imageio.plugins.jpeg.JPEGImageWriterResources",
Integer.toString(code));
}
/**
......@@ -1274,21 +1301,41 @@ public class JPEGImageWriter extends ImageWriter {
* library warnings from being printed to stderr.
*/
void warningWithMessage(String msg) {
processWarningOccurred(currentImage, msg);
cbLock.lock();
try {
processWarningOccurred(currentImage, msg);
} finally {
cbLock.unlock();
}
}
void thumbnailStarted(int thumbnailIndex) {
processThumbnailStarted(currentImage, thumbnailIndex);
cbLock.lock();
try {
processThumbnailStarted(currentImage, thumbnailIndex);
} finally {
cbLock.unlock();
}
}
// Provide access to protected superclass method
void thumbnailProgress(float percentageDone) {
processThumbnailProgress(percentageDone);
cbLock.lock();
try {
processThumbnailProgress(percentageDone);
} finally {
cbLock.unlock();
}
}
// Provide access to protected superclass method
void thumbnailComplete() {
processThumbnailComplete();
cbLock.lock();
try {
processThumbnailComplete();
} finally {
cbLock.unlock();
}
}
///////// End of Package-access API
......@@ -1615,16 +1662,14 @@ public class JPEGImageWriter extends ImageWriter {
////////////// Native methods and callbacks
/** Sets up static native structures. */
private static native void initWriterIDs(Class iosClass,
Class qTableClass,
private static native void initWriterIDs(Class qTableClass,
Class huffClass);
/** Sets up per-writer native structure and returns a pointer to it. */
private native long initJPEGImageWriter();
/** Sets up native structures for output stream */
private native void setDest(long structPointer,
ImageOutputStream ios);
private native void setDest(long structPointer);
/**
* Returns <code>true</code> if the write was aborted.
......@@ -1749,7 +1794,12 @@ public class JPEGImageWriter extends ImageWriter {
}
raster.setRect(sourceLine);
if ((y > 7) && (y%8 == 0)) { // Every 8 scanlines
processImageProgress((float) y / (float) sourceHeight * 100.0F);
cbLock.lock();
try {
processImageProgress((float) y / (float) sourceHeight * 100.0F);
} finally {
cbLock.unlock();
}
}
}
......@@ -1777,6 +1827,25 @@ public class JPEGImageWriter extends ImageWriter {
}
}
/**
* This method is called from native code in order to write encoder
* output to the destination.
*
* We block any attempt to change the writer state during this
* method, in order to prevent a corruption of the native encoder
* state.
*/
private void writeOutputData(byte[] data, int offset, int len)
throws IOException
{
cbLock.lock();
try {
ios.write(data, offset, len);
} finally {
cbLock.unlock();
}
}
private Thread theThread = null;
private int theLockCount = 0;
......@@ -1811,4 +1880,34 @@ public class JPEGImageWriter extends ImageWriter {
theThread = null;
}
}
private CallBackLock cbLock = new CallBackLock();
private static class CallBackLock {
private State lockState;
CallBackLock() {
lockState = State.Unlocked;
}
void check() {
if (lockState != State.Unlocked) {
throw new IllegalStateException("Access to the writer is not allowed");
}
}
private void lock() {
lockState = State.Locked;
}
private void unlock() {
lockState = State.Unlocked;
}
private static enum State {
Unlocked,
Locked
}
}
}
/*
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -32,6 +32,7 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.security.Permission;
import java.util.Map;
import java.util.logging.Level;
......@@ -213,7 +214,6 @@ public class MBeanInstantiator {
Object moi;
// ------------------------------
// ------------------------------
Constructor<?> cons = findConstructor(theClass, null);
......@@ -224,6 +224,7 @@ public class MBeanInstantiator {
// Instantiate the new object
try {
ReflectUtil.checkPackageAccess(theClass);
ensureClassAccess(theClass);
moi= cons.newInstance();
} catch (InvocationTargetException e) {
// Wrap the exception.
......@@ -270,7 +271,6 @@ public class MBeanInstantiator {
checkMBeanPermission(theClass, null, null, "instantiate");
// Instantiate the new object
// ------------------------------
// ------------------------------
final Class<?>[] tab;
......@@ -300,6 +300,7 @@ public class MBeanInstantiator {
}
try {
ReflectUtil.checkPackageAccess(theClass);
ensureClassAccess(theClass);
moi = cons.newInstance(params);
}
catch (NoSuchMethodError error) {
......@@ -741,4 +742,13 @@ public class MBeanInstantiator {
sm.checkPermission(perm);
}
}
private static void ensureClassAccess(Class clazz)
throws IllegalAccessException
{
int mod = clazz.getModifiers();
if (!Modifier.isPublic(mod)) {
throw new IllegalAccessException("Class is not public and can't be instantiated");
}
}
}
......@@ -56,7 +56,7 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
// from simultaneous creation and destruction
// reduces possibility of deadlock, compared to
// synchronizing to the class instance
private Object traRecLock = new Object();
private final Object traRecLock = new Object();
// DEVICE ATTRIBUTES
......@@ -474,7 +474,7 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
This is necessary for Receivers retrieved via MidiSystem.getReceiver()
(which opens the device implicitely).
*/
protected abstract class AbstractReceiver implements MidiDeviceReceiver {
abstract class AbstractReceiver implements MidiDeviceReceiver {
private boolean open = true;
......@@ -483,24 +483,24 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
Receiver. Therefore, subclasses should not override this method.
Instead, they should implement implSend().
*/
public synchronized void send(MidiMessage message, long timeStamp) {
if (open) {
implSend(message, timeStamp);
} else {
@Override
public final synchronized void send(final MidiMessage message,
final long timeStamp) {
if (!open) {
throw new IllegalStateException("Receiver is not open");
}
implSend(message, timeStamp);
}
protected abstract void implSend(MidiMessage message, long timeStamp);
abstract void implSend(MidiMessage message, long timeStamp);
/** Close the Receiver.
* Here, the call to the magic method closeInternal() takes place.
* Therefore, subclasses that override this method must call
* 'super.close()'.
*/
public void close() {
@Override
public final void close() {
open = false;
synchronized (AbstractMidiDevice.this.traRecLock) {
AbstractMidiDevice.this.getReceiverList().remove(this);
......@@ -508,11 +508,12 @@ abstract class AbstractMidiDevice implements MidiDevice, ReferenceCountingDevice
AbstractMidiDevice.this.closeInternal(this);
}
public MidiDevice getMidiDevice() {
@Override
public final MidiDevice getMidiDevice() {
return AbstractMidiDevice.this;
}
protected boolean isOpen() {
final boolean isOpen() {
return open;
}
......
......@@ -32,7 +32,7 @@ import javax.sound.midi.*;
*
* @author Florian Bomers
*/
class FastShortMessage extends ShortMessage {
final class FastShortMessage extends ShortMessage {
private int packedMsg;
public FastShortMessage(int packedMsg) throws InvalidMidiDataException {
......
......@@ -32,7 +32,7 @@ import javax.sound.midi.*;
*
* @author Florian Bomers
*/
class FastSysexMessage extends SysexMessage {
final class FastSysexMessage extends SysexMessage {
FastSysexMessage(byte[] data) throws InvalidMidiDataException {
super(data);
......
......@@ -103,9 +103,9 @@ class MidiOutDevice extends AbstractMidiDevice {
class MidiOutReceiver extends AbstractReceiver {
protected void implSend(MidiMessage message, long timeStamp) {
int length = message.getLength();
int status = message.getStatus();
void implSend(final MidiMessage message, final long timeStamp) {
final int length = message.getLength();
final int status = message.getStatus();
if (length <= 3 && status != 0xF0 && status != 0xF7) {
int packedMsg;
if (message instanceof ShortMessage) {
......@@ -140,11 +140,15 @@ class MidiOutDevice extends AbstractMidiDevice {
}
nSendShortMessage(id, packedMsg, timeStamp);
} else {
final byte[] data;
if (message instanceof FastSysexMessage) {
nSendLongMessage(id, ((FastSysexMessage) message).getReadOnlyMessage(),
length, timeStamp);
data = ((FastSysexMessage) message).getReadOnlyMessage();
} else {
nSendLongMessage(id, message.getMessage(), length, timeStamp);
data = message.getMessage();
}
final int dataLength = Math.min(length, data.length);
if (dataLength > 0) {
nSendLongMessage(id, data, dataLength, timeStamp);
}
}
}
......
......@@ -1026,7 +1026,7 @@ class RealTimeSequencer extends AbstractMidiDevice implements Sequencer, AutoCon
class SequencerReceiver extends AbstractReceiver {
protected void implSend(MidiMessage message, long timeStamp) {
void implSend(MidiMessage message, long timeStamp) {
if (recording) {
long tickPos = 0;
......
/*
* Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -2234,7 +2234,7 @@ public class Window extends Container implements Accessible {
WindowPeer peer = (WindowPeer)this.peer;
synchronized(getTreeLock()) {
if (peer != null) {
peer.setAlwaysOnTop(alwaysOnTop);
peer.updateAlwaysOnTopState();
}
}
}
......
/*
* Copyright (c) 1995, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -53,15 +53,14 @@ public interface WindowPeer extends ContainerPeer {
void toBack();
/**
* Sets if the window should always stay on top of all other windows or
* not.
*
* @param alwaysOnTop if the window should always stay on top of all other
* windows or not
* Updates the window's always-on-top state.
* Sets if the window should always stay
* on top of all other windows or not.
*
* @see Window#getAlwaysOnTop()
* @see Window#setAlwaysOnTop(boolean)
*/
void setAlwaysOnTop(boolean alwaysOnTop);
void updateAlwaysOnTopState();
/**
* Updates the window's focusable state.
......
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -29,7 +29,6 @@ import com.sun.beans.finder.BeanInfoFinder;
import com.sun.beans.finder.PropertyEditorFinder;
import java.awt.GraphicsEnvironment;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
......@@ -42,7 +41,7 @@ import java.util.WeakHashMap;
*/
final class ThreadGroupContext {
private static final Map<ThreadGroup, ThreadGroupContext> contexts = new WeakHashMap<>();
private static final WeakIdentityMap<ThreadGroupContext> contexts = new WeakIdentityMap<>();
/**
* Returns the appropriate {@code AppContext} for the caller,
......@@ -69,6 +68,8 @@ final class ThreadGroupContext {
private BeanInfoFinder beanInfoFinder;
private PropertyEditorFinder propertyEditorFinder;
private ThreadGroupContext() {
}
boolean isDesignTime() {
return this.isDesignTime;
......
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.beans;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
/**
* Hash table based mapping, which uses weak references to store keys
* and reference-equality in place of object-equality to compare them.
* An entry will automatically be removed when its key is no longer
* in ordinary use. Both null values and the null key are supported.
*
* @see java.util.IdentityHashMap
* @see java.util.WeakHashMap
*/
final class WeakIdentityMap<T> {
private static final int MAXIMUM_CAPACITY = 1 << 30; // it MUST be a power of two
private static final Object NULL = new Object(); // special object for null key
private final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
private Entry<T>[] table = newTable(1<<3); // table's length MUST be a power of two
private int threshold = 6; // the next size value at which to resize
private int size = 0; // the number of key-value mappings
public T get(Object key) {
removeStaleEntries();
if (key == null) {
key = NULL;
}
int hash = key.hashCode();
int index = getIndex(this.table, hash);
for (Entry<T> entry = this.table[index]; entry != null; entry = entry.next) {
if (entry.isMatched(key, hash)) {
return entry.value;
}
}
return null;
}
public T put(Object key, T value) {
removeStaleEntries();
if (key == null) {
key = NULL;
}
int hash = key.hashCode();
int index = getIndex(this.table, hash);
for (Entry<T> entry = this.table[index]; entry != null; entry = entry.next) {
if (entry.isMatched(key, hash)) {
T oldValue = entry.value;
entry.value = value;
return oldValue;
}
}
this.table[index] = new Entry<T>(key, hash, value, this.queue, this.table[index]);
if (++this.size >= this.threshold) {
if (this.table.length == MAXIMUM_CAPACITY) {
this.threshold = Integer.MAX_VALUE;
}
else {
removeStaleEntries();
Entry<T>[] table = newTable(this.table.length * 2);
transfer(this.table, table);
// If ignoring null elements and processing ref queue caused massive
// shrinkage, then restore old table. This should be rare, but avoids
// unbounded expansion of garbage-filled tables.
if (this.size >= this.threshold / 2) {
this.table = table;
this.threshold *= 2;
}
else {
transfer(table, this.table);
}
}
}
return null;
}
private void removeStaleEntries() {
for (Object ref = this.queue.poll(); ref != null; ref = this.queue.poll()) {
@SuppressWarnings("unchecked")
Entry<T> entry = (Entry<T>) ref;
int index = getIndex(this.table, entry.hash);
Entry<T> prev = this.table[index];
Entry<T> current = prev;
while (current != null) {
Entry<T> next = current.next;
if (current == entry) {
if (prev == entry) {
this.table[index] = next;
}
else {
prev.next = next;
}
entry.value = null; // Help GC
entry.next = null; // Help GC
this.size--;
break;
}
prev = current;
current = next;
}
}
}
private void transfer(Entry<T>[] oldTable, Entry<T>[] newTable) {
for (int i = 0; i < oldTable.length; i++) {
Entry<T> entry = oldTable[i];
oldTable[i] = null;
while (entry != null) {
Entry<T> next = entry.next;
Object key = entry.get();
if (key == null) {
entry.value = null; // Help GC
entry.next = null; // Help GC
this.size--;
}
else {
int index = getIndex(newTable, entry.hash);
entry.next = newTable[index];
newTable[index] = entry;
}
entry = next;
}
}
}
@SuppressWarnings("unchecked")
private Entry<T>[] newTable(int length) {
return (Entry<T>[]) new Entry<?>[length];
}
private static int getIndex(Entry<?>[] table, int hash) {
return hash & (table.length - 1);
}
private static class Entry<T> extends WeakReference<Object> {
private final int hash;
private T value;
private Entry<T> next;
Entry(Object key, int hash, T value, ReferenceQueue<Object> queue, Entry<T> next) {
super(key, queue);
this.hash = hash;
this.value = value;
this.next = next;
}
boolean isMatched(Object key, int hash) {
return (this.hash == hash) && (key == get());
}
}
}
......@@ -41,6 +41,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
import static java.io.ObjectStreamClass.processQueue;
import sun.reflect.misc.ReflectUtil;
/**
* An ObjectInputStream deserializes primitive data and objects previously
......@@ -1519,6 +1520,12 @@ public class ObjectInputStream
}
}
private boolean isCustomSubclass() {
// Return true if this class is a custom subclass of ObjectInputStream
return getClass().getClassLoader()
!= ObjectInputStream.class.getClassLoader();
}
/**
* Reads in and returns class descriptor for a dynamic proxy class. Sets
* passHandle to proxy class descriptor's assigned handle. If proxy class
......@@ -1548,6 +1555,15 @@ public class ObjectInputStream
try {
if ((cl = resolveProxyClass(ifaces)) == null) {
resolveEx = new ClassNotFoundException("null class");
} else if (!Proxy.isProxyClass(cl)) {
throw new InvalidClassException("Not a proxy");
} else {
// ReflectUtil.checkProxyPackageAccess makes a test
// equivalent to isCustomSubclass so there's no need
// to condition this call to isCustomSubclass == true here.
ReflectUtil.checkProxyPackageAccess(
getClass().getClassLoader(),
cl.getInterfaces());
}
} catch (ClassNotFoundException ex) {
resolveEx = ex;
......@@ -1589,9 +1605,12 @@ public class ObjectInputStream
Class<?> cl = null;
ClassNotFoundException resolveEx = null;
bin.setBlockDataMode(true);
final boolean checksRequired = isCustomSubclass();
try {
if ((cl = resolveClass(readDesc)) == null) {
resolveEx = new ClassNotFoundException("null class");
} else if (checksRequired) {
ReflectUtil.checkPackageAccess(cl);
}
} catch (ClassNotFoundException ex) {
resolveEx = ex;
......
......@@ -30,6 +30,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.security.AccessControlException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
......@@ -1024,13 +1025,24 @@ public final class ProcessBuilder
redirects,
redirectErrorStream);
} catch (IOException e) {
String exceptionInfo = ": " + e.getMessage();
Throwable cause = e;
if (security != null) {
// Can not disclose the fail reason for read-protected files.
try {
security.checkRead(prog);
} catch (AccessControlException ace) {
exceptionInfo = "";
cause = ace;
}
}
// It's much easier for us to create a high-quality error
// message than the low-level C code which found the problem.
throw new IOException(
"Cannot run program \"" + prog + "\""
+ (dir == null ? "" : " (in directory \"" + dir + "\")")
+ ": " + e.getMessage(),
e);
+ exceptionInfo,
cause);
}
}
}
......@@ -1237,6 +1237,30 @@ return mh1;
checkMethod(refKind, refc, method);
if (method.isMethodHandleInvoke())
return fakeMethodHandleInvoke(method);
Class<?> refcAsSuper;
if (refKind == REF_invokeSpecial &&
refc != lookupClass() &&
refc != (refcAsSuper = lookupClass().getSuperclass()) &&
refc.isAssignableFrom(lookupClass())) {
assert(!method.getName().equals("<init>")); // not this code path
// Per JVMS 6.5, desc. of invokespecial instruction:
// If the method is in a superclass of the LC,
// and if our original search was above LC.super,
// repeat the search (symbolic lookup) from LC.super.
// FIXME: MemberName.resolve should handle this instead.
MemberName m2 = new MemberName(refcAsSuper,
method.getName(),
method.getMethodType(),
REF_invokeSpecial);
m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
if (m2 == null) throw new InternalError(method.toString());
method = m2;
refc = refcAsSuper;
// redo basic checks
checkMethod(refKind, refc, method);
}
MethodHandle mh = DirectMethodHandle.make(refKind, refc, method);
mh = maybeBindCaller(method, mh, callerClass);
mh = mh.setVarargs(method);
......
......@@ -38,9 +38,9 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
*/
static native void invokeFinalizeMethod(Object o) throws Throwable;
static private ReferenceQueue queue = new ReferenceQueue();
static private Finalizer unfinalized = null;
static private Object lock = new Object();
private static ReferenceQueue queue = new ReferenceQueue();
private static Finalizer unfinalized = null;
private static final Object lock = new Object();
private Finalizer
next = null,
......@@ -142,7 +142,11 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
/* Called by Runtime.runFinalization() */
static void runFinalization() {
forkSecondaryFinalizer(new Runnable() {
private volatile boolean running;
public void run() {
if (running)
return;
running = true;
for (;;) {
Finalizer f = (Finalizer)queue.poll();
if (f == null) break;
......@@ -155,7 +159,11 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
/* Invoked by java.lang.Shutdown */
static void runAllFinalizers() {
forkSecondaryFinalizer(new Runnable() {
private volatile boolean running;
public void run() {
if (running)
return;
running = true;
for (;;) {
Finalizer f;
synchronized (lock) {
......@@ -168,10 +176,14 @@ final class Finalizer extends FinalReference { /* Package-private; must be in
}
private static class FinalizerThread extends Thread {
private volatile boolean running;
FinalizerThread(ThreadGroup g) {
super(g, "Finalizer");
}
public void run() {
if (running)
return;
running = true;
for (;;) {
try {
Finalizer f = (Finalizer)queue.remove();
......
......@@ -122,7 +122,7 @@ abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
* not connected already.
*/
protected void disconnect() {
disconnect0(connectedAddress.family);
disconnect0(connectedAddress.holder().getFamily());
connected = false;
connectedAddress = null;
connectedPort = -1;
......
......@@ -100,27 +100,28 @@ class Inet4Address extends InetAddress {
Inet4Address() {
super();
hostName = null;
address = 0;
family = IPv4;
holder().hostName = null;
holder().address = 0;
holder().family = IPv4;
}
Inet4Address(String hostName, byte addr[]) {
this.hostName = hostName;
this.family = IPv4;
holder().hostName = hostName;
holder().family = IPv4;
if (addr != null) {
if (addr.length == INADDRSZ) {
address = addr[3] & 0xFF;
int address = addr[3] & 0xFF;
address |= ((addr[2] << 8) & 0xFF00);
address |= ((addr[1] << 16) & 0xFF0000);
address |= ((addr[0] << 24) & 0xFF000000);
holder().address = address;
}
}
}
Inet4Address(String hostName, int address) {
this.hostName = hostName;
this.family = IPv4;
this.address = address;
holder().hostName = hostName;
holder().family = IPv4;
holder().address = address;
}
/**
......@@ -134,8 +135,8 @@ class Inet4Address extends InetAddress {
private Object writeReplace() throws ObjectStreamException {
// will replace the to be serialized 'this' object
InetAddress inet = new InetAddress();
inet.hostName = this.hostName;
inet.address = this.address;
inet.holder().hostName = holder().getHostName();
inet.holder().address = holder().getAddress();
/**
* Prior to 1.4 an InetAddress was created with a family
......@@ -143,7 +144,7 @@ class Inet4Address extends InetAddress {
* For compatibility reasons we must therefore write the
* the InetAddress with this family.
*/
inet.family = 2;
inet.holder().family = 2;
return inet;
}
......@@ -157,7 +158,7 @@ class Inet4Address extends InetAddress {
* @since JDK1.1
*/
public boolean isMulticastAddress() {
return ((address & 0xf0000000) == 0xe0000000);
return ((holder().getAddress() & 0xf0000000) == 0xe0000000);
}
/**
......@@ -167,7 +168,7 @@ class Inet4Address extends InetAddress {
* @since 1.4
*/
public boolean isAnyLocalAddress() {
return address == 0;
return holder().getAddress() == 0;
}
/**
......@@ -195,6 +196,7 @@ class Inet4Address extends InetAddress {
// defined in "Documenting Special Use IPv4 Address Blocks
// that have been Registered with IANA" by Bill Manning
// draft-manning-dsua-06.txt
int address = holder().getAddress();
return (((address >>> 24) & 0xFF) == 169)
&& (((address >>> 16) & 0xFF) == 254);
}
......@@ -211,6 +213,7 @@ class Inet4Address extends InetAddress {
// 10/8 prefix
// 172.16/12 prefix
// 192.168/16 prefix
int address = holder().getAddress();
return (((address >>> 24) & 0xFF) == 10)
|| ((((address >>> 24) & 0xFF) == 172)
&& (((address >>> 16) & 0xF0) == 16))
......@@ -257,6 +260,7 @@ class Inet4Address extends InetAddress {
*/
public boolean isMCLinkLocal() {
// 224.0.0/24 prefix and ttl == 1
int address = holder().getAddress();
return (((address >>> 24) & 0xFF) == 224)
&& (((address >>> 16) & 0xFF) == 0)
&& (((address >>> 8) & 0xFF) == 0);
......@@ -272,6 +276,7 @@ class Inet4Address extends InetAddress {
*/
public boolean isMCSiteLocal() {
// 239.255/16 prefix or ttl < 32
int address = holder().getAddress();
return (((address >>> 24) & 0xFF) == 239)
&& (((address >>> 16) & 0xFF) == 255);
}
......@@ -287,6 +292,7 @@ class Inet4Address extends InetAddress {
*/
public boolean isMCOrgLocal() {
// 239.192 - 239.195
int address = holder().getAddress();
return (((address >>> 24) & 0xFF) == 239)
&& (((address >>> 16) & 0xFF) >= 192)
&& (((address >>> 16) & 0xFF) <= 195);
......@@ -300,6 +306,7 @@ class Inet4Address extends InetAddress {
* @return the raw IP address of this object.
*/
public byte[] getAddress() {
int address = holder().getAddress();
byte[] addr = new byte[INADDRSZ];
addr[0] = (byte) ((address >>> 24) & 0xFF);
......@@ -325,7 +332,7 @@ class Inet4Address extends InetAddress {
* @return a hash code value for this IP address.
*/
public int hashCode() {
return address;
return holder().getAddress();
}
/**
......@@ -346,7 +353,7 @@ class Inet4Address extends InetAddress {
*/
public boolean equals(Object obj) {
return (obj != null) && (obj instanceof Inet4Address) &&
(((InetAddress)obj).address == address);
(((InetAddress)obj).holder().getAddress() == holder().getAddress());
}
// Utilities
......
......@@ -40,7 +40,7 @@ class Inet4AddressImpl implements InetAddressImpl {
public synchronized InetAddress anyLocalAddress() {
if (anyLocalAddress == null) {
anyLocalAddress = new Inet4Address(); // {0x00,0x00,0x00,0x00}
anyLocalAddress.hostName = "0.0.0.0";
anyLocalAddress.holder().hostName = "0.0.0.0";
}
return anyLocalAddress;
}
......
......@@ -210,18 +210,18 @@ class Inet6Address extends InetAddress {
Inet6Address() {
super();
hostName = null;
holder().hostName = null;
ipaddress = new byte[INADDRSZ];
family = IPv6;
holder().family = IPv6;
}
/* checking of value for scope_id should be done by caller
* scope_id must be >= 0, or -1 to indicate not being set
*/
Inet6Address(String hostName, byte addr[], int scope_id) {
this.hostName = hostName;
holder().hostName = hostName;
if (addr.length == INADDRSZ) { // normal IPv6 address
family = IPv6;
holder().family = IPv6;
ipaddress = addr.clone();
}
if (scope_id >= 0) {
......@@ -335,9 +335,9 @@ class Inet6Address extends InetAddress {
private void initif(String hostName, byte addr[],NetworkInterface nif)
throws UnknownHostException
{
this.hostName = hostName;
holder().hostName = hostName;
if (addr.length == INADDRSZ) { // normal IPv6 address
family = IPv6;
holder().family = IPv6;
ipaddress = addr.clone();
}
if (nif != null) {
......@@ -420,6 +420,11 @@ class Inet6Address extends InetAddress {
*/
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
if (getClass().getClassLoader() != null) {
throw new SecurityException ("invalid address type");
}
s.defaultReadObject();
if (ifname != null && !ifname.equals("")) {
......@@ -447,7 +452,7 @@ class Inet6Address extends InetAddress {
ipaddress.length);
}
if (family != IPv6) {
if (holder().getFamily() != IPv6) {
throw new InvalidObjectException("invalid address family type");
}
}
......
......@@ -81,7 +81,7 @@ class Inet6AddressImpl implements InetAddressImpl {
if (anyLocalAddress == null) {
if (InetAddress.preferIPv6Address) {
anyLocalAddress = new Inet6Address();
anyLocalAddress.hostName = "::";
anyLocalAddress.holder().hostName = "::";
} else {
anyLocalAddress = (new Inet4AddressImpl()).anyLocalAddress();
}
......
......@@ -35,8 +35,12 @@ import java.util.ArrayList;
import java.util.ServiceLoader;
import java.security.AccessController;
import java.io.ObjectStreamException;
import java.io.ObjectStreamField;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectInputStream.GetField;
import java.io.ObjectOutputStream;
import java.io.ObjectOutputStream.PutField;
import sun.security.action.*;
import sun.net.InetAddressCachePolicy;
import sun.net.util.IPAddressUtil;
......@@ -199,25 +203,48 @@ class InetAddress implements java.io.Serializable {
/* Specify address family preference */
static transient boolean preferIPv6Address = false;
/**
* @serial
*/
String hostName;
static class InetAddressHolder {
/**
* Holds a 32-bit IPv4 address.
*
* @serial
*/
int address;
InetAddressHolder() {}
/**
* Specifies the address family type, for instance, '1' for IPv4
* addresses, and '2' for IPv6 addresses.
*
* @serial
*/
int family;
InetAddressHolder(String hostName, int address, int family) {
this.hostName = hostName;
this.address = address;
this.family = family;
}
String hostName;
String getHostName() {
return hostName;
}
/**
* Holds a 32-bit IPv4 address.
*/
int address;
int getAddress() {
return address;
}
/**
* Specifies the address family type, for instance, '1' for IPv4
* addresses, and '2' for IPv6 addresses.
*/
int family;
int getFamily() {
return family;
}
}
/* Used to store the serializable fields of InetAddress */
private final transient InetAddressHolder holder;
InetAddressHolder holder() {
return holder;
}
/* Used to store the name service provider */
private static List<NameService> nameServices = null;
......@@ -251,6 +278,7 @@ class InetAddress implements java.io.Serializable {
* put in the address cache, since it is not created by name.
*/
InetAddress() {
holder = new InetAddressHolder();
}
/**
......@@ -263,7 +291,7 @@ class InetAddress implements java.io.Serializable {
*/
private Object readResolve() throws ObjectStreamException {
// will replace the deserialized 'this' object
return new Inet4Address(this.hostName, this.address);
return new Inet4Address(holder().getHostName(), holder().getAddress());
}
/**
......@@ -500,10 +528,10 @@ class InetAddress implements java.io.Serializable {
* @see SecurityManager#checkConnect
*/
String getHostName(boolean check) {
if (hostName == null) {
hostName = InetAddress.getHostFromNameService(this, check);
if (holder().getHostName() == null) {
holder().hostName = InetAddress.getHostFromNameService(this, check);
}
return hostName;
return holder().getHostName();
}
/**
......@@ -666,6 +694,7 @@ class InetAddress implements java.io.Serializable {
* @return a string representation of this IP address.
*/
public String toString() {
String hostName = holder().getHostName();
return ((hostName != null) ? hostName : "")
+ "/" + getHostAddress();
}
......@@ -1522,14 +1551,58 @@ class InetAddress implements java.io.Serializable {
}
}
private static final long FIELDS_OFFSET;
private static final sun.misc.Unsafe UNSAFE;
static {
try {
sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
FIELDS_OFFSET = unsafe.objectFieldOffset(
InetAddress.class.getDeclaredField("holder")
);
UNSAFE = unsafe;
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
private void readObject (ObjectInputStream s) throws
IOException, ClassNotFoundException {
s.defaultReadObject ();
if (getClass().getClassLoader() != null) {
hostName = null;
address = 0;
throw new SecurityException ("invalid address type");
}
GetField gf = s.readFields();
String host = (String)gf.get("hostName", null);
int address= gf.get("address", 0);
int family= gf.get("family", 0);
InetAddressHolder h = new InetAddressHolder(host, address, family);
UNSAFE.putObject(this, FIELDS_OFFSET, h);
}
/* needed because the serializable fields no longer exist */
/**
* @serialField hostName String
* @serialField address int
* @serialField family int
*/
private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("hostName", String.class),
new ObjectStreamField("address", int.class),
new ObjectStreamField("family", int.class),
};
private void writeObject (ObjectOutputStream s) throws
IOException {
if (getClass().getClassLoader() != null) {
throw new SecurityException ("invalid address type");
}
PutField pf = s.putFields();
pf.put("hostName", holder().getHostName());
pf.put("address", holder().getAddress());
pf.put("family", holder().getFamily());
s.writeFields();
s.flush();
}
}
......
......@@ -87,8 +87,8 @@ public class InetSocketAddress
if (hostname != null)
return hostname;
if (addr != null) {
if (addr.hostName != null)
return addr.hostName;
if (addr.holder().getHostName() != null)
return addr.holder().getHostName();
else
return addr.getHostAddress();
}
......
/*
* Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -120,6 +120,13 @@ public class LogStream extends PrintStream {
*/
@Deprecated
public static synchronized void setDefaultStream(PrintStream newDefault) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(
new java.util.logging.LoggingPermission("control", null));
}
defaultStream = newDefault;
}
......
......@@ -556,7 +556,7 @@ public class DriverManager {
*/
try{
while(driversIterator.hasNext()) {
println(" Loading done by the java.util.ServiceLoader : "+driversIterator.next());
driversIterator.next();
}
} catch(Throwable t) {
// Do nothing
......
......@@ -34,6 +34,7 @@
*/
package java.util.concurrent;
import java.io.ObjectInputStream;
import java.util.concurrent.locks.*;
import java.util.*;
import java.io.Serializable;
......@@ -1483,7 +1484,23 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
@SuppressWarnings("unchecked")
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
// Don't call defaultReadObject()
ObjectInputStream.GetField oisFields = s.readFields();
final Segment<K,V>[] oisSegments = (Segment<K,V>[])oisFields.get("segments", null);
final int ssize = oisSegments.length;
if (ssize < 1 || ssize > MAX_SEGMENTS
|| (ssize & (ssize-1)) != 0 ) // ssize not power of two
throw new java.io.InvalidObjectException("Bad number of segments:"
+ ssize);
int sshift = 0, ssizeTmp = ssize;
while (ssizeTmp > 1) {
++sshift;
ssizeTmp >>>= 1;
}
UNSAFE.putIntVolatile(this, SEGSHIFT_OFFSET, 32 - sshift);
UNSAFE.putIntVolatile(this, SEGMASK_OFFSET, ssize - 1);
UNSAFE.putObjectVolatile(this, SEGMENTS_OFFSET, oisSegments);
// set hashMask
UNSAFE.putIntVolatile(this, HASHSEED_OFFSET,
......@@ -1517,6 +1534,9 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
private static final long TBASE;
private static final int TSHIFT;
private static final long HASHSEED_OFFSET;
private static final long SEGSHIFT_OFFSET;
private static final long SEGMASK_OFFSET;
private static final long SEGMENTS_OFFSET;
static {
int ss, ts;
......@@ -1530,6 +1550,12 @@ public class ConcurrentHashMap<K, V> extends AbstractMap<K, V>
ss = UNSAFE.arrayIndexScale(sc);
HASHSEED_OFFSET = UNSAFE.objectFieldOffset(
ConcurrentHashMap.class.getDeclaredField("hashSeed"));
SEGSHIFT_OFFSET = UNSAFE.objectFieldOffset(
ConcurrentHashMap.class.getDeclaredField("segmentShift"));
SEGMASK_OFFSET = UNSAFE.objectFieldOffset(
ConcurrentHashMap.class.getDeclaredField("segmentMask"));
SEGMENTS_OFFSET = UNSAFE.objectFieldOffset(
ConcurrentHashMap.class.getDeclaredField("segments"));
} catch (Exception e) {
throw new Error(e);
}
......
......@@ -539,7 +539,7 @@ public abstract class EmbeddedFrame extends Frame
public void toBack() {}
public void updateFocusableWindowState() {}
public void updateAlwaysOnTop() {}
public void setAlwaysOnTop(boolean alwaysOnTop) {}
public void updateAlwaysOnTopState() {}
public Component getGlobalHeavyweightFocusOwner() { return null; }
public void setBoundsPrivate(int x, int y, int width, int height) {
setBounds(x, y, width, height, SET_BOUNDS);
......
......@@ -102,11 +102,11 @@ public class TransferableProxy implements Transferable {
protected final boolean isLocal;
}
class ClassLoaderObjectOutputStream extends ObjectOutputStream {
final class ClassLoaderObjectOutputStream extends ObjectOutputStream {
private final Map<Set<String>, ClassLoader> map =
new HashMap<Set<String>, ClassLoader>();
public ClassLoaderObjectOutputStream(OutputStream os) throws IOException {
ClassLoaderObjectOutputStream(OutputStream os) throws IOException {
super(os);
}
......@@ -140,16 +140,16 @@ class ClassLoaderObjectOutputStream extends ObjectOutputStream {
map.put(s, classLoader);
}
public Map<Set<String>, ClassLoader> getClassLoaderMap() {
Map<Set<String>, ClassLoader> getClassLoaderMap() {
return new HashMap(map);
}
}
class ClassLoaderObjectInputStream extends ObjectInputStream {
final class ClassLoaderObjectInputStream extends ObjectInputStream {
private final Map<Set<String>, ClassLoader> map;
public ClassLoaderObjectInputStream(InputStream is,
Map<Set<String>, ClassLoader> map)
ClassLoaderObjectInputStream(InputStream is,
Map<Set<String>, ClassLoader> map)
throws IOException {
super(is);
if (map == null) {
......@@ -166,8 +166,11 @@ class ClassLoaderObjectInputStream extends ObjectInputStream {
s.add(className);
ClassLoader classLoader = map.get(s);
return Class.forName(className, false, classLoader);
if (classLoader != null) {
return Class.forName(className, false, classLoader);
} else {
return super.resolveClass(classDesc);
}
}
protected Class<?> resolveProxyClass(String[] interfaces)
......@@ -179,6 +182,9 @@ class ClassLoaderObjectInputStream extends ObjectInputStream {
}
ClassLoader classLoader = map.get(s);
if (classLoader == null) {
return super.resolveProxyClass(interfaces);
}
// The code below is mostly copied from the superclass.
ClassLoader nonPublicLoader = null;
......
......@@ -868,6 +868,15 @@ public class ByteComponentRaster extends SunWritableRaster {
* or if data buffer has not enough capacity.
*/
protected final void verify() {
/* Need to re-verify the dimensions since a sample model may be
* specified to the constructor
*/
if (width <= 0 || height <= 0 ||
height > (Integer.MAX_VALUE / width))
{
throw new RasterFormatException("Invalid raster dimension");
}
for (int i = 0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) {
throw new RasterFormatException("Data offsets for band " + i
......@@ -905,13 +914,14 @@ public class ByteComponentRaster extends SunWritableRaster {
lastPixelOffset += lastScanOffset;
for (int i = 0; i < numDataElements; i++) {
size = lastPixelOffset + dataOffsets[i];
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
throw new RasterFormatException("Incorrect band offset: "
+ dataOffsets[i]);
}
size = lastPixelOffset + dataOffsets[i];
if (size > maxSize) {
maxSize = size;
}
......
......@@ -1368,11 +1368,35 @@ public class BytePackedRaster extends SunWritableRaster {
throw new RasterFormatException("Data offsets must be >= 0");
}
/* Need to re-verify the dimensions since a sample model may be
* specified to the constructor
*/
if (width <= 0 || height <= 0 ||
height > (Integer.MAX_VALUE / width))
{
throw new RasterFormatException("Invalid raster dimension");
}
/*
* pixelBitstride was verified in constructor, so just make
* sure that it is safe to multiply it by width.
*/
if ((width - 1) > Integer.MAX_VALUE / pixelBitStride) {
throw new RasterFormatException("Invalid raster dimension");
}
if (scanlineStride < 0 ||
scanlineStride > (Integer.MAX_VALUE / height))
{
throw new RasterFormatException("Invalid scanline stride");
}
int lastbit = (dataBitOffset
+ (height-1) * scanlineStride * 8
+ (width-1) * pixelBitStride
+ pixelBitStride - 1);
if (lastbit / 8 >= data.length) {
if (lastbit < 0 || lastbit / 8 >= data.length) {
throw new RasterFormatException("raster dimensions overflow " +
"array bounds");
}
......
......@@ -333,10 +333,10 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
hints = h;
}
private native void setICMpixels(int x, int y, int w, int h, int[] lut,
private native boolean setICMpixels(int x, int y, int w, int h, int[] lut,
byte[] pix, int off, int scansize,
IntegerComponentRaster ict);
private native int setDiffICM(int x, int y, int w, int h, int[] lut,
private native boolean setDiffICM(int x, int y, int w, int h, int[] lut,
int transPix, int numLut, IndexColorModel icm,
byte[] pix, int off, int scansize,
ByteComponentRaster bct, int chanOff);
......@@ -426,10 +426,10 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
IndexColorModel icm = (IndexColorModel) model;
ByteComponentRaster bct = (ByteComponentRaster) biRaster;
int numlut = numSrcLUT;
if (setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex,
if (!setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex,
numSrcLUT, icm,
pix, off, scansize, bct,
bct.getDataOffset(0)) == 0) {
bct.getDataOffset(0))) {
convertToRGB();
}
else {
......@@ -470,9 +470,14 @@ public class ImageRepresentation extends ImageWatched implements ImageConsumer
if (s_useNative) {
// Note that setICMpixels modifies the raster directly
// so we must mark it as changed afterwards
setICMpixels(x, y, w, h, srcLUT, pix, off, scansize,
iraster);
iraster.markDirty();
if (setICMpixels(x, y, w, h, srcLUT, pix, off, scansize,
iraster))
{
iraster.markDirty();
} else {
abort();
return;
}
}
else {
int[] storage = new int[w*h];
......
......@@ -208,7 +208,7 @@ public class IntegerComponentRaster extends SunWritableRaster {
" SinglePixelPackedSampleModel");
}
verify(false);
verify();
}
......@@ -629,16 +629,26 @@ public class IntegerComponentRaster extends SunWritableRaster {
}
/**
* Verify that the layout parameters are consistent with
* the data. If strictCheck
* is false, this method will check for ArrayIndexOutOfBounds conditions. If
* strictCheck is true, this method will check for additional error
* conditions such as line wraparound (width of a line greater than
* the scanline stride).
* @return String Error string, if the layout is incompatible with
* the data. Otherwise returns null.
* Verify that the layout parameters are consistent with the data.
*
* The method verifies whether scanline stride and pixel stride do not
* cause an integer overflow during calculation of a position of the pixel
* in data buffer. It also verifies whether the data buffer has enough data
* to correspond the raster layout attributes.
*
* @throws RasterFormatException if an integer overflow is detected,
* or if data buffer has not enough capacity.
*/
private void verify (boolean strictCheck) {
protected final void verify() {
/* Need to re-verify the dimensions since a sample model may be
* specified to the constructor
*/
if (width <= 0 || height <= 0 ||
height > (Integer.MAX_VALUE / width))
{
throw new RasterFormatException("Invalid raster dimension");
}
if (dataOffsets[0] < 0) {
throw new RasterFormatException("Data offset ("+dataOffsets[0]+
") must be >= 0");
......@@ -647,17 +657,46 @@ public class IntegerComponentRaster extends SunWritableRaster {
int maxSize = 0;
int size;
for (int i=0; i < numDataElements; i++) {
size = (height-1)*scanlineStride + (width-1)*pixelStride +
dataOffsets[i];
// we can be sure that width and height are greater than 0
if (scanlineStride < 0 ||
scanlineStride > (Integer.MAX_VALUE / height))
{
// integer overflow
throw new RasterFormatException("Incorrect scanline stride: "
+ scanlineStride);
}
int lastScanOffset = (height - 1) * scanlineStride;
if (pixelStride < 0 ||
pixelStride > (Integer.MAX_VALUE / width))
{
// integer overflow
throw new RasterFormatException("Incorrect pixel stride: "
+ pixelStride);
}
int lastPixelOffset = (width - 1) * pixelStride;
if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
// integer overflow
throw new RasterFormatException("Incorrect raster attributes");
}
lastPixelOffset += lastScanOffset;
for (int i = 0; i < numDataElements; i++) {
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
throw new RasterFormatException("Incorrect band offset: "
+ dataOffsets[i]);
}
size = lastPixelOffset + dataOffsets[i];
if (size > maxSize) {
maxSize = size;
}
}
if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+
maxSize
+" but is "+data.length+" )");
throw new RasterFormatException("Data array too small (should be "
+ maxSize + " )");
}
}
......
......@@ -151,7 +151,7 @@ public class IntegerInterleavedRaster extends IntegerComponentRaster {
throw new RasterFormatException("IntegerInterleavedRasters must have"+
" SinglePixelPackedSampleModel");
}
verify(false);
verify();
}
......@@ -540,31 +540,6 @@ public class IntegerInterleavedRaster extends IntegerComponentRaster {
return createCompatibleWritableRaster(width,height);
}
/**
* Verify that the layout parameters are consistent with
* the data. If strictCheck
* is false, this method will check for ArrayIndexOutOfBounds conditions. If
* strictCheck is true, this method will check for additional error
* conditions such as line wraparound (width of a line greater than
* the scanline stride).
* @return String Error string, if the layout is incompatible with
* the data. Otherwise returns null.
*/
private void verify (boolean strictCheck) {
int maxSize = 0;
int size;
size = (height-1)*scanlineStride + (width-1) + dataOffsets[0];
if (size > maxSize) {
maxSize = size;
}
if (data.length < maxSize) {
throw new RasterFormatException("Data array too small (should be "+
maxSize
+" but is "+data.length+" )");
}
}
public String toString() {
return new String ("IntegerInterleavedRaster: width = "+width
+" height = " + height
......
......@@ -802,6 +802,15 @@ public class ShortComponentRaster extends SunWritableRaster {
* or if data buffer has not enough capacity.
*/
protected final void verify() {
/* Need to re-verify the dimensions since a sample model may be
* specified to the constructor
*/
if (width <= 0 || height <= 0 ||
height > (Integer.MAX_VALUE / width))
{
throw new RasterFormatException("Invalid raster dimension");
}
for (int i = 0; i < dataOffsets.length; i++) {
if (dataOffsets[i] < 0) {
throw new RasterFormatException("Data offsets for band " + i
......@@ -839,12 +848,13 @@ public class ShortComponentRaster extends SunWritableRaster {
lastPixelOffset += lastScanOffset;
for (int i = 0; i < numDataElements; i++) {
size = lastPixelOffset + dataOffsets[i];
if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
throw new RasterFormatException("Incorrect band offset: "
+ dataOffsets[i]);
}
size = lastPixelOffset + dataOffsets[i];
if (size > maxSize) {
maxSize = size;
}
......
......@@ -841,7 +841,6 @@ abstract class CMap {
CMapFormat6(ByteBuffer bbuffer, int offset, char[] xlat) {
System.err.println("WARNING: CMapFormat8 is untested.");
bbuffer.position(offset+6);
CharBuffer buffer = bbuffer.asCharBuffer();
firstCode = buffer.get();
......@@ -884,7 +883,6 @@ abstract class CMap {
CMapFormat8(ByteBuffer bbuffer, int offset, char[] xlat) {
System.err.println("WARNING: CMapFormat8 is untested.");
bbuffer.position(12);
bbuffer.get(is32);
nGroups = bbuffer.getInt();
......@@ -915,7 +913,6 @@ abstract class CMap {
CMapFormat10(ByteBuffer bbuffer, int offset, char[] xlat) {
System.err.println("WARNING: CMapFormat10 is untested.");
firstCode = bbuffer.getInt() & INTMASK;
entryCount = bbuffer.getInt() & INTMASK;
bbuffer.position(offset+20);
......
......@@ -85,45 +85,72 @@ class LCMSImageLayout {
private boolean imageAtOnce = false;
Object dataArray;
private LCMSImageLayout(int np, int pixelType, int pixelSize) {
private int dataArrayLength; /* in bytes */
private LCMSImageLayout(int np, int pixelType, int pixelSize)
throws ImageLayoutException
{
this.pixelType = pixelType;
width = np;
height = 1;
nextRowOffset = np * pixelSize;
nextRowOffset = safeMult(pixelSize, np);
offset = 0;
}
private LCMSImageLayout(int width, int height, int pixelType,
int pixelSize) {
int pixelSize)
throws ImageLayoutException
{
this.pixelType = pixelType;
this.width = width;
this.height = height;
nextRowOffset = width * pixelSize;
nextRowOffset = safeMult(pixelSize, width);
offset = 0;
}
public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize) {
public LCMSImageLayout(byte[] data, int np, int pixelType, int pixelSize)
throws ImageLayoutException
{
this(np, pixelType, pixelSize);
dataType = DT_BYTE;
dataArray = data;
dataArrayLength = data.length;
verify();
}
public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize) {
public LCMSImageLayout(short[] data, int np, int pixelType, int pixelSize)
throws ImageLayoutException
{
this(np, pixelType, pixelSize);
dataType = DT_SHORT;
dataArray = data;
dataArrayLength = 2 * data.length;
verify();
}
public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize) {
public LCMSImageLayout(int[] data, int np, int pixelType, int pixelSize)
throws ImageLayoutException
{
this(np, pixelType, pixelSize);
dataType = DT_INT;
dataArray = data;
dataArrayLength = 4 * data.length;
verify();
}
public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize) {
public LCMSImageLayout(double[] data, int np, int pixelType, int pixelSize)
throws ImageLayoutException
{
this(np, pixelType, pixelSize);
dataType = DT_DOUBLE;
dataArray = data;
dataArrayLength = 8 * data.length;
verify();
}
private LCMSImageLayout() {
......@@ -132,7 +159,7 @@ class LCMSImageLayout {
/* This method creates a layout object for given image.
* Returns null if the image is not supported by current implementation.
*/
public static LCMSImageLayout createImageLayout(BufferedImage image) {
public static LCMSImageLayout createImageLayout(BufferedImage image) throws ImageLayoutException {
LCMSImageLayout l = new LCMSImageLayout();
switch (image.getType()) {
......@@ -193,9 +220,10 @@ class LCMSImageLayout {
do {
IntegerComponentRaster intRaster = (IntegerComponentRaster)
image.getRaster();
l.nextRowOffset = intRaster.getScanlineStride() * 4;
l.offset = intRaster.getDataOffset(0) * 4;
l.nextRowOffset = safeMult(4, intRaster.getScanlineStride());
l.offset = safeMult(4, intRaster.getDataOffset(0));
l.dataArray = intRaster.getDataStorage();
l.dataArrayLength = 4 * intRaster.getDataStorage().length;
l.dataType = DT_INT;
if (l.nextRowOffset == l.width * 4 * intRaster.getPixelStride()) {
......@@ -213,6 +241,7 @@ class LCMSImageLayout {
int firstBand = image.getSampleModel().getNumBands() - 1;
l.offset = byteRaster.getDataOffset(firstBand);
l.dataArray = byteRaster.getDataStorage();
l.dataArrayLength = byteRaster.getDataStorage().length;
l.dataType = DT_BYTE;
if (l.nextRowOffset == l.width * byteRaster.getPixelStride()) {
l.imageAtOnce = true;
......@@ -225,6 +254,7 @@ class LCMSImageLayout {
ByteComponentRaster byteRaster = (ByteComponentRaster)
image.getRaster();
l.nextRowOffset = byteRaster.getScanlineStride();
l.dataArrayLength = byteRaster.getDataStorage().length;
l.offset = byteRaster.getDataOffset(0);
l.dataArray = byteRaster.getDataStorage();
l.dataType = DT_BYTE;
......@@ -239,9 +269,10 @@ class LCMSImageLayout {
do {
ShortComponentRaster shortRaster = (ShortComponentRaster)
image.getRaster();
l.nextRowOffset = shortRaster.getScanlineStride() * 2;
l.offset = shortRaster.getDataOffset(0) * 2;
l.nextRowOffset = safeMult(2, shortRaster.getScanlineStride());
l.offset = safeMult(2, shortRaster.getDataOffset(0));
l.dataArray = shortRaster.getDataStorage();
l.dataArrayLength = 2 * shortRaster.getDataStorage().length;
l.dataType = DT_SHORT;
if (l.nextRowOffset == l.width * 2 * shortRaster.getPixelStride()) {
......@@ -252,6 +283,7 @@ class LCMSImageLayout {
default:
return null;
}
l.verify();
return l;
}
......@@ -293,6 +325,46 @@ class LCMSImageLayout {
}
}
private void verify() throws ImageLayoutException {
if (offset < 0 || offset >= dataArrayLength) {
throw new ImageLayoutException("Invalid image layout");
}
int lastPixelOffset = safeMult(nextRowOffset, (height - 1));
lastPixelOffset = safeAdd(lastPixelOffset, (width - 1));
int off = safeAdd(offset, lastPixelOffset);
if (off < 0 || off >= dataArrayLength) {
throw new ImageLayoutException("Invalid image layout");
}
}
static int safeAdd(int a, int b) throws ImageLayoutException {
long res = a;
res += b;
if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
throw new ImageLayoutException("Invalid image layout");
}
return (int)res;
}
static int safeMult(int a, int b) throws ImageLayoutException {
long res = a;
res *= b;
if (res < Integer.MIN_VALUE || res > Integer.MAX_VALUE) {
throw new ImageLayoutException("Invalid image layout");
}
return (int)res;
}
public static class ImageLayoutException extends Exception {
public ImageLayoutException(String message) {
super(message);
}
}
public static LCMSImageLayout createImageLayout(Raster r) {
LCMSImageLayout l = new LCMSImageLayout();
if (r instanceof ByteComponentRaster) {
......
......@@ -51,6 +51,7 @@ import java.awt.image.SinglePixelPackedSampleModel;
import java.awt.image.ComponentSampleModel;
import sun.java2d.cmm.*;
import sun.java2d.cmm.lcms.*;
import static sun.java2d.cmm.lcms.LCMSImageLayout.ImageLayoutException;
public class LCMSTransform implements ColorTransform {
......@@ -162,15 +163,19 @@ public class LCMSTransform implements ColorTransform {
public void colorConvert(BufferedImage src, BufferedImage dst) {
LCMSImageLayout srcIL, dstIL;
try {
dstIL = LCMSImageLayout.createImageLayout(dst);
dstIL = LCMSImageLayout.createImageLayout(dst);
if (dstIL != null) {
srcIL = LCMSImageLayout.createImageLayout(src);
if (srcIL != null) {
doTransform(srcIL, dstIL);
return;
if (dstIL != null) {
srcIL = LCMSImageLayout.createImageLayout(src);
if (srcIL != null) {
doTransform(srcIL, dstIL);
return;
}
}
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert images");
}
Raster srcRas = src.getRaster();
......@@ -228,14 +233,18 @@ public class LCMSTransform implements ColorTransform {
}
int idx;
// TODO check for src npixels = dst npixels
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumInComponents());
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
try {
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumInComponents());
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert images");
}
// process each scanline
for (int y = 0; y < h; y++) {
// convert src scanline
......@@ -284,16 +293,19 @@ public class LCMSTransform implements ColorTransform {
alpha = new float[w];
}
int idx;
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
try {
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert images");
}
// process each scanline
for (int y = 0; y < h; y++) {
// convert src scanline
......@@ -402,16 +414,19 @@ public class LCMSTransform implements ColorTransform {
short[] srcLine = new short[w * srcNumBands];
short[] dstLine = new short[w * dstNumBands];
int idx;
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
try {
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert rasters");
}
// process each scanline
for (int y = 0; y < h; y++, ys++, yd++) {
// get src scanline
......@@ -502,15 +517,18 @@ public class LCMSTransform implements ColorTransform {
byte[] dstLine = new byte[w * dstNumBands];
int idx;
// TODO check for src npixels = dst npixels
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumInComponents());
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
try {
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumInComponents());
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert rasters");
}
// process each scanline
for (int y = 0; y < h; y++, ys++, yd++) {
// get src scanline
......@@ -542,16 +560,20 @@ public class LCMSTransform implements ColorTransform {
short[] srcLine = new short[w * srcNumBands];
short[] dstLine = new short[w * dstNumBands];
int idx;
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
try {
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert rasters");
}
// process each scanline
for (int y = 0; y < h; y++, ys++, yd++) {
// get src scanline
......@@ -592,19 +614,23 @@ public class LCMSTransform implements ColorTransform {
dst = new short [(src.length/getNumInComponents())*getNumOutComponents()];
}
LCMSImageLayout srcIL = new LCMSImageLayout(
src, src.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
try {
LCMSImageLayout srcIL = new LCMSImageLayout(
src, src.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
LCMSImageLayout dstIL = new LCMSImageLayout(
dst, dst.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
LCMSImageLayout dstIL = new LCMSImageLayout(
dst, dst.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
doTransform(srcIL, dstIL);
doTransform(srcIL, dstIL);
return dst;
return dst;
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert data");
}
}
public byte[] colorConvert(byte[] src, byte[] dst) {
......@@ -612,18 +638,22 @@ public class LCMSTransform implements ColorTransform {
dst = new byte [(src.length/getNumInComponents())*getNumOutComponents()];
}
LCMSImageLayout srcIL = new LCMSImageLayout(
src, src.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumInComponents());
try {
LCMSImageLayout srcIL = new LCMSImageLayout(
src, src.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumInComponents());
LCMSImageLayout dstIL = new LCMSImageLayout(
dst, dst.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
LCMSImageLayout dstIL = new LCMSImageLayout(
dst, dst.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
doTransform(srcIL, dstIL);
doTransform(srcIL, dstIL);
return dst;
return dst;
} catch (ImageLayoutException e) {
throw new CMMException("Unable to convert data");
}
}
}
......@@ -46,8 +46,28 @@ import sun.misc.IOUtils;
class Trampoline {
static {
if (Trampoline.class.getClassLoader() == null) {
throw new Error(
"Trampoline must not be defined by the bootstrap classloader");
}
}
private static void ensureInvocableMethod(Method m)
throws InvocationTargetException
{
Class<?> clazz = m.getDeclaringClass();
if (clazz.equals(AccessController.class) ||
clazz.equals(Method.class) ||
clazz.getName().startsWith("java.lang.invoke."))
throw new InvocationTargetException(
new UnsupportedOperationException("invocation not supported"));
}
private static Object invoke(Method m, Object obj, Object[] params)
throws InvocationTargetException, IllegalAccessException {
throws InvocationTargetException, IllegalAccessException
{
ensureInvocableMethod(m);
return m.invoke(obj, params);
}
}
......@@ -251,16 +271,6 @@ public final class MethodUtil extends SecureClassLoader {
*/
public static Object invoke(Method m, Object obj, Object[] params)
throws InvocationTargetException, IllegalAccessException {
if (m.getDeclaringClass().equals(AccessController.class) ||
(m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.class)
&& m.getName().equals("lookup")) ||
(m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.Lookup.class)
&& (m.getName().startsWith("find") ||
m.getName().startsWith("bind") ||
m.getName().startsWith("unreflect"))) ||
m.getDeclaringClass().equals(Method.class))
throw new InvocationTargetException(
new UnsupportedOperationException("invocation not supported"));
try {
return bounce.invoke(null, new Object[] {m, obj, params});
} catch (InvocationTargetException ie) {
......@@ -293,10 +303,10 @@ public final class MethodUtil extends SecureClassLoader {
Method.class, Object.class, Object[].class
};
Method b = t.getDeclaredMethod("invoke", types);
((AccessibleObject)b).setAccessible(true);
return b;
}
});
b.setAccessible(true);
return b;
}
});
} catch (Exception e) {
throw new InternalError("bouncer cannot be found", e);
}
......
......@@ -55,13 +55,19 @@ import java.rmi.server.RMIClassLoader;
public class MarshalInputStream extends ObjectInputStream {
/**
* value of "java.rmi.server.useCodebaseOnly" property,
* Value of "java.rmi.server.useCodebaseOnly" property,
* as cached at class initialization time.
*
* The default value is true. That is, the value is true
* if the property is absent or is not equal to "false".
* The value is only false when the property is present
* and is equal to "false".
*/
private static final boolean useCodebaseOnlyProperty =
java.security.AccessController.doPrivileged(
new sun.security.action.GetBooleanAction(
"java.rmi.server.useCodebaseOnly")).booleanValue();
! java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(
"java.rmi.server.useCodebaseOnly", "true"))
.equalsIgnoreCase("false");
/** table to hold sun classes to which access is explicitly permitted */
protected static Map<String, Class<?>> permittedSunClasses
......
/*
* Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -101,7 +101,7 @@ abstract class SHA2 extends DigestBase {
i2bBig4((int)bitsProcessed, buffer, 60);
implCompress(buffer, 0);
i2bBig(state, 0, out, ofs, 32);
i2bBig(state, 0, out, ofs, engineGetDigestLength());
}
/**
......
......@@ -843,5 +843,52 @@ public final class UntrustedCertificates {
"zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" +
"-----END CERTIFICATE-----");
//
// Revoked code signing certificate w/ a stolen key issued by GoDaddy
// used to sign malware
//
// Subject: CN=CLEARESULT CONSULTING INC., OU=Corporate IT,
// O=CLEARESULT CONSULTING INC., L=Austin, ST=TX, C=US
// Issuer: SERIALNUMBER=07969287,
// CN=Go Daddy Secure Certification Authority,
// OU=http://certificates.godaddy.com/repository,
// O="GoDaddy.com, Inc.",
// L=Scottsdale,
// ST=Arizona,
// C=US
// Serial: 2b:73:43:2a:a8:4f:44
add("clearesult-consulting-inc-2AA84F44",
"-----BEGIN CERTIFICATE-----\n" +
"MIIFYjCCBEqgAwIBAgIHK3NDKqhPRDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE\n" +
"BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY\n" +
"BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm\n" +
"aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5\n" +
"IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky\n" +
"ODcwHhcNMTIwMjE1MjEwOTA2WhcNMTQwMjE1MjEwOTA2WjCBjDELMAkGA1UEBgwC\n" +
"VVMxCzAJBgNVBAgMAlRYMQ8wDQYDVQQHDAZBdXN0aW4xIzAhBgNVBAoMGkNMRUFS\n" +
"RVNVTFQgQ09OU1VMVElORyBJTkMuMRUwEwYDVQQLDAxDb3Jwb3JhdGUgSVQxIzAh\n" +
"BgNVBAMMGkNMRUFSRVNVTFQgQ09OU1VMVElORyBJTkMuMIIBIjANBgkqhkiG9w0B\n" +
"AQEFAAOCAQ8AMIIBCgKCAQEAtIOjCKeAicull+7ZIzt0/4ya3IeXUFlfypqKMLkU\n" +
"IbKjn0P5uMj6VE3rlbZr44RCegxvdnR6umBh1c0ZXoN3o+yc0JKcKcLiApmJJ277\n" +
"p7IbLwYDhBXRQNoIJm187IOMRPIxsKN4hL91txn9jGBmW+9zKlJlNhR5R7vjwU2E\n" +
"jrH/6oqsc9EM2yYpfjlNv6+3jSwAYZCkSWr+27PQOV+YHKmIxtJjX0upFz5FdIrV\n" +
"9CCX+L2Kji1THOkSgG4QTbYxmEcHqGViWz8hXLeNXjcbEsPuIiAu3hknxRHfUTE/\n" +
"U0Lh0Ug1e3LrJu+WnxM2SmUY4krsZ22c0yWUW9hzWITIjQIDAQABo4IBhzCCAYMw\n" +
"DwYDVR0TAQH/BAUwAwEBADATBgNVHSUEDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8E\n" +
"BAMCB4AwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9n\n" +
"ZHM1LTE2LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcCMDkwNwYIKwYBBQUH\n" +
"AgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8w\n" +
"gYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRk\n" +
"eS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHku\n" +
"Y29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9\n" +
"rGEyk2xF1uLuhV+auud2mWjM5zAdBgNVHQ4EFgQUDtdeKqeN2QkcbEp1HovFieNB\n" +
"XiowDQYJKoZIhvcNAQEFBQADggEBAD74Agw5tvi2aBl4/f/s7/VE/BClzDsKMb9K\n" +
"v9qpeC45ZA/jelxV11HKbQnVF194gDb7D2H9OsAsRUy8HVKbXEcc/8dKvwOqb+BC\n" +
"2i/EmfjLgmCfezNFtLq8xcPxF3zIRc44vPrK0z4YZsaHdH+yTEJ51p5EMdTqaLaP\n" +
"4n5m8LX3RfqlQB9dYFe6dUoYZjKm9d/pIRww3VqfOzjl42Edi1w6dWmBVMx1NZuR\n" +
"DBabJH1vJ9Gd+KwxMCmBZ6pQPl28JDimhJhI2LNqU349uADQVV0HJosddN/ARyyI\n" +
"LSIQO7BnNVKVG9Iujf33bvPNeg0qNz5qw+rKKq97Pqeum+L5oKU=\n" +
"-----END CERTIFICATE-----");
}
}
......@@ -146,22 +146,35 @@ keystore.type=jks
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.xml.internal.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
#
# List of comma-separated packages that start with or equal this string
......@@ -174,22 +187,35 @@ package.access=sun.,\
# checkPackageDefinition.
#
package.definition=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.xml.internal.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
#
# Determines whether this properties file can be appended to
......
......@@ -147,22 +147,34 @@ keystore.type=jks
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.xml.internal.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
apple.
#
......@@ -176,22 +188,34 @@ package.access=sun.,\
# checkPackageDefinition.
#
package.definition=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.xml.internal.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
apple.
#
......
......@@ -148,22 +148,34 @@ keystore.type=jks
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.xml.internal.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
#
# List of comma-separated packages that start with or equal this string
......@@ -176,22 +188,34 @@ package.access=sun.,\
# checkPackageDefinition.
#
package.definition=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.xml.internal.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
#
# Determines whether this properties file can be appended to
......
......@@ -147,22 +147,35 @@ keystore.type=jks
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.xml.internal.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
com.sun.java.accessibility.
#
# List of comma-separated packages that start with or equal this string
......@@ -175,22 +188,35 @@ package.access=sun.,\
# checkPackageDefinition.
#
package.definition=sun.,\
com.sun.xml.internal.bind.,\
com.sun.xml.internal.org.jvnet.staxex.,\
com.sun.xml.internal.ws.,\
com.sun.xml.internal.,\
com.sun.imageio.,\
com.sun.istack.internal.,\
com.sun.jmx.,\
com.sun.proxy.,\
com.sun.org.apache.xerces.internal.utils.,\
com.sun.org.apache.bcel.internal.,\
com.sun.org.apache.regexp.internal.,\
com.sun.org.apache.xerces.internal.,\
com.sun.org.apache.xpath.internal.,\
com.sun.org.apache.xalan.internal.extensions.,\
com.sun.org.apache.xalan.internal.lib.,\
com.sun.org.apache.xalan.internal.res.,\
com.sun.org.apache.xalan.internal.templates.,\
com.sun.org.apache.xalan.internal.utils.,\
com.sun.org.glassfish.external.,\
com.sun.org.glassfish.gmbal.,\
com.sun.org.apache.xalan.internal.xslt.,\
com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
com.sun.org.apache.xalan.internal.xsltc.compiler.,\
com.sun.org.apache.xalan.internal.xsltc.trax.,\
com.sun.org.apache.xalan.internal.xsltc.util.,\
com.sun.org.apache.xml.internal.res.,\
com.sun.org.apache.xml.internal.serializer.utils.,\
com.sun.org.apache.xml.internal.utils.,\
com.sun.org.glassfish.,\
com.oracle.xmlns.internal.,\
com.oracle.webservices.internal.,\
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.
jdk.internal.,\
jdk.nashorn.internal.,\
jdk.nashorn.tools.,\
com.sun.java.accessibility.
#
# Determines whether this properties file can be appended to
......
......@@ -33,8 +33,11 @@
*/
jclass ia_class;
jfieldID ia_addressID;
jfieldID ia_familyID;
jclass iac_class;
jfieldID ia_holderID;
jfieldID iac_addressID;
jfieldID iac_familyID;
jfieldID iac_hostNameID;
jfieldID ia_preferIPv6AddressID;
/*
......@@ -48,10 +51,18 @@ Java_java_net_InetAddress_init(JNIEnv *env, jclass cls) {
CHECK_NULL(c);
ia_class = (*env)->NewGlobalRef(env, c);
CHECK_NULL(ia_class);
ia_addressID = (*env)->GetFieldID(env, ia_class, "address", "I");
CHECK_NULL(ia_addressID);
ia_familyID = (*env)->GetFieldID(env, ia_class, "family", "I");
CHECK_NULL(ia_familyID);
c = (*env)->FindClass(env,"java/net/InetAddress$InetAddressHolder");
CHECK_NULL(c);
iac_class = (*env)->NewGlobalRef(env, c);
ia_holderID = (*env)->GetFieldID(env, ia_class, "holder", "Ljava/net/InetAddress$InetAddressHolder;");
CHECK_NULL(ia_holderID);
ia_preferIPv6AddressID = (*env)->GetStaticFieldID(env, ia_class, "preferIPv6Address", "Z");
CHECK_NULL(ia_preferIPv6AddressID);
iac_addressID = (*env)->GetFieldID(env, iac_class, "address", "I");
CHECK_NULL(iac_addressID);
iac_familyID = (*env)->GetFieldID(env, iac_class, "family", "I");
CHECK_NULL(iac_familyID);
iac_hostNameID = (*env)->GetFieldID(env, iac_class, "hostName", "Ljava/lang/String;");
CHECK_NULL(iac_hostNameID);
}
......@@ -84,6 +84,58 @@ void init(JNIEnv *env) {
}
}
/* The address, and family fields used to be in InetAddress
* but are now in an implementation object. So, there is an extra
* level of indirection to access them now.
*/
extern jclass iac_class;
extern jfieldID ia_holderID;
extern jfieldID iac_addressID;
extern jfieldID iac_familyID;
void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) {
jobject holder;
init(env);
holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
(*env)->SetIntField(env, holder, iac_addressID, address);
}
void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) {
jobject holder;
init(env);
holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
(*env)->SetIntField(env, holder, iac_familyID, family);
}
void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) {
jobject holder;
init(env);
holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
(*env)->SetObjectField(env, holder, iac_hostNameID, host);
}
int getInetAddress_addr(JNIEnv *env, jobject iaObj) {
jobject holder;
init(env);
holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
return (*env)->GetIntField(env, holder, iac_addressID);
}
int getInetAddress_family(JNIEnv *env, jobject iaObj) {
jobject holder;
init(env);
holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
return (*env)->GetIntField(env, holder, iac_familyID);
}
jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) {
jobject holder;
init(env);
holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
return (*env)->GetObjectField(env, holder, iac_hostNameID);
}
JNIEXPORT jobject JNICALL
NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
jobject iaObj;
......@@ -110,8 +162,8 @@ NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
iaObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
CHECK_NULL_RETURN(iaObj, NULL);
address = NET_IPv4MappedToIPv4(caddr);
(*env)->SetIntField(env, iaObj, ia_addressID, address);
(*env)->SetIntField(env, iaObj, ia_familyID, IPv4);
setInetAddress_addr(env, iaObj, address);
setInetAddress_family(env, iaObj, IPv4);
} else {
static jclass inet6Cls = 0;
jint scope;
......@@ -131,7 +183,7 @@ NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
(*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress);
(*env)->SetIntField(env, iaObj, ia_familyID, IPv6);
setInetAddress_family(env, iaObj, IPv6);
scope = getScopeID(him);
(*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
if (scope > 0)
......@@ -153,9 +205,8 @@ NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
}
iaObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
CHECK_NULL_RETURN(iaObj, NULL);
(*env)->SetIntField(env, iaObj, ia_familyID, IPv4);
(*env)->SetIntField(env, iaObj, ia_addressID,
ntohl(him4->sin_addr.s_addr));
setInetAddress_family(env, iaObj, IPv4);
setInetAddress_addr(env, iaObj, ntohl(him4->sin_addr.s_addr));
*port = ntohs(him4->sin_port);
}
return iaObj;
......@@ -167,8 +218,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, struct sockaddr *him, jobject iaObj)
jint family = AF_INET;
#ifdef AF_INET6
family = (*env)->GetIntField(env, iaObj, ia_familyID) == IPv4?
AF_INET : AF_INET6;
family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
if (him->sa_family == AF_INET6) {
#ifdef WIN32
struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
......@@ -183,7 +233,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, struct sockaddr *him, jobject iaObj)
return JNI_FALSE;
}
addrNew = NET_IPv4MappedToIPv4(caddrNew);
addrCur = (*env)->GetIntField(env, iaObj, ia_addressID);
addrCur = getInetAddress_addr(env, iaObj);
if (addrNew == addrCur) {
return JNI_TRUE;
} else {
......@@ -215,7 +265,7 @@ NET_SockaddrEqualsInetAddress(JNIEnv *env, struct sockaddr *him, jobject iaObj)
return JNI_FALSE;
}
addrNew = ntohl(him4->sin_addr.s_addr);
addrCur = (*env)->GetIntField(env, iaObj, ia_addressID);
addrCur = getInetAddress_addr(env, iaObj);
if (addrNew == addrCur) {
return JNI_TRUE;
} else {
......
......@@ -53,10 +53,18 @@
* i.e. psi_timeoutID is PlainSocketImpl's timeout field's ID.
*/
extern jclass ia_class;
extern jfieldID ia_addressID;
extern jfieldID ia_familyID;
extern jfieldID iac_addressID;
extern jfieldID iac_familyID;
extern jfieldID iac_hostNameID;
extern jfieldID ia_preferIPv6AddressID;
extern void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address);
extern void setInetAddress_family(JNIEnv *env, jobject iaObj, int family);
extern void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject h);
extern int getInetAddress_addr(JNIEnv *env, jobject iaObj);
extern int getInetAddress_family(JNIEnv *env, jobject iaObj);
extern jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj);
extern jclass ia4_class;
extern jmethodID ia4_ctrID;
......
......@@ -45,6 +45,53 @@ static int findIdx(unsigned int rgb, unsigned int *lut, int numLut1);
# define TRUE 1
#endif
#define CHECK_STRIDE(yy, hh, ss) \
if ((ss) != 0) { \
int limit = 0x7fffffff / ((ss) > 0 ? (ss) : -(ss)); \
if (limit < (yy) || limit < ((yy) + (hh) - 1)) { \
/* integer oveflow */ \
return JNI_FALSE; \
} \
} \
#define CHECK_SRC() \
do { \
int pixeloffset; \
if (off < 0 || off >= srcDataLength) { \
return JNI_FALSE; \
} \
CHECK_STRIDE(0, h, scansize); \
\
/* check scansize */ \
pixeloffset = scansize * (h - 1); \
if ((w - 1) > (0x7fffffff - pixeloffset)) { \
return JNI_FALSE; \
} \
pixeloffset += (w - 1); \
\
if (off > (0x7fffffff - pixeloffset)) { \
return JNI_FALSE; \
} \
} while (0) \
#define CHECK_DST(xx, yy) \
do { \
int soffset = (yy) * sStride; \
int poffset = (xx) * pixelStride; \
if (poffset > (0x7fffffff - soffset)) { \
return JNI_FALSE; \
} \
poffset += soffset; \
if (dstDataOff > (0x7fffffff - poffset)) { \
return JNI_FALSE; \
} \
poffset += dstDataOff; \
\
if (poffset < 0 || poffset >= dstDataLength) { \
return JNI_FALSE; \
} \
} while (0) \
static jfieldID s_JnumSrcLUTID;
static jfieldID s_JsrcLUTtransIndexID;
......@@ -58,7 +105,7 @@ Java_sun_awt_image_ImageRepresentation_initIDs(JNIEnv *env, jclass cls) {
/*
* This routine is used to draw ICM pixels into a default color model
*/
JNIEXPORT void JNICALL
JNIEXPORT jboolean JNICALL
Java_sun_awt_image_ImageRepresentation_setICMpixels(JNIEnv *env, jclass cls,
jint x, jint y, jint w,
jint h, jintArray jlut,
......@@ -67,7 +114,10 @@ Java_sun_awt_image_ImageRepresentation_setICMpixels(JNIEnv *env, jclass cls,
jobject jict)
{
unsigned char *srcData = NULL;
jint srcDataLength;
int *dstData;
jint dstDataLength;
jint dstDataOff;
int *dstP, *dstyP;
unsigned char *srcyP, *srcP;
int *srcLUT = NULL;
......@@ -80,12 +130,20 @@ Java_sun_awt_image_ImageRepresentation_setICMpixels(JNIEnv *env, jclass cls,
if (JNU_IsNull(env, jlut)) {
JNU_ThrowNullPointerException(env, "NullPointerException");
return;
return JNI_FALSE;
}
if (JNU_IsNull(env, jpix)) {
JNU_ThrowNullPointerException(env, "NullPointerException");
return;
return JNI_FALSE;
}
if (x < 0 || w < 1 || (0x7fffffff - x) < w) {
return JNI_FALSE;
}
if (y < 0 || h < 1 || (0x7fffffff - y) < h) {
return JNI_FALSE;
}
sStride = (*env)->GetIntField(env, jict, g_ICRscanstrID);
......@@ -93,10 +151,47 @@ Java_sun_awt_image_ImageRepresentation_setICMpixels(JNIEnv *env, jclass cls,
joffs = (*env)->GetObjectField(env, jict, g_ICRdataOffsetsID);
jdata = (*env)->GetObjectField(env, jict, g_ICRdataID);
if (JNU_IsNull(env, jdata)) {
/* no destination buffer */
return JNI_FALSE;
}
if (JNU_IsNull(env, joffs) || (*env)->GetArrayLength(env, joffs) < 1) {
/* invalid data offstes in raster */
return JNI_FALSE;
}
srcDataLength = (*env)->GetArrayLength(env, jpix);
dstDataLength = (*env)->GetArrayLength(env, jdata);
cOffs = (int *) (*env)->GetPrimitiveArrayCritical(env, joffs, NULL);
if (cOffs == NULL) {
JNU_ThrowNullPointerException(env, "Null channel offset array");
return JNI_FALSE;
}
dstDataOff = cOffs[0];
/* the offset array is not needed anymore and can be released */
(*env)->ReleasePrimitiveArrayCritical(env, joffs, cOffs, JNI_ABORT);
joffs = NULL;
cOffs = NULL;
/* do basic validation: make sure that offsets for
* first pixel and for last pixel are safe to calculate and use */
CHECK_STRIDE(y, h, sStride);
CHECK_STRIDE(x, w, pixelStride);
CHECK_DST(x, y);
CHECK_DST(x + w -1, y + h - 1);
/* check source array */
CHECK_SRC();
srcLUT = (int *) (*env)->GetPrimitiveArrayCritical(env, jlut, NULL);
if (srcLUT == NULL) {
JNU_ThrowNullPointerException(env, "Null IndexColorModel LUT");
return;
return JNI_FALSE;
}
srcData = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, jpix,
......@@ -104,27 +199,18 @@ Java_sun_awt_image_ImageRepresentation_setICMpixels(JNIEnv *env, jclass cls,
if (srcData == NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT);
JNU_ThrowNullPointerException(env, "Null data array");
return;
}
cOffs = (int *) (*env)->GetPrimitiveArrayCritical(env, joffs, NULL);
if (cOffs == NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT);
JNU_ThrowNullPointerException(env, "Null channel offset array");
return;
return JNI_FALSE;
}
dstData = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, NULL);
if (dstData == NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, joffs, cOffs, JNI_ABORT);
JNU_ThrowNullPointerException(env, "Null tile data array");
return;
return JNI_FALSE;
}
dstyP = dstData + cOffs[0] + y*sStride + x*pixelStride;
dstyP = dstData + dstDataOff + y*sStride + x*pixelStride;
srcyP = srcData + off;
for (yIdx = 0; yIdx < h; yIdx++, srcyP += scansize, dstyP+=sStride) {
srcP = srcyP;
......@@ -137,12 +223,12 @@ Java_sun_awt_image_ImageRepresentation_setICMpixels(JNIEnv *env, jclass cls,
/* Release the locked arrays */
(*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, joffs, cOffs, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dstData, JNI_ABORT);
return JNI_TRUE;
}
JNIEXPORT jint JNICALL
JNIEXPORT jboolean JNICALL
Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls,
jint x, jint y, jint w,
jint h, jintArray jlut,
......@@ -150,7 +236,7 @@ Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls,
jobject jicm,
jbyteArray jpix, jint off,
jint scansize,
jobject jbct, jint chanOff)
jobject jbct, jint dstDataOff)
{
unsigned int *srcLUT = NULL;
unsigned int *newLUT = NULL;
......@@ -159,6 +245,8 @@ Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls,
int mapSize;
jobject jdata = NULL;
jobject jnewlut = NULL;
jint srcDataLength;
jint dstDataLength;
unsigned char *srcData;
unsigned char *dstData;
unsigned char *dataP;
......@@ -174,14 +262,23 @@ Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls,
if (JNU_IsNull(env, jlut)) {
JNU_ThrowNullPointerException(env, "NullPointerException");
return 0;
return JNI_FALSE;
}
if (JNU_IsNull(env, jpix)) {
JNU_ThrowNullPointerException(env, "NullPointerException");
return 0;
return JNI_FALSE;
}
if (x < 0 || w < 1 || (0x7fffffff - x) < w) {
return JNI_FALSE;
}
if (y < 0 || h < 1 || (0x7fffffff - y) < h) {
return JNI_FALSE;
}
sStride = (*env)->GetIntField(env, jbct, g_BCRscanstrID);
pixelStride =(*env)->GetIntField(env, jbct, g_BCRpixstrID);
jdata = (*env)->GetObjectField(env, jbct, g_BCRdataID);
......@@ -193,13 +290,31 @@ Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls,
of byte data type, so we have to convert the image data
to default representation.
*/
return 0;
return JNI_FALSE;
}
if (JNU_IsNull(env, jdata)) {
/* no destination buffer */
return JNI_FALSE;
}
srcDataLength = (*env)->GetArrayLength(env, jpix);
dstDataLength = (*env)->GetArrayLength(env, jdata);
CHECK_STRIDE(y, h, sStride);
CHECK_STRIDE(x, w, pixelStride);
CHECK_DST(x, y);
CHECK_DST(x + w -1, y + h - 1);
/* check source array */
CHECK_SRC();
srcLUT = (unsigned int *) (*env)->GetPrimitiveArrayCritical(env, jlut,
NULL);
if (srcLUT == NULL) {
/* out of memory error already thrown */
return 0;
return JNI_FALSE;
}
newLUT = (unsigned int *) (*env)->GetPrimitiveArrayCritical(env, jnewlut,
......@@ -208,7 +323,7 @@ Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls,
(*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT,
JNI_ABORT);
/* out of memory error already thrown */
return 0;
return JNI_FALSE;
}
newNumLut = numLut;
......@@ -219,7 +334,7 @@ Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls,
(*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT,
JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, jnewlut, newLUT, JNI_ABORT);
return 0;
return JNI_FALSE;
}
/* Don't need these any more */
......@@ -239,7 +354,7 @@ Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls,
NULL);
if (srcData == NULL) {
/* out of memory error already thrown */
return 0;
return JNI_FALSE;
}
dstData = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, jdata,
......@@ -247,10 +362,10 @@ Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls,
if (dstData == NULL) {
(*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT);
/* out of memory error already thrown */
return 0;
return JNI_FALSE;
}
ydataP = dstData + chanOff + y*sStride + x*pixelStride;
ydataP = dstData + dstDataOff + y*sStride + x*pixelStride;
ypixP = srcData + off;
for (i=0; i < h; i++) {
......@@ -268,7 +383,7 @@ Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls,
(*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT);
(*env)->ReleasePrimitiveArrayCritical(env, jdata, dstData, JNI_ABORT);
return 1;
return JNI_TRUE;
}
static int compareLUTs(unsigned int *lut1, int numLut1, int transIdx,
......
......@@ -34,6 +34,7 @@
#include "java_awt_color_ColorSpace.h"
#include "awt_Mlib.h"
#include "safe_alloc.h"
#include "safe_math.h"
static int setHints(JNIEnv *env, BufImageS_t *imageP);
......
......@@ -57,8 +57,8 @@
#define MAX(a,b) ((a) > (b) ? (a) : (b))
/* Cached Java method ids */
static jmethodID ImageInputStream_readID;
static jmethodID ImageInputStream_skipBytesID;
static jmethodID JPEGImageReader_readInputDataID;
static jmethodID JPEGImageReader_skipInputBytesID;
static jmethodID JPEGImageReader_warningOccurredID;
static jmethodID JPEGImageReader_warningWithMessageID;
static jmethodID JPEGImageReader_setImageDataID;
......@@ -66,7 +66,7 @@ static jmethodID JPEGImageReader_acceptPixelsID;
static jmethodID JPEGImageReader_pushBackID;
static jmethodID JPEGImageReader_passStartedID;
static jmethodID JPEGImageReader_passCompleteID;
static jmethodID ImageOutputStream_writeID;
static jmethodID JPEGImageWriter_writeOutputDataID;
static jmethodID JPEGImageWriter_warningOccurredID;
static jmethodID JPEGImageWriter_warningWithMessageID;
static jmethodID JPEGImageWriter_writeMetadataID;
......@@ -923,7 +923,7 @@ imageio_fill_input_buffer(j_decompress_ptr cinfo)
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallIntMethod(env,
sb->stream,
ImageInputStream_readID,
JPEGImageReader_readInputDataID,
sb->hstreamBuffer, 0,
sb->bufferLength);
if ((*env)->ExceptionOccurred(env)
......@@ -1013,7 +1013,7 @@ imageio_fill_suspended_buffer(j_decompress_ptr cinfo)
}
ret = (*env)->CallIntMethod(env, sb->stream,
ImageInputStream_readID,
JPEGImageReader_readInputDataID,
sb->hstreamBuffer,
offset, buflen);
if ((*env)->ExceptionOccurred(env)
......@@ -1107,7 +1107,7 @@ imageio_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
RELEASE_ARRAYS(env, data, src->next_input_byte);
ret = (*env)->CallLongMethod(env,
sb->stream,
ImageInputStream_skipBytesID,
JPEGImageReader_skipInputBytesID,
(jlong) num_bytes);
if ((*env)->ExceptionOccurred(env)
|| !GET_ARRAYS(env, data, &(src->next_input_byte))) {
......@@ -1382,13 +1382,13 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_initReaderIDs
jclass qTableClass,
jclass huffClass) {
ImageInputStream_readID = (*env)->GetMethodID(env,
ImageInputStreamClass,
"read",
JPEGImageReader_readInputDataID = (*env)->GetMethodID(env,
cls,
"readInputData",
"([BII)I");
ImageInputStream_skipBytesID = (*env)->GetMethodID(env,
ImageInputStreamClass,
"skipBytes",
JPEGImageReader_skipInputBytesID = (*env)->GetMethodID(env,
cls,
"skipInputBytes",
"(J)J");
JPEGImageReader_warningOccurredID = (*env)->GetMethodID(env,
cls,
......@@ -1531,8 +1531,7 @@ JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_setSource
(JNIEnv *env,
jobject this,
jlong ptr,
jobject source) {
jlong ptr) {
imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
j_common_ptr cinfo;
......@@ -1546,7 +1545,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_setSource
cinfo = data->jpegObj;
imageio_set_stream(env, cinfo, data, source);
imageio_set_stream(env, cinfo, data, this);
imageio_init_source((j_decompress_ptr) cinfo);
}
......@@ -2291,7 +2290,7 @@ imageio_empty_output_buffer (j_compress_ptr cinfo)
(*env)->CallVoidMethod(env,
sb->stream,
ImageOutputStream_writeID,
JPEGImageWriter_writeOutputDataID,
sb->hstreamBuffer,
0,
sb->bufferLength);
......@@ -2328,7 +2327,7 @@ imageio_term_destination (j_compress_ptr cinfo)
(*env)->CallVoidMethod(env,
sb->stream,
ImageOutputStream_writeID,
JPEGImageWriter_writeOutputDataID,
sb->hstreamBuffer,
0,
datacount);
......@@ -2366,13 +2365,12 @@ JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initWriterIDs
(JNIEnv *env,
jclass cls,
jclass IOSClass,
jclass qTableClass,
jclass huffClass) {
ImageOutputStream_writeID = (*env)->GetMethodID(env,
IOSClass,
"write",
JPEGImageWriter_writeOutputDataID = (*env)->GetMethodID(env,
cls,
"writeOutputData",
"([BII)V");
JPEGImageWriter_warningOccurredID = (*env)->GetMethodID(env,
......@@ -2496,8 +2494,7 @@ JNIEXPORT void JNICALL
Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_setDest
(JNIEnv *env,
jobject this,
jlong ptr,
jobject destination) {
jlong ptr) {
imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
j_compress_ptr cinfo;
......@@ -2511,7 +2508,7 @@ Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_setDest
cinfo = (j_compress_ptr) data->jpegObj;
imageio_set_stream(env, data->jpegObj, data, destination);
imageio_set_stream(env, data->jpegObj, data, this);
// Don't call the init method, as that depends on pinned arrays
......
......@@ -42,6 +42,7 @@
#include "awt_Mlib.h"
#include "gdefs.h"
#include "safe_alloc.h"
#include "safe_math.h"
/***************************************************************************
* Definitions *
......@@ -1993,13 +1994,23 @@ cvtCustomToDefault(JNIEnv *env, BufImageS_t *imageP, int component,
unsigned char *dP = dataP;
#define NUM_LINES 10
int numLines = NUM_LINES;
int nbytes = rasterP->width*4*NUM_LINES;
/* it is safe to calculate the scan length, because width has been verified
* on creation of the mlib image
*/
int scanLength = rasterP->width * 4;
int nbytes = 0;
if (!SAFE_TO_MULT(numLines, scanLength)) {
return -1;
}
nbytes = numLines * scanLength;
for (y=0; y < rasterP->height; y+=numLines) {
/* getData, one scanline at a time */
if (y+numLines > rasterP->height) {
numLines = rasterP->height - y;
nbytes = rasterP->width*4*numLines;
nbytes = numLines * scanLength;
}
jpixels = (*env)->CallObjectMethod(env, imageP->jimage,
g_BImgGetRGBMID, 0, y,
......@@ -2129,8 +2140,14 @@ allocateArray(JNIEnv *env, BufImageS_t *imageP,
if (cvtToDefault) {
int status = 0;
*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, 4, width, height);
if (*mlibImagePP == NULL) {
return -1;
}
cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
/* Make sure the image is cleared */
/* Make sure the image is cleared.
* NB: the image dimension is already verified, so we can
* safely calculate the length of the buffer.
*/
memset(cDataP, 0, width*height*4);
if (!isSrc) {
......@@ -2380,6 +2397,9 @@ allocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
case sun_awt_image_IntegerComponentRaster_TYPE_BYTE_PACKED_SAMPLES:
*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
width, height);
if (*mlibImagePP == NULL) {
return -1;
}
if (!isSrc) return 0;
cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
return expandPackedBCR(env, rasterP, -1, cDataP);
......@@ -2388,6 +2408,9 @@ allocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
if (rasterP->sppsm.maxBitSize <= 8) {
*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
width, height);
if (*mlibImagePP == NULL) {
return -1;
}
if (!isSrc) return 0;
cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
return expandPackedSCR(env, rasterP, -1, cDataP);
......@@ -2397,6 +2420,9 @@ allocateRasterArray(JNIEnv *env, RasterS_t *rasterP,
if (rasterP->sppsm.maxBitSize <= 8) {
*mlibImagePP = (*sMlibSysFns.createFP)(MLIB_BYTE, rasterP->numBands,
width, height);
if (*mlibImagePP == NULL) {
return -1;
}
if (!isSrc) return 0;
cDataP = (unsigned char *) mlib_ImageGetData(*mlibImagePP);
return expandPackedICR(env, rasterP, -1, cDataP);
......
......@@ -120,6 +120,7 @@
#include "mlib_image.h"
#include "mlib_ImageRowTable.h"
#include "mlib_ImageCreate.h"
#include "safe_math.h"
/***************************************************************/
mlib_image* mlib_ImageSet(mlib_image *image,
......@@ -247,28 +248,50 @@ mlib_image *mlib_ImageCreate(mlib_type type,
return NULL;
};
if (!SAFE_TO_MULT(width, channels)) {
return NULL;
}
wb = width * channels;
switch (type) {
case MLIB_DOUBLE:
wb = width * channels * 8;
if (!SAFE_TO_MULT(wb, 8)) {
return NULL;
}
wb *= 8;
break;
case MLIB_FLOAT:
case MLIB_INT:
wb = width * channels * 4;
if (!SAFE_TO_MULT(wb, 4)) {
return NULL;
}
wb *= 4;
break;
case MLIB_USHORT:
case MLIB_SHORT:
wb = width * channels * 2;
if (!SAFE_TO_MULT(wb, 4)) {
return NULL;
}
wb *= 2;
break;
case MLIB_BYTE:
wb = width * channels;
// wb is ready
break;
case MLIB_BIT:
wb = (width * channels + 7) / 8;
if (!SAFE_TO_ADD(7, wb)) {
return NULL;
}
wb = (wb + 7) / 8;
break;
default:
return NULL;
}
if (!SAFE_TO_MULT(wb, height)) {
return NULL;
}
data = mlib_malloc(wb * height);
if (data == NULL) {
return NULL;
......
......@@ -41,10 +41,4 @@
(((w) > 0) && ((h) > 0) && ((sz) > 0) && \
(((0xffffffffu / ((juint)(w))) / ((juint)(h))) > ((juint)(sz))))
#define SAFE_TO_MULT(a, b) \
(((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
#define SAFE_TO_ADD(a, b) \
(((a) >= 0) && ((b) >= 0) && ((0x7fffffff - (a)) > (b)))
#endif // __SAFE_ALLOC_H__
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef __SAFE_MATH_H__
#define __SAFE_MATH_H__
#define SAFE_TO_MULT(a, b) \
(((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
#define SAFE_TO_ADD(a, b) \
(((a) >= 0) && ((b) >= 0) && ((0x7fffffff - (a)) > (b)))
#endif // __SAFE_MATH_H__
......@@ -66,8 +66,21 @@ FontInstanceAdapter::FontInstanceAdapter(JNIEnv *theEnv,
yScalePixelsToUnits = upem / yppem;
};
const void *FontInstanceAdapter::getFontTable(LETag tableTag) const
{
size_t ignored = 0;
return getFontTable(tableTag, ignored);
}
static const LETag cacheMap[LAYOUTCACHE_ENTRIES] = {
GPOS_TAG, GDEF_TAG, GSUB_TAG, MORT_TAG, MORX_TAG, KERN_TAG
};
const void *FontInstanceAdapter::getFontTable(LETag tableTag, size_t &length) const
{
length = 0;
if (!layoutTables) { // t1 font
return 0;
}
......@@ -75,14 +88,19 @@ const void *FontInstanceAdapter::getFontTable(LETag tableTag) const
// cache in font's pscaler object
// font disposer will handle for us
switch(tableTag) {
case GSUB_TAG: if (layoutTables->gsub_len != -1) return (void*)layoutTables->gsub; break;
case GPOS_TAG: if (layoutTables->gpos_len != -1) return (void*)layoutTables->gpos; break;
case GDEF_TAG: if (layoutTables->gdef_len != -1) return (void*)layoutTables->gdef; break;
case MORT_TAG: if (layoutTables->mort_len != -1) return (void*)layoutTables->mort; break;
case KERN_TAG: if (layoutTables->kern_len != -1) return (void*)layoutTables->kern; break;
default:
//fprintf(stderr, "unexpected table request from font instance adapter: %x\n", tableTag);
int cacheIdx;
for (cacheIdx=0;cacheIdx<LAYOUTCACHE_ENTRIES;cacheIdx++) {
if (tableTag==cacheMap[cacheIdx]) break;
}
if (cacheIdx<LAYOUTCACHE_ENTRIES) { // if found
if (layoutTables->entries[cacheIdx].len != -1) {
length = layoutTables->entries[cacheIdx].len;
return layoutTables->entries[cacheIdx].ptr;
}
} else {
//fprintf(stderr, "unexpected table request from font instance adapter: %x\n", tableTag);
// (don't load any other tables)
return 0;
}
......@@ -96,16 +114,13 @@ const void *FontInstanceAdapter::getFontTable(LETag tableTag) const
env->GetByteArrayRegion(tableBytes, 0, len, result);
}
switch(tableTag) {
case GSUB_TAG: layoutTables->gsub = (void*)result; layoutTables->gsub_len = len; break;
case GPOS_TAG: layoutTables->gpos = (void*)result; layoutTables->gpos_len = len; break;
case GDEF_TAG: layoutTables->gdef = (void*)result; layoutTables->gdef_len = len; break;
case MORT_TAG: layoutTables->mort = (void*)result; layoutTables->mort_len = len; break;
case KERN_TAG: layoutTables->kern = (void*)result; layoutTables->kern_len = len; break;
default: break;
if (cacheIdx<LAYOUTCACHE_ENTRIES) { // if cacheable table
layoutTables->entries[cacheIdx].len = len;
layoutTables->entries[cacheIdx].ptr = (const void*)result;
}
return (void*)result;
length = len;
return (const void*)result;
};
LEGlyphID FontInstanceAdapter::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
......
......@@ -86,6 +86,7 @@ public:
// tables are cached with the native font scaler data
// only supports gsub, gpos, gdef, mort tables at present
virtual const void *getFontTable(LETag tableTag) const;
virtual const void *getFontTable(LETag tableTag, size_t &len) const;
virtual void *getKernPairs() const {
return layoutTables->kernPairs;
......
......@@ -120,20 +120,19 @@ typedef struct GlyphInfo {
#define GPOS_TAG 0x47504F53 /* 'GPOS' */
#define GDEF_TAG 0x47444546 /* 'GDEF' */
#define MORT_TAG 0x6D6F7274 /* 'mort' */
#define MORX_TAG 0x6D6F7278 /* 'morx' */
#define KERN_TAG 0x6B65726E /* 'kern' */
typedef struct TTLayoutTableCacheEntry {
const void* ptr;
int len;
} TTLayoutTableCacheEntry;
#define LAYOUTCACHE_ENTRIES 6
typedef struct TTLayoutTableCache {
void* gsub;
void* gpos;
void* gdef;
void* mort;
void* kern;
void* kernPairs;
int gsub_len;
int gpos_len;
int gdef_len;
int mort_len;
int kern_len;
TTLayoutTableCacheEntry entries[LAYOUTCACHE_ENTRIES];
void* kernPairs;
} TTLayoutTableCache;
#include "sunfontids.h"
......
......@@ -39,19 +39,20 @@
U_NAMESPACE_BEGIN
le_uint32 AlternateSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSubstitutionSubtable> &base,
GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
{
// NOTE: For now, we'll just pick the first alternative...
LEGlyphID glyph = glyphIterator->getCurrGlyphID();
le_int32 coverageIndex = getGlyphCoverage(glyph);
le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
if (coverageIndex >= 0) {
if (coverageIndex >= 0 && LE_SUCCESS(success)) {
le_uint16 altSetCount = SWAPW(alternateSetCount);
if (coverageIndex < altSetCount) {
Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]);
const AlternateSetTable *alternateSetTable =
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset);
const LEReferenceTo<AlternateSetTable> alternateSetTable(base, success,
(const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]);
if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
......
......@@ -51,13 +51,17 @@ struct AlternateSetTable
TTGlyphID alternateArray[ANY_NUMBER];
};
LE_VAR_ARRAY(AlternateSetTable, alternateArray)
struct AlternateSubstitutionSubtable : GlyphSubstitutionSubtable
{
le_uint16 alternateSetCount;
Offset alternateSetTableOffsetArray[ANY_NUMBER];
le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const;
le_uint32 process(const LEReferenceTo<AlternateSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
};
LE_VAR_ARRAY(AlternateSubstitutionSubtable, alternateSetTableOffsetArray)
U_NAMESPACE_END
#endif
......@@ -26,7 +26,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
......@@ -58,15 +58,18 @@ le_bool CharSubstitutionFilter::accept(LEGlyphID glyph) const
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
le_int32 languageCode, le_int32 typoFlags,
const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable,
LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
{
fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
fFeatureOrder = TRUE;
}
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
le_int32 languageCode,
le_int32 typoFlags, LEErrorCode &success)
: OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
{
......@@ -88,8 +91,9 @@ ArabicOpenTypeLayoutEngine::~ArabicOpenTypeLayoutEngine()
// Input: characters
// Output: characters, char indices, tags
// Returns: output character count
le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count,
le_int32 max, le_bool rightToLeft, LEUnicode *&outChars,
LEGlyphStorage &glyphStorage, LEErrorCode &success)
{
if (LE_FAILURE(success)) {
return 0;
......@@ -137,32 +141,30 @@ void ArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode chars[], l
return;
}
if (fGPOSTable != NULL) {
if (!fGPOSTable.isEmpty()) {
OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
} else if (fGDEFTable != NULL) {
GDEFMarkFilter filter(fGDEFTable);
} else if (!fGDEFTable.isEmpty()) {
GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(glyphStorage, &filter, success);
} else {
GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
GDEFMarkFilter filter(gdefTable);
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
GDEFMarkFilter filter(gdefTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
}
}
UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
: ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
{
fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
/* OpenTypeLayoutEngine will allocate a substitution filter */
}
UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
{
delete fSubstitutionFilter;
/* OpenTypeLayoutEngine will cleanup the substitution filter */
}
// "glyphs", "indices" -> glyphs, indices
......@@ -233,7 +235,7 @@ void UnicodeArabicOpenTypeLayoutEngine::adjustGlyphPositions(const LEUnicode cha
return;
}
GDEFMarkFilter filter(fGDEFTable);
GDEFMarkFilter filter(fGDEFTable, success);
adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
}
......
......@@ -75,7 +75,7 @@ public:
* @internal
*/
ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
/**
* This constructor is used when the font requires a "canned" GSUB table which can't be known
......
......@@ -58,14 +58,16 @@ const ArabicShaping::ShapeType ArabicShaping::shapeTypes[] =
*/
ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
{
const ClassDefinitionTable *joiningTypes = (const ClassDefinitionTable *) ArabicShaping::shapingTypeTable;
le_int32 joiningType = joiningTypes->getGlyphClass(c);
LEErrorCode success = LE_NO_ERROR;
const LEReferenceTo<ClassDefinitionTable> joiningTypes((const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
ArabicShaping::shapingTypeTableLen);
le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success);
if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT) {
return ArabicShaping::shapeTypes[joiningType];
}
if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT && LE_SUCCESS(success)) {
return ArabicShaping::shapeTypes[joiningType];
}
return ArabicShaping::ST_NOSHAPE_NONE;
return ArabicShaping::ST_NOSHAPE_NONE;
}
#define isolFeatureTag LE_ISOL_FEATURE_TAG
......
......@@ -93,6 +93,8 @@ private:
static ShapeType getShapeType(LEUnicode c);
static const le_uint8 shapingTypeTable[];
static const size_t shapingTypeTableLen;
static const ShapeType shapeTypes[];
static void adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage);
......
......@@ -52,14 +52,14 @@ struct AttachmentPositioningSubtable : GlyphPositioningSubtable
Offset markArrayOffset;
Offset baseArrayOffset;
inline le_int32 getBaseCoverage(LEGlyphID baseGlyphId) const;
inline le_int32 getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphId, LEErrorCode &success) const;
le_uint32 process(GlyphIterator *glyphIterator) const;
};
inline le_int32 AttachmentPositioningSubtable::getBaseCoverage(LEGlyphID baseGlyphID) const
inline le_int32 AttachmentPositioningSubtable::getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphID, LEErrorCode &success) const
{
return getGlyphCoverage(baseCoverageTableOffset, baseGlyphID);
return getGlyphCoverage(base, baseCoverageTableOffset, baseGlyphID, success);
}
U_NAMESPACE_END
......
......@@ -3641,4 +3641,9 @@ const le_uint8 CanonShaping::glyphDefinitionTable[] = {
0x00, 0xE6, 0xD2, 0x42, 0xD2, 0x44, 0x00, 0xE6
};
const size_t CanonShaping::glyphSubstitutionTableLen = sizeof(glyphSubstitutionTable)/sizeof(glyphSubstitutionTable[0]);
const size_t CanonShaping::glyphDefinitionTableLen = sizeof(glyphDefinitionTable)/sizeof(glyphDefinitionTable[0]);
U_NAMESPACE_END
......@@ -59,15 +59,15 @@ void CanonShaping::sortMarks(le_int32 *indices, const le_int32 *combiningClasses
void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
LEUnicode *outChars, LEGlyphStorage &glyphStorage)
{
const GlyphDefinitionTableHeader *gdefTable = (const GlyphDefinitionTableHeader *) glyphDefinitionTable;
const ClassDefinitionTable *classTable = gdefTable->getMarkAttachClassDefinitionTable();
LEErrorCode success = LE_NO_ERROR;
LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success);
le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
LEErrorCode status = LE_NO_ERROR;
le_int32 i;
for (i = 0; i < charCount; i += 1) {
combiningClasses[i] = classTable->getGlyphClass((LEGlyphID) inChars[i]);
combiningClasses[i] = classTable->getGlyphClass(classTable, (LEGlyphID) inChars[i], success);
indices[i] = i;
}
......@@ -96,7 +96,7 @@ void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le
le_int32 index = indices[i];
outChars[i] = inChars[index];
glyphStorage.setCharIndex(out, index, status);
glyphStorage.setCharIndex(out, index, success);
}
LE_DELETE_ARRAY(indices);
......
......@@ -42,7 +42,9 @@ class U_LAYOUT_API CanonShaping /* not : public UObject because all members are
{
public:
static const le_uint8 glyphSubstitutionTable[];
static const size_t glyphSubstitutionTableLen;
static const le_uint8 glyphDefinitionTable[];
static const size_t glyphDefinitionTableLen;
static void reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
LEUnicode *outChars, LEGlyphStorage &glyphStorage);
......
......@@ -37,49 +37,51 @@
U_NAMESPACE_BEGIN
le_int32 ClassDefinitionTable::getGlyphClass(LEGlyphID glyphID) const
le_int32 ClassDefinitionTable::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
{
switch(SWAPW(classFormat)) {
LEReferenceTo<ClassDefinitionTable> thisRef(base, success);
if (LE_FAILURE(success)) return 0;
switch(SWAPW(classFormat)) {
case 0:
return 0;
case 1:
{
const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this;
return f1Table->getGlyphClass(glyphID);
const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
return f1Table->getGlyphClass(f1Table, glyphID, success);
}
case 2:
{
const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this;
return f2Table->getGlyphClass(glyphID);
const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
return f2Table->getGlyphClass(f2Table, glyphID, success);
}
default:
return 0;
}
}
}
le_bool ClassDefinitionTable::hasGlyphClass(le_int32 glyphClass) const
le_bool ClassDefinitionTable::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
{
LEReferenceTo<ClassDefinitionTable> thisRef(base, success);
if (LE_FAILURE(success)) return 0;
switch(SWAPW(classFormat)) {
case 0:
return 0;
case 1:
{
const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this;
return f1Table->hasGlyphClass(glyphClass);
const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
return f1Table->hasGlyphClass(f1Table, glyphClass, success);
}
case 2:
{
const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this;
return f2Table->hasGlyphClass(glyphClass);
const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
return f2Table->hasGlyphClass(f2Table, glyphClass, success);
}
default:
......@@ -87,26 +89,32 @@ le_bool ClassDefinitionTable::hasGlyphClass(le_int32 glyphClass) const
}
}
le_int32 ClassDefFormat1Table::getGlyphClass(LEGlyphID glyphID) const
le_int32 ClassDefFormat1Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
{
if(LE_FAILURE(success)) return 0;
le_uint16 count = SWAPW(glyphCount);
LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count);
TTGlyphID ttGlyphID = (TTGlyphID) LE_GET_GLYPH(glyphID);
TTGlyphID firstGlyph = SWAPW(startGlyph);
TTGlyphID lastGlyph = firstGlyph + SWAPW(glyphCount);
TTGlyphID lastGlyph = firstGlyph + count;
if (ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
return SWAPW(classValueArray[ttGlyphID - firstGlyph]);
if (LE_SUCCESS(success) && ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
return SWAPW( classValueArrayRef(ttGlyphID - firstGlyph, success) );
}
return 0;
}
le_bool ClassDefFormat1Table::hasGlyphClass(le_int32 glyphClass) const
le_bool ClassDefFormat1Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
{
le_uint16 count = SWAPW(glyphCount);
if(LE_FAILURE(success)) return 0;
le_uint16 count = SWAPW(glyphCount);
LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count);
int i;
for (i = 0; i < count; i += 1) {
if (SWAPW(classValueArray[i]) == glyphClass) {
for (i = 0; LE_SUCCESS(success)&& (i < count); i += 1) {
if (SWAPW(classValueArrayRef(i,success)) == glyphClass) {
return TRUE;
}
}
......@@ -114,27 +122,31 @@ le_bool ClassDefFormat1Table::hasGlyphClass(le_int32 glyphClass) const
return FALSE;
}
le_int32 ClassDefFormat2Table::getGlyphClass(LEGlyphID glyphID) const
le_int32 ClassDefFormat2Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
{
if(LE_FAILURE(success)) return 0;
TTGlyphID ttGlyph = (TTGlyphID) LE_GET_GLYPH(glyphID);
le_uint16 rangeCount = SWAPW(classRangeCount);
LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
le_int32 rangeIndex =
OpenTypeUtilities::getGlyphRangeIndex(ttGlyph, classRangeRecordArray, rangeCount);
OpenTypeUtilities::getGlyphRangeIndex(ttGlyph, classRangeRecordArrayRef, success);
if (rangeIndex < 0) {
if (rangeIndex < 0 || LE_FAILURE(success)) {
return 0;
}
return SWAPW(classRangeRecordArray[rangeIndex].rangeValue);
return SWAPW(classRangeRecordArrayRef(rangeIndex, success).rangeValue);
}
le_bool ClassDefFormat2Table::hasGlyphClass(le_int32 glyphClass) const
le_bool ClassDefFormat2Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
{
if(LE_FAILURE(success)) return 0;
le_uint16 rangeCount = SWAPW(classRangeCount);
LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
int i;
for (i = 0; i < rangeCount; i += 1) {
if (SWAPW(classRangeRecordArray[i].rangeValue) == glyphClass) {
for (i = 0; i < rangeCount && LE_SUCCESS(success); i += 1) {
if (SWAPW(classRangeRecordArrayRef(i,success).rangeValue) == glyphClass) {
return TRUE;
}
}
......
......@@ -46,8 +46,20 @@ struct ClassDefinitionTable
{
le_uint16 classFormat;
le_int32 getGlyphClass(LEGlyphID glyphID) const;
le_bool hasGlyphClass(le_int32 glyphClass) const;
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
le_int32 getGlyphClass(LEGlyphID glyphID) const {
LETableReference base((const le_uint8*)this);
LEErrorCode ignored = LE_NO_ERROR;
return getGlyphClass(base,glyphID,ignored);
}
le_bool hasGlyphClass(le_int32 glyphClass) const {
LETableReference base((const le_uint8*)this);
LEErrorCode ignored = LE_NO_ERROR;
return hasGlyphClass(base,glyphClass,ignored);
}
};
struct ClassDefFormat1Table : ClassDefinitionTable
......@@ -56,9 +68,11 @@ struct ClassDefFormat1Table : ClassDefinitionTable
le_uint16 glyphCount;
le_uint16 classValueArray[ANY_NUMBER];
le_int32 getGlyphClass(LEGlyphID glyphID) const;
le_bool hasGlyphClass(le_int32 glyphClass) const;
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
};
LE_VAR_ARRAY(ClassDefFormat1Table, classValueArray)
struct ClassRangeRecord
{
......@@ -72,9 +86,10 @@ struct ClassDefFormat2Table : ClassDefinitionTable
le_uint16 classRangeCount;
GlyphRangeRecord classRangeRecordArray[ANY_NUMBER];
le_int32 getGlyphClass(LEGlyphID glyphID) const;
le_bool hasGlyphClass(le_int32 glyphClass) const;
le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
};
LE_VAR_ARRAY(ClassDefFormat2Table, classRangeRecordArray)
U_NAMESPACE_END
#endif
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
......@@ -49,6 +49,11 @@ struct ContextualGlyphInsertionHeader : MorphStateTableHeader
{
};
struct ContextualGlyphInsertionHeader2 : MorphStateTableHeader2
{
le_uint32 insertionTableOffset;
};
enum ContextualGlyphInsertionFlags
{
cgiSetMark = 0x8000,
......@@ -61,11 +66,17 @@ enum ContextualGlyphInsertionFlags
cgiMarkedInsertCountMask = 0x001F
};
struct LigatureSubstitutionStateEntry : StateEntry
struct ContextualGlyphInsertionStateEntry : StateEntry
{
ByteOffset currentInsertionListOffset;
ByteOffset markedInsertionListOffset;
};
struct ContextualGlyphInsertionStateEntry2 : StateEntry2
{
le_uint16 currentInsertionListIndex;
le_uint16 markedInsertionListIndex;
};
U_NAMESPACE_END
#endif
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
*
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
*
*/
#include "LETypes.h"
#include "MorphTables.h"
#include "StateTables.h"
#include "MorphStateTables.h"
#include "SubtableProcessor2.h"
#include "StateTableProcessor2.h"
#include "ContextualGlyphInsertionProc2.h"
#include "LEGlyphStorage.h"
#include "LESwaps.h"
U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)
ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(
const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor2(morphSubtableHeader, success)
{
contextualGlyphHeader = LEReferenceTo<ContextualGlyphInsertionHeader2>(morphSubtableHeader, success);
if(LE_FAILURE(success) || !contextualGlyphHeader.isValid()) return;
le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
insertionTable = LEReferenceToArrayOf<le_uint16>(stHeader, success, insertionTableOffset, LE_UNBOUNDED_ARRAY);
entryTable = LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
}
ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2()
{
}
void ContextualGlyphInsertionProcessor2::beginStateTable()
{
markGlyph = 0;
}
void ContextualGlyphInsertionProcessor2::doInsertion(LEGlyphStorage &glyphStorage,
le_int16 atGlyph,
le_int16 &index,
le_int16 count,
le_bool /* isKashidaLike */,
le_bool isBefore,
LEErrorCode &success) {
LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(atGlyph, count + 1, success);
if(LE_FAILURE(success) || insertGlyphs==NULL) {
return;
}
// Note: Kashida vs Split Vowel seems to only affect selection and highlighting.
// We note the flag, but do not layout different.
// https://developer.apple.com/fonts/TTRefMan/RM06/Chap6mort.html
le_int16 targetIndex = 0;
if(isBefore) {
// insert at beginning
insertGlyphs[targetIndex++] = glyphStorage[atGlyph];
} else {
// insert at end
insertGlyphs[count] = glyphStorage[atGlyph];
}
while(count--) {
insertGlyphs[targetIndex++] = insertionTable.getObject(index++, success);
}
glyphStorage.applyInsertions();
}
le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
EntryTableIndex2 index, LEErrorCode &success)
{
const ContextualGlyphInsertionStateEntry2 *entry = entryTable.getAlias(index, success);
if(LE_FAILURE(success)) return 0; // TODO- which state?
le_uint16 newState = SWAPW(entry->newStateIndex);
le_uint16 flags = SWAPW(entry->flags);
le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
if (markIndex > 0) {
le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
le_bool isBefore = (flags & cgiMarkInsertBefore);
doInsertion(glyphStorage, markGlyph, markIndex, count, isKashidaLike, isBefore, success);
}
le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
if (currIndex > 0) {
le_int16 count = flags & cgiCurrentInsertCountMask;
le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
le_bool isBefore = (flags & cgiCurrentInsertBefore);
doInsertion(glyphStorage, currGlyph, currIndex, count, isKashidaLike, isBefore, success);
}
if (flags & cgiSetMark) {
markGlyph = currGlyph;
}
if (!(flags & cgiDontAdvance)) {
currGlyph += dir;
}
return newState;
}
void ContextualGlyphInsertionProcessor2::endStateTable()
{
}
U_NAMESPACE_END
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
*
* (C) Copyright IBM Corp. and others 2013 - All Rights Reserved
*
*/
#ifndef __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H
#define __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H
/**
* \file
* \internal
*/
#include "LETypes.h"
#include "MorphTables.h"
#include "SubtableProcessor2.h"
#include "StateTableProcessor2.h"
#include "ContextualGlyphInsertionProc2.h"
#include "ContextualGlyphInsertion.h"
U_NAMESPACE_BEGIN
class LEGlyphStorage;
class ContextualGlyphInsertionProcessor2 : public StateTableProcessor2
{
public:
virtual void beginStateTable();
virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage,
le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
virtual void endStateTable();
ContextualGlyphInsertionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
virtual ~ContextualGlyphInsertionProcessor2();
/**
* ICU "poor man's RTTI", returns a UClassID for the actual class.
*
* @stable ICU 2.8
*/
virtual UClassID getDynamicClassID() const;
/**
* ICU "poor man's RTTI", returns a UClassID for this class.
*
* @stable ICU 2.8
*/
static UClassID getStaticClassID();
private:
ContextualGlyphInsertionProcessor2();
/**
* Perform the actual insertion
* @param atGlyph index of glyph to insert at
* @param index index into the insertionTable (in/out)
* @param count number of insertions
* @param isKashidaLike Kashida like (vs Split Vowel like). No effect currently.
* @param isBefore if true, insert extra glyphs before the marked glyph
*/
void doInsertion(LEGlyphStorage &glyphStorage,
le_int16 atGlyph,
le_int16 &index,
le_int16 count,
le_bool isKashidaLike,
le_bool isBefore,
LEErrorCode &success);
protected:
le_int32 markGlyph;
LEReferenceToArrayOf<le_uint16> insertionTable;
LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2> entryTable;
LEReferenceTo<ContextualGlyphInsertionHeader2> contextualGlyphHeader;
};
U_NAMESPACE_END
#endif
......@@ -43,13 +43,18 @@ U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor)
ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader)
: StateTableProcessor(morphSubtableHeader)
ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success)
{
contextualGlyphSubstitutionHeader = (const ContextualGlyphSubstitutionHeader *) morphSubtableHeader;
substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
contextualGlyphSubstitutionHeader.orphan();
substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
entryTable = (const ContextualGlyphSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
entryTable = LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry>(stateTableHeader, success,
(const ContextualGlyphSubstitutionStateEntry*)(&stateTableHeader->stHeader),
entryTableOffset, LE_UNBOUNDED_ARRAY);
int16Table = LEReferenceToArrayOf<le_int16>(stateTableHeader, success, (const le_int16*)(&stateTableHeader->stHeader),
0, LE_UNBOUNDED_ARRAY); // rest of the table as le_int16s
}
ContextualGlyphSubstitutionProcessor::~ContextualGlyphSubstitutionProcessor()
......@@ -63,27 +68,26 @@ void ContextualGlyphSubstitutionProcessor::beginStateTable()
ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
{
const ContextualGlyphSubstitutionStateEntry *entry = &entryTable[index];
ByteOffset newState = SWAPW(entry->newStateOffset);
le_int16 flags = SWAPW(entry->flags);
WordOffset markOffset = SWAPW(entry->markOffset);
WordOffset currOffset = SWAPW(entry->currOffset);
if (markOffset != 0) {
const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + markOffset * 2);
LEGlyphID mGlyph = glyphStorage[markGlyph];
TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(mGlyph)]);
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
}
if (currOffset != 0) {
const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + currOffset * 2);
LEGlyphID thisGlyph = glyphStorage[currGlyph];
TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(thisGlyph)]);
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
}
LEErrorCode success = LE_NO_ERROR;
const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
ByteOffset newState = SWAPW(entry->newStateOffset);
le_int16 flags = SWAPW(entry->flags);
WordOffset markOffset = SWAPW(entry->markOffset);
WordOffset currOffset = SWAPW(entry->currOffset);
if (markOffset != 0 && LE_SUCCESS(success)) {
LEGlyphID mGlyph = glyphStorage[markGlyph];
TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew.
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
}
if (currOffset != 0) {
LEGlyphID thisGlyph = glyphStorage[currGlyph];
TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew.
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
}
if (flags & cgsSetMark) {
markGlyph = currGlyph;
......
......@@ -56,7 +56,7 @@ public:
virtual void endStateTable();
ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader);
ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
virtual ~ContextualGlyphSubstitutionProcessor();
/**
......@@ -78,11 +78,11 @@ private:
protected:
ByteOffset substitutionTableOffset;
const ContextualGlyphSubstitutionStateEntry *entryTable;
LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry> entryTable;
LEReferenceToArrayOf<le_int16> int16Table;
le_int32 markGlyph;
const ContextualGlyphSubstitutionHeader *contextualGlyphSubstitutionHeader;
LEReferenceTo<ContextualGlyphSubstitutionHeader> contextualGlyphSubstitutionHeader;
};
......
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
/*
*
* (C) Copyright IBM Corp. and others 1998-2013 - All Rights Reserved
*
*/
#include "LETypes.h"
#include "MorphTables.h"
#include "StateTables.h"
#include "MorphStateTables.h"
#include "SubtableProcessor2.h"
#include "StateTableProcessor2.h"
#include "ContextualGlyphSubstProc2.h"
#include "LEGlyphStorage.h"
#include "LESwaps.h"
U_NAMESPACE_BEGIN
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2)
ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(
const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor2(morphSubtableHeader, success), contextualGlyphHeader(morphSubtableHeader, success)
{
if(LE_FAILURE(success)) return;
le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset);
perGlyphTable = LEReferenceToArrayOf<le_uint32> (stHeader, success, perGlyphTableOffset, LE_UNBOUNDED_ARRAY);
entryTable = LEReferenceToArrayOf<ContextualGlyphStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
}
ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2()
{
}
void ContextualGlyphSubstitutionProcessor2::beginStateTable()
{
markGlyph = 0;
}
le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
EntryTableIndex2 index, LEErrorCode &success)
{
if(LE_FAILURE(success)) return 0;
const ContextualGlyphStateEntry2 *entry = entryTable.getAlias(index, success);
if(LE_FAILURE(success)) return 0;
le_uint16 newState = SWAPW(entry->newStateIndex);
le_uint16 flags = SWAPW(entry->flags);
le_int16 markIndex = SWAPW(entry->markIndex);
le_int16 currIndex = SWAPW(entry->currIndex);
if (markIndex != -1) {
le_uint32 offset = SWAPL(perGlyphTable(markIndex, success));
LEGlyphID mGlyph = glyphStorage[markGlyph];
TTGlyphID newGlyph = lookup(offset, mGlyph, success);
glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
}
if (currIndex != -1) {
le_uint32 offset = SWAPL(perGlyphTable(currIndex, success));
LEGlyphID thisGlyph = glyphStorage[currGlyph];
TTGlyphID newGlyph = lookup(offset, thisGlyph, success);
glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
}
if (flags & cgsSetMark) {
markGlyph = currGlyph;
}
if (!(flags & cgsDontAdvance)) {
currGlyph += dir;
}
return newState;
}
TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success)
{
TTGlyphID newGlyph = 0xFFFF;
if(LE_FAILURE(success)) return newGlyph;
LEReferenceTo<LookupTable> lookupTable(perGlyphTable, success, offset);
if(LE_FAILURE(success)) return newGlyph;
le_int16 format = SWAPW(lookupTable->format);
switch (format) {
case ltfSimpleArray: {
#ifdef TEST_FORMAT
// Disabled pending for design review
LEReferenceTo<SimpleArrayLookupTable> lookupTable0(lookupTable, success);
LEReferenceToArrayOf<LookupValue> valueArray(lookupTable0, success, &lookupTable0->valueArray[0], LE_UNBOUNDED_ARRAY);
if(LE_FAILURE(success)) return newGlyph;
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
newGlyph = SWAPW(lookupTable0->valueArray(glyphCode, success));
#endif
break;
}
case ltfSegmentSingle: {
#ifdef TEST_FORMAT
// Disabled pending for design review
LEReferenceTo<SegmentSingleLookupTable> lookupTable2 = (SegmentSingleLookupTable *) lookupTable;
const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
if (segment != NULL) {
newGlyph = SWAPW(segment->value);
}
#endif
break;
}
case ltfSegmentArray: {
//printf("Context Lookup Table Format4: specific interpretation needed!\n");
break;
}
case ltfSingleTable:
{
#ifdef TEST_FORMAT
// Disabled pending for design review
LEReferenceTo<SingleTableLookupTable> lookupTable6 = (SingleTableLookupTable *) lookupTable;
const LEReferenceTo<LookupSingle> segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
if (segment != NULL) {
newGlyph = SWAPW(segment->value);
}
#endif
break;
}
case ltfTrimmedArray: {
LEReferenceTo<TrimmedArrayLookupTable> lookupTable8(lookupTable, success);
if (LE_FAILURE(success)) return newGlyph;
TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
TTGlyphID glyphCount = SWAPW(lookupTable8->glyphCount);
TTGlyphID lastGlyph = firstGlyph + glyphCount;
TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) {
LEReferenceToArrayOf<LookupValue> valueArray(lookupTable8, success, &lookupTable8->valueArray[0], glyphCount);
newGlyph = SWAPW(valueArray(glyphCode - firstGlyph, success));
}
}
default:
break;
}
return newGlyph;
}
void ContextualGlyphSubstitutionProcessor2::endStateTable()
{
}
U_NAMESPACE_END
......@@ -25,7 +25,7 @@
/*
*
* (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
* (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
*
*/
......@@ -49,6 +49,11 @@ struct ContextualGlyphSubstitutionHeader : MorphStateTableHeader
ByteOffset substitutionTableOffset;
};
struct ContextualGlyphHeader2 : MorphStateTableHeader2
{
le_uint32 perGlyphTableOffset; // no more substitution tables
};
enum ContextualGlyphSubstitutionFlags
{
cgsSetMark = 0x8000,
......@@ -62,5 +67,11 @@ struct ContextualGlyphSubstitutionStateEntry : StateEntry
WordOffset currOffset;
};
struct ContextualGlyphStateEntry2 : StateEntry2
{
le_uint16 markIndex;
le_uint16 currIndex;
};
U_NAMESPACE_END
#endif
......@@ -57,6 +57,7 @@ private:
static const le_uint16 fieldSignBits[];
static const le_uint16 fieldBits[];
};
LE_VAR_ARRAY(DeviceTable, deltaValues)
U_NAMESPACE_END
#endif
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册