Skip to content

Commit d6d8d48

Browse files
authored
Merge pull request #38 from chkp-edenbr/master
file name too long fix
2 parents b6b27e6 + 16f1493 commit d6d8d48

4 files changed

Lines changed: 104 additions & 13 deletions

File tree

src/main/java/com/checkpoint/mgmt_api/examples/ShowPackageConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public enum ShowPackageConfiguration {
2727

2828
INSTANCE;
2929

30-
private static final String TOOL_VERSION = "v2.3.0";
30+
private static final String TOOL_VERSION = "v2.3.1";
3131
private static final String TAR_SUFFIX = ".tar.gz";
3232
private static final String LOG_SUFFIX = ".elg";
3333
private static final String PREFIX = "show_package-";

src/main/java/com/checkpoint/mgmt_api/examples/ShowPackageTool.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import com.checkpoint.mgmt_api.utils.TarGZUtils;
2323
import org.json.simple.JSONArray;
2424
import org.json.simple.JSONObject;
25+
import com.checkpoint.mgmt_api.utils.FileNameUtils;
2526

2627
import java.io.FileNotFoundException;
2728
import java.io.IOException;
@@ -765,7 +766,8 @@ private static Layer aggregatePackageLayers(String packageName, List<Layer> acce
765766
}
766767
configuration.getLogger().debug("Found nat layer in package: '" + packageName + "'");
767768
natLayer.setDomainType(domain.get("domain-type").toString());
768-
natLayer.setHtmlFileName(packageName + " " + natLayer.getName() + "-" + natLayer.getDomain() + ".html");
769+
String baseFileName = packageName + " " + natLayer.getName() + "-" + natLayer.getDomain();
770+
natLayer.setHtmlFileName(FileNameUtils.sanitizeFileName(baseFileName) + ".html");
769771
}
770772
}
771773
return natLayer;
@@ -1338,7 +1340,8 @@ private static Layer createNewLayer(JSONObject layerInfo){
13381340
layer.setDomain("Management server");
13391341
}
13401342
layer.setDomainType(((JSONObject) layerInfo.get("domain")).get("domain-type").toString());
1341-
layer.setHtmlFileName(layer.getName() + "-" + layer.getDomain() + ".html");
1343+
String baseFileName = layer.getName() + "-" + layer.getDomain();
1344+
layer.setHtmlFileName(FileNameUtils.sanitizeFileName(baseFileName) + ".html");
13421345

13431346
return layer;
13441347
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package com.checkpoint.mgmt_api.utils;
2+
3+
import java.nio.charset.StandardCharsets;
4+
import java.security.MessageDigest;
5+
import java.security.NoSuchAlgorithmException;
6+
7+
/**
8+
* Utility class for filename sanitization to prevent "File name too long" filesystem errors.
9+
* Provides cross-platform compatible filename handling with length limits and character filtering.
10+
*/
11+
public class FileNameUtils {
12+
13+
// Maximum filename length (excluding path and extension) to ensure compatibility across filesystems
14+
// Linux supports up to 255, Windows up to 260, but we use a conservative limit for safety
15+
private static final int MAX_FILENAME_LENGTH = 200;
16+
// Maximum length for the truncated portion before adding hash
17+
private static final int MAX_TRUNCATED_LENGTH = 150;
18+
19+
/**
20+
* Sanitizes a filename to ensure it doesn't exceed filesystem limits.
21+
* If the filename is too long, it truncates the name and adds a hash suffix for uniqueness.
22+
*
23+
* This method handles cross-platform filename restrictions:
24+
* - Removes/replaces invalid characters for both Windows and Linux
25+
* - Enforces length limits compatible with most filesystems
26+
*
27+
* @param baseFileName the original filename (without extension)
28+
* @return sanitized filename that fits within filesystem limits
29+
*/
30+
public static String sanitizeFileName(String baseFileName) {
31+
if (baseFileName == null || baseFileName.isEmpty()) {
32+
return "unnamed";
33+
}
34+
35+
// Remove or replace invalid filename characters for cross-platform compatibility
36+
// Linux is more permissive, but we sanitize for Windows compatibility as well
37+
String sanitized = baseFileName
38+
.replaceAll("[<>:\"/\\\\|?*]", "_") // Windows invalid chars
39+
.replaceAll("\\s+", "_") // Replace multiple spaces with single underscore
40+
.replaceAll("_{2,}", "_") // Replace multiple underscores with single
41+
.replaceAll("^[._]+", "") // Remove leading dots/underscores (Linux hidden files)
42+
.replaceAll("[._]+$", ""); // Remove trailing dots/underscores
43+
44+
// Ensure we have a valid filename after sanitization
45+
if (sanitized.isEmpty()) {
46+
sanitized = "unnamed";
47+
}
48+
49+
// Check if filename length is within limits
50+
if (sanitized.length() <= MAX_FILENAME_LENGTH) {
51+
return sanitized;
52+
}
53+
// Filename is too long, need to truncate and add hash for uniqueness
54+
String truncated = sanitized.substring(0, Math.min(sanitized.length(), MAX_TRUNCATED_LENGTH));
55+
String hash = generateShortHash(baseFileName); // Use original name for hash to maintain uniqueness
56+
String result = truncated + "_" + hash; // Log the truncation for debugging purposes
57+
System.out.println("WARNING: Filename too long, truncated from '" + baseFileName + "' to '" + result + "'");
58+
59+
return result;
60+
}
61+
62+
/**
63+
* Generates a short hash from the input string to ensure filename uniqueness.
64+
*
65+
* @param input the string to hash
66+
* @return a short hash string (8 characters)
67+
*/
68+
public static String generateShortHash(String input) {
69+
try {
70+
MessageDigest md = MessageDigest.getInstance("MD5");
71+
byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
72+
73+
// Convert to hex and take first 8 characters for a short unique identifier
74+
StringBuilder sb = new StringBuilder();
75+
for (int i = 0; i < Math.min(4, hash.length); i++) {
76+
sb.append(String.format("%02x", hash[i]));
77+
}
78+
return sb.toString();
79+
} catch (NoSuchAlgorithmException e) {
80+
// Fallback: use hashCode if MD5 is not available
81+
return String.format("%08x", Math.abs(input.hashCode()));
82+
}
83+
}
84+
}

src/main/java/com/checkpoint/mgmt_api/utils/HtmlUtils.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,12 @@ public void writeRulebaseHTML(String layerName, String packageName, String domai
182182
"\"domain\" : \"" + domain + "\", \"package\" : \""
183183
+ packageName + "\", " + "\"layer\" : \"" + layerName + "\", \"type\" : \"" + rulebaseType + "\"}";
184184

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

186-
String htmlFileName = resultFolderPath +layerName + "-" + domain + HTML_SUFFIX;
187-
String jsonFileName = resultFolderPath +layerName + "-" + domain + JSON_SUFFIX;
189+
String htmlFileName = resultFolderPath + sanitizedBaseFileName + HTML_SUFFIX;
190+
String jsonFileName = resultFolderPath + sanitizedBaseFileName + JSON_SUFFIX;
188191
String objectsFile = resultFolderPath + RULEBASE_FILE;
189192
FileDetails details = new FileDetails(objectsFile,getRulebaseHtmlTemplateLines(),htmlFileName, jsonFileName,
190193
uidToName, new RulebaseData(rulebase, inlineLayers, failedCreatingRulbase));
@@ -293,13 +296,14 @@ private void setDataInHtmlFile(PrintStream htmlFile, FileDetails details) throws
293296
* @throws FileNotFoundException
294297
* @throws UnsupportedEncodingException
295298
*/
296-
public void writeObjectsHTML(String packageName) throws IOException
297-
{
298-
String objectsFile = resultFolderPath + OBJECTS_FILE;
299-
String htmlFileName = resultFolderPath + packageName + "_objects" + HTML_SUFFIX;
300-
String jsonFileName = resultFolderPath + packageName + "_objects" + JSON_SUFFIX;
301-
FileDetails details = new FileDetails(objectsFile, getObjectsHtmlTemplateLines(), htmlFileName, jsonFileName);
302-
createHtmlFile(details, FileType.OBJECTS);
299+
public void writeObjectsHTML(String packageName) throws IOException
300+
{
301+
String objectsFile = resultFolderPath + OBJECTS_FILE;
302+
String sanitizedPackageName = FileNameUtils.sanitizeFileName(packageName + "_objects");
303+
String htmlFileName = resultFolderPath + sanitizedPackageName + HTML_SUFFIX;
304+
String jsonFileName = resultFolderPath + sanitizedPackageName + JSON_SUFFIX;
305+
FileDetails details = new FileDetails(objectsFile, getObjectsHtmlTemplateLines(), htmlFileName, jsonFileName);
306+
createHtmlFile(details, FileType.OBJECTS);
303307
}
304308

305309
/**
@@ -313,7 +317,7 @@ public void writeObjectsHTML(String packageName) throws IOException
313317
*/
314318
public boolean writeGatewaysHTML(String packageName, String objectsAsJsonString ) throws IOException
315319
{
316-
String pageName = packageName +"_gateway_objects";
320+
String pageName = FileNameUtils.sanitizeFileName(packageName + "_gateway_objects");
317321
return writeToHtmlPage(pageName, objectsAsJsonString, getObjectsHtmlTemplateLines());
318322
}
319323

0 commit comments

Comments
 (0)