From 4cd41f08f7618ffa61bc57f1eec7ef1168e849dc Mon Sep 17 00:00:00 2001 From: Michael Dieringer <65093775+MichaelDieringer@users.noreply.github.com> Date: Mon, 28 Sep 2026 18:02:08 +0200 Subject: [PATCH] Make barcode bad fixture self-contained: 1D EncodeFont without ValidateInput The previous bad fixture (literal '*' delimiters, no layout/font/provider evidence) no longer matched the narrowed routing cue. It now shows an IDAutomation 1D provider path that calls EncodeFont without ValidateInput, which is visible in AL alone. Article Anti Pattern and Source updated to describe this variant (verified: IDAutomation 1D Provider's EncodeFont does not call IsValidInput). Co-Authored-By: Claude Opus 5.5 --- ...ode-module-and-production-font-name.bad.al | 38 +++++++++---------- ...barcode-module-and-production-font-name.md | 11 +++++- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/microsoft/knowledge/data-modeling/report-barcodes-must-use-barcode-module-and-production-font-name.bad.al b/microsoft/knowledge/data-modeling/report-barcodes-must-use-barcode-module-and-production-font-name.bad.al index 0de8b58..a60692b 100644 --- a/microsoft/knowledge/data-modeling/report-barcodes-must-use-barcode-module-and-production-font-name.bad.al +++ b/microsoft/knowledge/data-modeling/report-barcodes-must-use-barcode-module-and-production-font-name.bad.al @@ -12,30 +12,30 @@ report 50110 "Sample Item Barcode Label" column(Barcode; BarcodeText) { } trigger OnAfterGetRecord() + var + BarcodeFontProvider: Interface "Barcode Font Provider"; begin - // WRONG: hand-rolled "encoding" instead of the Barcode - // module's provider/encoder API. This is not wrong merely - // because the delimiter was added by hand - Code 39's own - // symbology does use "*" as its start/stop character - // (Microsoft Learn, "Barcode Fonts with Business Central - // Online"). It's wrong because it's demonstrably mismatched - // with what encoding "No." through the real API would - // produce: - // - it skips ValidateInput, so a "No." value outside Code - // 39's character set, or one that needs a checksum this - // code never applies, reaches the font unvalidated; - // - IDAutomation 1D Provider's own EncodeFont output for - // Code 39 wraps the value in "(" / ")", not literal "*" - // (BCApps' own encoder test: EncodeFont('1234', Code39) - // = '(1234)') - the paired font maps those parentheses to - // the real start/stop glyph, so a string built with - // literal asterisks is simply the wrong characters for - // that font, on top of carrying no real checksum. - BarcodeText := '*' + "No." + '*'; + // WRONG: a one-dimensional IDAutomation provider path that + // calls EncodeFont without ValidateInput. "Barcode Font + // Provider" (1D) declares both, and IDAutomation 1D + // Provider's EncodeFont does not validate on its own - it + // hands the text straight to the font encoder. Code 39 + // accepts only 0-9, A-Z, space and - . $ / + % *, but an + // Item "No." can legally contain characters outside that + // set (e.g. "_" or "#"). Such a value is never rejected; + // it silently reaches the font as an unscannable barcode. + BarcodeFontProvider := Enum::"Barcode Font Provider"::IDAutomation1D; + BarcodeText := BarcodeFontProvider.EncodeFont("No.", BarcodeSymbology); end; } } var + BarcodeSymbology: Enum "Barcode Symbology"; BarcodeText: Text; + + trigger OnInitReport() + begin + BarcodeSymbology := Enum::"Barcode Symbology"::Code39; + end; } diff --git a/microsoft/knowledge/data-modeling/report-barcodes-must-use-barcode-module-and-production-font-name.md b/microsoft/knowledge/data-modeling/report-barcodes-must-use-barcode-module-and-production-font-name.md index 892c2f1..1d21211 100644 --- a/microsoft/knowledge/data-modeling/report-barcodes-must-use-barcode-module-and-production-font-name.md +++ b/microsoft/knowledge/data-modeling/report-barcodes-must-use-barcode-module-and-production-font-name.md @@ -78,13 +78,22 @@ evaluation font instead of the purchased one. Both look complete in review and fail silently — the first because the data was never a real barcode, the second because BC online refuses to render it. +The same gap exists even when the module *is* used: a 1D path that calls +`EncodeFont` on `"Barcode Font Provider"` without `ValidateInput`. +IDAutomation 1D Provider's `EncodeFont` does not validate on its own, so +a value outside the symbology's character set is never rejected — it +reaches the font as an unscannable barcode. The sample shows this +variant, because it is visible in AL alone without layout evidence. + See sample: [`report-barcodes-must-use-barcode-module-and-production-font-name.bad.al`](report-barcodes-must-use-barcode-module-and-production-font-name.bad.al). ## Source BCApps (`src/System Application/App/Barcode/src/`): `Barcode Provider/Font/BarcodeFontProvider.Interface.al` (1D: -`ValidateInput` + `EncodeFont`); `Barcode Provider 2D/Font/ +`ValidateInput` + `EncodeFont`); `IDAutomation 1D Provider/ +IDAutomation1DProvider.Codeunit.al` (`EncodeFont` goes straight to the +symbology encoder; only `ValidateInput` calls `IsValidInput`); `Barcode Provider 2D/Font/ BarcodeFontProvider2D.Interface.al` (2D: only `EncodeFont`); both read fresh from source. `IDAutomation 1D Provider/Encoders/ IDA1DCode39Encoder.Codeunit.al` (`codeunit 9204`, regex accepts literal