mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-07-30 07:18:37 -09:00
Merge tag 'Ghidra_12.1.2_build' into stable
This commit is contained in:
@@ -1,3 +1,14 @@
|
||||
# Ghidra 12.1.2 Change History (June 2026)
|
||||
|
||||
### Improvements
|
||||
* _MachineLearning_. Upgraded the Machine Learning extension's olcut jars to 5.3.1. (GP-6894)
|
||||
* _Multi-User_. Data buffers transferred to and from a Ghidra Server are now compressed by default. The default was previously inconsistent for the two directions. (GP-6915)
|
||||
|
||||
### Bugs
|
||||
* _Decompiler_. Fixed infinite loop in Decompiler analysis that was triggered by bitfield data-types. (GP-6850, Issue #9185)
|
||||
* _Importer:ELF_. Improved ELF GNU Hash table bounds-checking to avoid potential hang. (GP-6887)
|
||||
* _Multi-User_. Corrected severe regression error with Ghidra Server 12.1.1 block-stream compression. (GP-6903)
|
||||
|
||||
# Ghidra 12.1.1 Change History (May 2026)
|
||||
|
||||
### Improvements
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
MODULE FILE LICENSE: lib/olcut-config-protobuf-5.2.0.jar BSD-2-ORACLE
|
||||
MODULE FILE LICENSE: lib/olcut-core-5.2.0.jar BSD-2-ORACLE
|
||||
MODULE FILE LICENSE: lib/olcut-config-protobuf-5.3.1.jar BSD-2-ORACLE
|
||||
MODULE FILE LICENSE: lib/olcut-core-5.3.1.jar BSD-2-ORACLE
|
||||
MODULE FILE LICENSE: lib/tribuo-classification-core-4.3.2.jar Apache License 2.0
|
||||
MODULE FILE LICENSE: lib/tribuo-classification-tree-4.3.2.jar Apache License 2.0
|
||||
MODULE FILE LICENSE: lib/tribuo-common-tree-4.3.2.jar Apache License 2.0
|
||||
|
||||
@@ -26,8 +26,8 @@ def protobufVersion = getProperty("ghidra.protobuf.java.version")
|
||||
dependencies {
|
||||
api project(':Base')
|
||||
|
||||
api "com.oracle.labs.olcut:olcut-config-protobuf:5.2.0" //{exclude group: "com.google.protobuf", module: "protobuf-java"}
|
||||
api ("com.oracle.labs.olcut:olcut-core:5.2.0") {exclude group: "org.jline"}
|
||||
api "com.oracle.labs.olcut:olcut-config-protobuf:5.3.1" //{exclude group: "com.google.protobuf", module: "protobuf-java"}
|
||||
api ("com.oracle.labs.olcut:olcut-core:5.3.1") {exclude group: "org.jline"}
|
||||
api "org.tribuo:tribuo-classification-core:4.3.2"
|
||||
api "org.tribuo:tribuo-classification-tree:4.3.2"
|
||||
api "org.tribuo:tribuo-common-tree:4.3.2"
|
||||
|
||||
@@ -697,7 +697,7 @@ public class ElfHeader implements StructConverter {
|
||||
// p_vaddr to find it relative to a PT_LOAD segment
|
||||
long vaddr = dynamicHeaders[0].getVirtualAddress();
|
||||
if (vaddr == 0 || dynamicHeaders[0].getFileSize() == 0) {
|
||||
Msg.warn(this, "ELF Dynamic table appears to have been stripped from binary");
|
||||
logError("ELF Dynamic table appears to have been stripped from binary");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -931,7 +931,7 @@ public class ElfHeader implements StructConverter {
|
||||
!dynamicTable.containsDynamicValue(ElfDynamicType.DT_SYMENT) ||
|
||||
dynamicHashType == null) {
|
||||
if (dynamicStringTable != null) {
|
||||
Msg.warn(this, "Failed to parse DT_SYMTAB, missing dynamic dependency");
|
||||
logError("Failed to parse DT_SYMTAB, missing dynamic dependency");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -1012,14 +1012,26 @@ public class ElfHeader implements StructConverter {
|
||||
private int deriveGnuHashDynamicSymbolCount(long gnuHashTableOffset) throws IOException {
|
||||
int numBuckets = reader.readInt(gnuHashTableOffset);
|
||||
int symbolBase = reader.readInt(gnuHashTableOffset + 4);
|
||||
int bloomSize = reader.readInt(gnuHashTableOffset + 8);
|
||||
long bloomSize = reader.readUnsignedInt(gnuHashTableOffset + 8);
|
||||
// int bloomShift = reader.readInt(gnuHashTableOffset + 12);
|
||||
int bloomWordSize = is64Bit() ? 8 : 4;
|
||||
long bloomWordSize = is64Bit() ? 8 : 4;
|
||||
long bucketsOffset = gnuHashTableOffset + 16 + (bloomWordSize * bloomSize);
|
||||
|
||||
|
||||
// Identify restricted region which contains GNU hash table (arbitrary min-length)
|
||||
long maxOffset = getMaxOffsetForLoadedRegionContaining(gnuHashTableOffset, 12);
|
||||
if (maxOffset <= 0) {
|
||||
logError("Failed to idenitify loaded GNU Hash table");
|
||||
return 0;
|
||||
}
|
||||
|
||||
long bucketOffset = bucketsOffset;
|
||||
int maxSymbolIndex = 0;
|
||||
for (int i = 0; i < numBuckets; i++) {
|
||||
if (bucketOffset < gnuHashTableOffset || bucketOffset > maxOffset) {
|
||||
logError("Error occured while inspecting GNU Hash table");
|
||||
return 0;
|
||||
}
|
||||
int symbolIndex = reader.readInt(bucketOffset);
|
||||
if (symbolIndex > maxSymbolIndex) {
|
||||
maxSymbolIndex = symbolIndex;
|
||||
@@ -1032,6 +1044,10 @@ public class ElfHeader implements StructConverter {
|
||||
++maxSymbolIndex;
|
||||
long chainOffset = bucketOffset + (4 * chainIndex); // chains immediately follow buckets
|
||||
while (true) {
|
||||
if (chainOffset < gnuHashTableOffset || chainOffset > maxOffset) {
|
||||
logError("Error occured while inspecting GNU Hash table");
|
||||
return 0;
|
||||
}
|
||||
int chainValue = reader.readInt(chainOffset);
|
||||
if ((chainValue & 1) != 0) {
|
||||
break;
|
||||
@@ -1042,6 +1058,25 @@ public class ElfHeader implements StructConverter {
|
||||
return maxSymbolIndex;
|
||||
}
|
||||
|
||||
private long getMaxOffsetForLoadedRegionContaining(long offset, long minSize) {
|
||||
long maxOffset = -1;
|
||||
if (e_shnum != 0) {
|
||||
ElfSectionHeader sectionContaining =
|
||||
getSectionHeaderContainingFileRange(offset, minSize);
|
||||
if (sectionContaining != null) {
|
||||
maxOffset = sectionContaining.getOffset() + sectionContaining.getSize() - 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ElfProgramHeader containingSegment =
|
||||
getProgramLoadHeaderContainingFileOffset(offset);
|
||||
if (containingSegment != null) {
|
||||
maxOffset = containingSegment.getOffset() + containingSegment.getFileSize() - 1;
|
||||
}
|
||||
}
|
||||
return maxOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk DT_GNU_XHASH table to determine dynamic symbol count
|
||||
* @param gnuHashTableOffset DT_GNU_XHASH table file offset
|
||||
@@ -1296,6 +1331,7 @@ public class ElfHeader implements StructConverter {
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
logError("Elf prelink read failure (see log)");
|
||||
Msg.error(this, "Elf prelink read failure", e);
|
||||
}
|
||||
return preLinkImageBase;
|
||||
|
||||
@@ -115,6 +115,15 @@ BitFieldTransform::BitFieldTransform(Funcdata *f,Datatype *dt,int4 off)
|
||||
isBigEndian = f->getArch()->getDefaultDataSpace()->isBigEndian();
|
||||
}
|
||||
|
||||
const vector<uint4> BitFieldInsertTransform::allowedFinalWrites = {
|
||||
CPUI_COPY, CPUI_INT_EQUAL, CPUI_INT_NOTEQUAL, CPUI_INT_SLESS, CPUI_INT_SLESSEQUAL,
|
||||
CPUI_INT_LESS, CPUI_INT_LESSEQUAL, CPUI_INT_ZEXT, CPUI_INT_SEXT, CPUI_INT_ADD, CPUI_INT_CARRY,
|
||||
CPUI_INT_SCARRY, CPUI_INT_XOR, CPUI_INT_AND, CPUI_INT_OR, CPUI_INT_LEFT, CPUI_INT_RIGHT,
|
||||
CPUI_INT_SRIGHT, CPUI_INT_MULT, CPUI_BOOL_NEGATE, CPUI_BOOL_XOR, CPUI_BOOL_AND, CPUI_BOOL_OR,
|
||||
CPUI_FLOAT_EQUAL, CPUI_FLOAT_NOTEQUAL, CPUI_FLOAT_LESS, CPUI_FLOAT_LESSEQUAL, CPUI_FLOAT_NAN,
|
||||
CPUI_SUBPIECE
|
||||
};
|
||||
|
||||
/// If the state is for a partial field whose storage location is overwritten
|
||||
/// later in the same basic block, return \b true
|
||||
/// \param state is the field
|
||||
@@ -794,10 +803,17 @@ BitFieldInsertTransform::BitFieldInsertTransform(Funcdata *f,PcodeOp *op,Datatyp
|
||||
outvn = op->getIn(0);
|
||||
if (!outvn->isWritten()) return;
|
||||
finalWriteOp = outvn->getDef(); // But use the op feeding the INDIRECT as the finalWriteOp
|
||||
if (!mappedVn->isAddrTied())
|
||||
return;
|
||||
// Check that op feeding INDIRECT is in the allowed list
|
||||
if (!binary_search(allowedFinalWrites.begin(),allowedFinalWrites.end(),finalWriteOp->code()))
|
||||
return;
|
||||
}
|
||||
else {
|
||||
outvn = finalWriteOp->getOut();
|
||||
mappedVn = outvn;
|
||||
if (!mappedVn->isAddrTied())
|
||||
return;
|
||||
}
|
||||
containerSize = outvn->getSize();
|
||||
originalValue = (Varnode *)0;
|
||||
@@ -1678,13 +1694,8 @@ int4 RuleBitFieldStore::applyOp(PcodeOp *op,Funcdata &data)
|
||||
void RuleBitFieldOut::getOpList(vector<uint4> &oplist) const
|
||||
|
||||
{
|
||||
uint4 list[]={ CPUI_COPY, CPUI_INT_EQUAL, CPUI_INT_NOTEQUAL, CPUI_INT_SLESS, CPUI_INT_SLESSEQUAL,
|
||||
CPUI_INT_LESS, CPUI_INT_LESSEQUAL, CPUI_INT_ZEXT, CPUI_INT_SEXT, CPUI_INT_ADD, CPUI_INT_CARRY,
|
||||
CPUI_INT_SCARRY, CPUI_INT_XOR, CPUI_INT_AND, CPUI_INT_OR, CPUI_INT_LEFT, CPUI_INT_RIGHT,
|
||||
CPUI_INT_SRIGHT, CPUI_INT_MULT, CPUI_BOOL_NEGATE, CPUI_BOOL_XOR, CPUI_BOOL_AND, CPUI_BOOL_OR,
|
||||
CPUI_FLOAT_EQUAL, CPUI_FLOAT_NOTEQUAL, CPUI_FLOAT_LESS, CPUI_FLOAT_LESSEQUAL, CPUI_FLOAT_NAN,
|
||||
CPUI_INDIRECT, CPUI_SUBPIECE };
|
||||
oplist.insert(oplist.end(),list,list+30);
|
||||
oplist.insert(oplist.end(),BitFieldInsertTransform::allowedFinalWrites.begin(),BitFieldInsertTransform::allowedFinalWrites.end());
|
||||
oplist.push_back(CPUI_INDIRECT);
|
||||
}
|
||||
|
||||
int4 RuleBitFieldOut::applyOp(PcodeOp *op,Funcdata &data)
|
||||
|
||||
@@ -112,6 +112,8 @@ public:
|
||||
BitFieldInsertTransform(Funcdata *f,PcodeOp *op,Datatype *dt,int4 off); ///< Construct from a terminating op
|
||||
bool doTrace(void); ///< Trace bitfields backward from the terminating op
|
||||
void apply(void); ///< Transform recovered expressions into INSERT operations
|
||||
|
||||
static const vector<uint4> allowedFinalWrites; ///< List of opcodes allowed for finalWriteOp (must be sorted)
|
||||
};
|
||||
|
||||
/// \brief Class that converts bitfield pull expressions into explicit ZPULL and SPULL operations
|
||||
|
||||
@@ -1806,18 +1806,16 @@ void RuleDoubleSub::getOpList(vector<uint4> &oplist) const
|
||||
int4 RuleDoubleSub::applyOp(PcodeOp *op,Funcdata &data)
|
||||
|
||||
{
|
||||
PcodeOp *op2;
|
||||
Varnode *vn;
|
||||
int4 offset1,offset2;
|
||||
|
||||
vn = op->getIn(0);
|
||||
Varnode *vn = op->getIn(0);
|
||||
if (!vn->isWritten()) return 0;
|
||||
op2 = vn->getDef();
|
||||
PcodeOp *op2 = vn->getDef();
|
||||
if (op2->code() != CPUI_SUBPIECE) return 0;
|
||||
offset1 = op->getIn(1)->getOffset();
|
||||
offset2 = op2->getIn(1)->getOffset();
|
||||
Varnode *inVn = op2->getIn(0);
|
||||
if (inVn->isFree()) return 0;
|
||||
int4 offset1 = op->getIn(1)->getOffset();
|
||||
int4 offset2 = op2->getIn(1)->getOffset();
|
||||
|
||||
data.opSetInput(op,op2->getIn(0),0); // Skip middleman
|
||||
data.opSetInput(op,inVn,0); // Skip middleman
|
||||
data.opSetInput(op,data.newConstant(4,offset1+offset2), 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -141,8 +141,14 @@ public class RemoteInputBlockStreamHandle extends RemoteBlockStreamHandle<InputB
|
||||
try (OutputStream out = getBlockInputStream(socket)) {
|
||||
|
||||
copyBlockData(inputBlockStream, out);
|
||||
|
||||
// Done with compressed stream, force compressed data to flush
|
||||
// before final handshake occurs
|
||||
if (out instanceof RemoteDeflaterOutputStream deflatorOut) {
|
||||
deflatorOut.finish();
|
||||
}
|
||||
|
||||
// perform final handshake before close (uncompressed)
|
||||
// Perform final handshake before close (uncompressed)
|
||||
writeStreamEnd(socket);
|
||||
readStreamEnd(socket, false);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class DataBuffer implements Buffer, Externalizable {
|
||||
"db.buffers.DataBuffer.compressedOutput";
|
||||
|
||||
private static boolean enableCompressedSerializationOutput =
|
||||
Boolean.parseBoolean(System.getProperty(COMPRESSED_SERIAL_OUTPUT_PROPERTY, "false"));
|
||||
Boolean.parseBoolean(System.getProperty(COMPRESSED_SERIAL_OUTPUT_PROPERTY, "true"));
|
||||
|
||||
public static void enableCompressedSerializationOutput(boolean enable) {
|
||||
System.setProperty(COMPRESSED_SERIAL_OUTPUT_PROPERTY, Boolean.toString(enable));
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@@ -15,12 +15,13 @@
|
||||
*/
|
||||
package db.buffers;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
@@ -35,6 +36,12 @@ public class DataBufferTest extends AbstractGenericTest {
|
||||
super();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
// restore default compression: enabled
|
||||
DataBuffer.enableCompressedSerializationOutput(true);
|
||||
}
|
||||
|
||||
private void transferData(boolean useRandomFill) throws Exception {
|
||||
|
||||
for (int k = 0; k < 20; k++) {
|
||||
|
||||
@@ -367,7 +367,7 @@ public abstract class LocalFolderItem implements FolderItem {
|
||||
File dataDir = getDataDir();
|
||||
File chkDir = new File(dataDir.getParentFile(), dataDir.getName() + ".delete");
|
||||
FileUtilities.deleteDir(chkDir);
|
||||
if (useDataDir && dataDir.exists() && !dataDir.renameTo(chkDir)) {
|
||||
if (dataDir.exists() && !dataDir.renameTo(chkDir)) {
|
||||
throw new FileInUseException(getName() + " is in use");
|
||||
}
|
||||
boolean success = false;
|
||||
@@ -380,15 +380,13 @@ public abstract class LocalFolderItem implements FolderItem {
|
||||
}
|
||||
finally {
|
||||
if (!success) {
|
||||
if (useDataDir && !dataDir.exists() && chkDir.exists() &&
|
||||
if (!dataDir.exists() && chkDir.exists() &&
|
||||
propertyFile.exists()) {
|
||||
chkDir.renameTo(dataDir);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (useDataDir) {
|
||||
FileUtilities.deleteDir(chkDir);
|
||||
}
|
||||
FileUtilities.deleteDir(chkDir);
|
||||
log("file deleted", user);
|
||||
}
|
||||
}
|
||||
@@ -785,13 +783,16 @@ public abstract class LocalFolderItem implements FolderItem {
|
||||
* Returns the appropriate instantiation of a LocalFolderItem
|
||||
* based upon a specified property file which resides within a
|
||||
* LocalFileSystem.
|
||||
* <p>
|
||||
* {@link LocalUnknownFolderItem} will be returned for unknown/unsupported content.
|
||||
*
|
||||
* @param fileSystem local file system which contains property file
|
||||
* @param propertyFile property file which identifies the folder item.
|
||||
* @return folder item
|
||||
* @return folder item or null if invalid item.
|
||||
*/
|
||||
static LocalFolderItem getFolderItem(LocalFileSystem fileSystem,
|
||||
ItemPropertyFile propertyFile) {
|
||||
int fileType = propertyFile.getInt(FILE_TYPE, UNKNOWN_FILE_TYPE);
|
||||
int fileType = propertyFile.getInt(FILE_TYPE, Integer.MIN_VALUE);
|
||||
try {
|
||||
if (fileType == DATAFILE_FILE_TYPE) {
|
||||
return new LocalDataFileItem(fileSystem, propertyFile);
|
||||
@@ -802,9 +803,15 @@ public abstract class LocalFolderItem implements FolderItem {
|
||||
else if (fileType == LINK_FILE_TYPE) {
|
||||
return new LocalTextDataItem(fileSystem, propertyFile);
|
||||
}
|
||||
else if (fileType == UNKNOWN_FILE_TYPE) {
|
||||
log.error("Folder item has unspecified file type: " + new File(
|
||||
else if (fileType == Integer.MIN_VALUE) {
|
||||
// Item not properly created and in bad state
|
||||
// Use badItem instance to remove all related storage
|
||||
LocalUnknownFolderItem badItem =
|
||||
new LocalUnknownFolderItem(fileSystem, propertyFile);
|
||||
badItem.delete(LATEST_VERSION, "REPAIR");
|
||||
log.error("Removing folder item with unspecified file type: " + new File(
|
||||
propertyFile.getParentStorageDirectory(), propertyFile.getStorageName()));
|
||||
return null; // triggers storage deallocation
|
||||
}
|
||||
else {
|
||||
log.error("Folder item has unsupported file type (" + fileType + "): " + new File(
|
||||
|
||||
@@ -95,9 +95,9 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener {
|
||||
private static final String SHOW_TOOLTIPS_OPTION_NAME = "Show Tooltips";
|
||||
private static final String BLINKING_CURSORS_OPTION_NAME = "Allow Blinking Cursors";
|
||||
|
||||
// TODO: Experimental Option !!
|
||||
private static final String ENABLE_COMPRESSED_DATABUFFER_OUTPUT =
|
||||
"Use DataBuffer Output Compression";
|
||||
private static final Boolean ENABLE_COMPRESSED_DATABUFFER_OUTPUT_DEFAULT = true;
|
||||
|
||||
private static final String RESTORE_PREVIOUS_PROJECT_NAME = "Restore Previous Project";
|
||||
private boolean shouldRestorePreviousProject;
|
||||
@@ -356,7 +356,8 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener {
|
||||
|
||||
options.registerOption(SHOW_TOOLTIPS_OPTION_NAME, true, help,
|
||||
"Controls the display of tooltip popup windows.");
|
||||
options.registerOption(ENABLE_COMPRESSED_DATABUFFER_OUTPUT, false, help,
|
||||
options.registerOption(ENABLE_COMPRESSED_DATABUFFER_OUTPUT,
|
||||
ENABLE_COMPRESSED_DATABUFFER_OUTPUT_DEFAULT, help,
|
||||
"When enabled data buffers sent to Ghidra Server are compressed (see server " +
|
||||
"configuration for other direction)");
|
||||
|
||||
@@ -381,7 +382,8 @@ public class FrontEndTool extends PluginTool implements OptionsChangeListener {
|
||||
DockingUtils.setGlobalTooltipEnabledOption(showToolTips);
|
||||
|
||||
boolean compressDataBuffers =
|
||||
options.getBoolean(ENABLE_COMPRESSED_DATABUFFER_OUTPUT, false);
|
||||
options.getBoolean(ENABLE_COMPRESSED_DATABUFFER_OUTPUT,
|
||||
ENABLE_COMPRESSED_DATABUFFER_OUTPUT_DEFAULT);
|
||||
DataBuffer.enableCompressedSerializationOutput(compressDataBuffers);
|
||||
|
||||
shouldRestorePreviousProject = options.getBoolean(RESTORE_PREVIOUS_PROJECT_NAME, true);
|
||||
|
||||
@@ -29,6 +29,7 @@ import javax.rmi.ssl.SslRMIClientSocketFactory;
|
||||
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
|
||||
import db.buffers.DataBuffer;
|
||||
import generic.hash.HashUtilities;
|
||||
import generic.test.*;
|
||||
import ghidra.framework.Application;
|
||||
@@ -92,6 +93,8 @@ public class ServerTestUtil {
|
||||
|
||||
private static final int SERVER_STARTUP_MAXWAIT_MS = 20000;
|
||||
|
||||
public static boolean enableCompressionOnServerStart = true;
|
||||
|
||||
private static IOThread cmdOut;
|
||||
private static IOThread cmdErr;
|
||||
private static Process serverProcess;
|
||||
@@ -413,6 +416,9 @@ public class ServerTestUtil {
|
||||
boolean enableAltLoginName, boolean enableSSHAuthentication,
|
||||
boolean enableAnonymousAuthentication) throws IOException {
|
||||
|
||||
// Set client-side compression to match server
|
||||
DataBuffer.enableCompressedSerializationOutput(enableCompressionOnServerStart);
|
||||
|
||||
if (port == 0) {
|
||||
port = GHIDRA_TEST_SERVER_PORT;
|
||||
}
|
||||
@@ -442,6 +448,7 @@ public class ServerTestUtil {
|
||||
argList.add("-Xdebug");
|
||||
argList.add("-Xnoagent");
|
||||
argList.add("-Djava.compiler=NONE");
|
||||
argList.add("-Ddb.buffers.DataBuffer.compressedOutput=" + enableCompressionOnServerStart);
|
||||
argList.add("-D" + DefaultTrustManagerFactory.GHIDRA_CACERTS_PATH_PROPERTY + "=" +
|
||||
getTestPkiCACertsPath());
|
||||
argList.add("-D" + DefaultKeyManagerFactory.KEYSTORE_PATH_PROPERTY + "=" +
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
application.name=Ghidra
|
||||
application.version=12.1.1
|
||||
application.version=12.1.2
|
||||
application.release.name=DEV
|
||||
application.layout.version=3
|
||||
application.gradle.min=8.5
|
||||
|
||||
Reference in New Issue
Block a user