Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public enum ShowPackageConfiguration {

INSTANCE;

private static final String TOOL_VERSION = "v2.3.0";
private static final String TOOL_VERSION = "v2.3.1";
private static final String TAR_SUFFIX = ".tar.gz";
private static final String LOG_SUFFIX = ".elg";
private static final String PREFIX = "show_package-";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.checkpoint.mgmt_api.utils.TarGZUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import com.checkpoint.mgmt_api.utils.FileNameUtils;

import java.io.FileNotFoundException;
import java.io.IOException;
Expand Down Expand Up @@ -765,7 +766,8 @@ private static Layer aggregatePackageLayers(String packageName, List<Layer> acce
}
configuration.getLogger().debug("Found nat layer in package: '" + packageName + "'");
natLayer.setDomainType(domain.get("domain-type").toString());
natLayer.setHtmlFileName(packageName + " " + natLayer.getName() + "-" + natLayer.getDomain() + ".html");
String baseFileName = packageName + " " + natLayer.getName() + "-" + natLayer.getDomain();
natLayer.setHtmlFileName(FileNameUtils.sanitizeFileName(baseFileName) + ".html");
}
}
return natLayer;
Expand Down Expand Up @@ -1338,7 +1340,8 @@ private static Layer createNewLayer(JSONObject layerInfo){
layer.setDomain("Management server");
}
layer.setDomainType(((JSONObject) layerInfo.get("domain")).get("domain-type").toString());
layer.setHtmlFileName(layer.getName() + "-" + layer.getDomain() + ".html");
String baseFileName = layer.getName() + "-" + layer.getDomain();
layer.setHtmlFileName(FileNameUtils.sanitizeFileName(baseFileName) + ".html");

return layer;
}
Expand Down
84 changes: 84 additions & 0 deletions src/main/java/com/checkpoint/mgmt_api/utils/FileNameUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.checkpoint.mgmt_api.utils;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
* Utility class for filename sanitization to prevent "File name too long" filesystem errors.
* Provides cross-platform compatible filename handling with length limits and character filtering.
*/
public class FileNameUtils {

// Maximum filename length (excluding path and extension) to ensure compatibility across filesystems
// Linux supports up to 255, Windows up to 260, but we use a conservative limit for safety
private static final int MAX_FILENAME_LENGTH = 200;
// Maximum length for the truncated portion before adding hash
private static final int MAX_TRUNCATED_LENGTH = 150;

/**
* Sanitizes a filename to ensure it doesn't exceed filesystem limits.
* If the filename is too long, it truncates the name and adds a hash suffix for uniqueness.
*
* This method handles cross-platform filename restrictions:
* - Removes/replaces invalid characters for both Windows and Linux
* - Enforces length limits compatible with most filesystems
*
* @param baseFileName the original filename (without extension)
* @return sanitized filename that fits within filesystem limits
*/
public static String sanitizeFileName(String baseFileName) {
if (baseFileName == null || baseFileName.isEmpty()) {
return "unnamed";
}

// Remove or replace invalid filename characters for cross-platform compatibility
// Linux is more permissive, but we sanitize for Windows compatibility as well
String sanitized = baseFileName
.replaceAll("[<>:\"/\\\\|?*]", "_") // Windows invalid chars
.replaceAll("\\s+", "_") // Replace multiple spaces with single underscore
.replaceAll("_{2,}", "_") // Replace multiple underscores with single
.replaceAll("^[._]+", "") // Remove leading dots/underscores (Linux hidden files)
.replaceAll("[._]+$", ""); // Remove trailing dots/underscores

// Ensure we have a valid filename after sanitization
if (sanitized.isEmpty()) {
sanitized = "unnamed";
}

// Check if filename length is within limits
if (sanitized.length() <= MAX_FILENAME_LENGTH) {
return sanitized;
}
// Filename is too long, need to truncate and add hash for uniqueness
String truncated = sanitized.substring(0, Math.min(sanitized.length(), MAX_TRUNCATED_LENGTH));
String hash = generateShortHash(baseFileName); // Use original name for hash to maintain uniqueness
String result = truncated + "_" + hash; // Log the truncation for debugging purposes
System.out.println("WARNING: Filename too long, truncated from '" + baseFileName + "' to '" + result + "'");

return result;
}

/**
* Generates a short hash from the input string to ensure filename uniqueness.
*
* @param input the string to hash
* @return a short hash string (8 characters)
*/
public static String generateShortHash(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));

// Convert to hex and take first 8 characters for a short unique identifier
StringBuilder sb = new StringBuilder();
for (int i = 0; i < Math.min(4, hash.length); i++) {
sb.append(String.format("%02x", hash[i]));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
// Fallback: use hashCode if MD5 is not available
return String.format("%08x", Math.abs(input.hashCode()));
}
}
}
24 changes: 14 additions & 10 deletions src/main/java/com/checkpoint/mgmt_api/utils/HtmlUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,12 @@ public void writeRulebaseHTML(String layerName, String packageName, String domai
"\"domain\" : \"" + domain + "\", \"package\" : \""
+ packageName + "\", " + "\"layer\" : \"" + layerName + "\", \"type\" : \"" + rulebaseType + "\"}";

// Sanitize filenames to prevent "File name too long" errors
String baseFileName = layerName + "-" + domain;
String sanitizedBaseFileName = FileNameUtils.sanitizeFileName(baseFileName);

String htmlFileName = resultFolderPath +layerName + "-" + domain + HTML_SUFFIX;
String jsonFileName = resultFolderPath +layerName + "-" + domain + JSON_SUFFIX;
String htmlFileName = resultFolderPath + sanitizedBaseFileName + HTML_SUFFIX;
String jsonFileName = resultFolderPath + sanitizedBaseFileName + JSON_SUFFIX;
String objectsFile = resultFolderPath + RULEBASE_FILE;
FileDetails details = new FileDetails(objectsFile,getRulebaseHtmlTemplateLines(),htmlFileName, jsonFileName,
uidToName, new RulebaseData(rulebase, inlineLayers, failedCreatingRulbase));
Expand Down Expand Up @@ -293,13 +296,14 @@ private void setDataInHtmlFile(PrintStream htmlFile, FileDetails details) throws
* @throws FileNotFoundException
* @throws UnsupportedEncodingException
*/
public void writeObjectsHTML(String packageName) throws IOException
{
String objectsFile = resultFolderPath + OBJECTS_FILE;
String htmlFileName = resultFolderPath + packageName + "_objects" + HTML_SUFFIX;
String jsonFileName = resultFolderPath + packageName + "_objects" + JSON_SUFFIX;
FileDetails details = new FileDetails(objectsFile, getObjectsHtmlTemplateLines(), htmlFileName, jsonFileName);
createHtmlFile(details, FileType.OBJECTS);
public void writeObjectsHTML(String packageName) throws IOException
{
String objectsFile = resultFolderPath + OBJECTS_FILE;
String sanitizedPackageName = FileNameUtils.sanitizeFileName(packageName + "_objects");
String htmlFileName = resultFolderPath + sanitizedPackageName + HTML_SUFFIX;
String jsonFileName = resultFolderPath + sanitizedPackageName + JSON_SUFFIX;
FileDetails details = new FileDetails(objectsFile, getObjectsHtmlTemplateLines(), htmlFileName, jsonFileName);
createHtmlFile(details, FileType.OBJECTS);
}

/**
Expand All @@ -313,7 +317,7 @@ public void writeObjectsHTML(String packageName) throws IOException
*/
public boolean writeGatewaysHTML(String packageName, String objectsAsJsonString ) throws IOException
{
String pageName = packageName +"_gateway_objects";
String pageName = FileNameUtils.sanitizeFileName(packageName + "_gateway_objects");
return writeToHtmlPage(pageName, objectsAsJsonString, getObjectsHtmlTemplateLines());
}

Expand Down