Fixing issue #1831 (#1879)
Some checks failed
CodeQL / Analyze (java) (push) Has been cancelled
Test Java 17 / build (push) Has been cancelled
Test Java 21 / build (push) Has been cancelled
Test Java 8 / build (push) Has been cancelled

* throw a more explicit exception when trying to PDF417/TEXT encode something outside of 0...255

* refactor PDF417HighLevelEncoder to avoid code duplication
extend UT to new method PDF417HighLevelEncoder#checkCharset

* fix javadoc typo
make UT more stringent on PDF417HighLevelEncoder#checkCharset

* restrict TEXT to 0...127
test with CP437 and Greek chars

* reinstate testEncodeAuto UT

* refactor testEncodeAuto UT

* address codacy findings

* formatting

* fix issue #1831
make PDF417#determineDimensions to enable finer UT
add UT coverage to validate fix for #1831

* fix javadoc for PDF417#determineDimensions
remove stacktrace when UT fails

* make UT Java 8 compliant
This commit is contained in:
François Tiercelin 2024-11-17 16:25:04 +00:00 committed by GitHub
parent 3b189fc700
commit 2dfb2054af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 57 additions and 4 deletions

View file

@ -659,7 +659,8 @@ public final class PDF417 {
String highLevel = PDF417HighLevelEncoder.encodeHighLevel(msg, compaction, encoding, autoECI);
int sourceCodeWords = highLevel.length();
int[] dimension = determineDimensions(sourceCodeWords, errorCorrectionCodeWords);
int[] dimension = determineDimensions(minCols, maxCols, minRows, maxRows,
sourceCodeWords, errorCorrectionCodeWords);
int cols = dimension[0];
int rows = dimension[1];
@ -692,16 +693,25 @@ public final class PDF417 {
* Determine optimal nr of columns and rows for the specified number of
* codewords.
*
* @param minCols minimum number of columns
* @param maxCols maximum number of columns
* @param minRows minimum number of rows
* @param maxRows maximum number of rows
* @param sourceCodeWords number of code words
* @param errorCorrectionCodeWords number of error correction code words
* @return dimension object containing cols as width and rows as height
* @throws WriterException when dimensions can't be determined
*/
private int[] determineDimensions(int sourceCodeWords, int errorCorrectionCodeWords) throws WriterException {
protected static int[] determineDimensions(int minCols, int maxCols,
int minRows, int maxRows,
int sourceCodeWords, int errorCorrectionCodeWords) throws WriterException {
float ratio = 0.0f;
int[] dimension = null;
int currentCol = minCols;
for (int cols = minCols; cols <= maxCols; cols++) {
currentCol = cols;
int rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, cols);
if (rows < minRows) {
@ -725,7 +735,7 @@ public final class PDF417 {
// Handle case when min values were larger than necessary
if (dimension == null) {
int rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, minCols);
int rows = calculateNumberOfRows(sourceCodeWords, errorCorrectionCodeWords, currentCol);
if (rows < minRows) {
dimension = new int[]{minCols, minRows};
}

View file

@ -23,7 +23,10 @@ import java.util.UUID;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Writer;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.pdf417.PDF417Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@ -161,4 +164,44 @@ public final class PDF417EncoderTestCase extends Assert {
public void testEncodeEmptyString() throws Exception {
PDF417HighLevelEncoder.encodeHighLevel("", Compaction.AUTO, null, false);
}
@Test
public void testDimensions() throws Exception {
// test https://github.com/zxing/zxing/issues/1831
String input = "0000000001000000022200000003330444400888888881010101010";
testDimensions(input, new Dimensions(1, 30, 7, 10));
testDimensions(input, new Dimensions(1, 40, 1, 7));
testDimensions(input, new Dimensions(10, 30, 1, 5));
testDimensions(input, new Dimensions(1, 3, 1, 15));
testDimensions(input, new Dimensions(5, 30, 7, 7));
testDimensions(input, new Dimensions(12, 12, 1, 17));
testDimensions(input, new Dimensions(1, 30, 7, 7));
}
public static void testDimensions(String input, Dimensions dimensions) throws Exception {
int sourceCodeWords = 20;
int errorCorrectionCodeWords = 8;
int[] calculated = PDF417.determineDimensions(dimensions.getMinCols(), dimensions.getMaxCols(),
dimensions.getMinRows(), dimensions.getMaxRows(),
sourceCodeWords, errorCorrectionCodeWords);
assertNotNull(calculated);
assertEquals(2,calculated.length);
assertTrue(dimensions.getMinCols() <= calculated[0]);
assertTrue(dimensions.getMaxCols() >= calculated[0]);
assertTrue(dimensions.getMinRows() <= calculated[1]);
assertTrue(dimensions.getMaxRows() >= calculated[1]);
assertNotNull(generatePDF417BitMatrix(input, 371, null, dimensions));
}
public static BitMatrix generatePDF417BitMatrix(final String barcodeText, final int width,
final Integer heightRequested, final Dimensions dimensions) throws WriterException {
final Writer barcodeWriter = new PDF417Writer();
final int height = heightRequested == null ? width / 4 : heightRequested;
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.MARGIN, 0);
hints.put(EncodeHintType.PDF417_DIMENSIONS, dimensions);
return barcodeWriter.encode(barcodeText, BarcodeFormat.PDF_417, width, height, hints);
}
}