{"record":{"id":"1cc79abfdd20d53a","repo":"unoplatform/uno","slug":"cmap-table-not-found","errorCode":null,"errorMessage":"cmap table not found","messagePattern":"cmap table not found","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/FontFallbackPreprocessor/Program.cs","lineNumber":280,"sourceCode":"\n\t\t// 2. Find 'cmap' table\n\t\tuint cmapOffset = 0;\n\t\tfor (int i = 0; i < numTables; i++)\n\t\t{\n\t\t\tuint tag = ReadUInt32Be(reader);\n\t\t\t_ = ReadUInt32Be(reader); // checkSum\n\t\t\tuint offset = ReadUInt32Be(reader);\n\t\t\t_ = ReadUInt32Be(reader); // length\n\n\t\t\tif (tag == 0x636D6170) // 'cmap'\n\t\t\t{\n\t\t\t\tcmapOffset = offset;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (cmapOffset == 0)\n\t\t\tthrow new Exception(\"cmap table not found\");\n\n\t\t// 3. Read cmap table header\n\t\tfs.Seek(cmapOffset, SeekOrigin.Begin);\n\t\t_ = ReadUInt16Be(reader); // version\n\t\tushort numSubtables = ReadUInt16Be(reader);\n\n\t\tuint selectedSubtableOffset = 0;\n\t\tint selectedPlatformId = -1;\n\t\tint selectedEncodingId = -1;\n\n\t\t// We want Platform 3 (Windows) and Encoding 1 (Unicode BMP) or 10 (Unicode Full)\n\t\t// Or Platform 0 (Unicode)\n\t\tfor (int i = 0; i < numSubtables; i++)\n\t\t{\n\t\t\tushort platformId = ReadUInt16Be(reader);\n\t\t\tushort encodingId = ReadUInt16Be(reader);\n\t\t\tuint offset = ReadUInt32Be(reader);\n","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/unoplatform/uno/blob/04183404888ea21b4e5bfa3493e8d5f15e972c3a/src/FontFallbackPreprocessor/Program.cs#L262-L298","documentation":"FontFallbackPreprocessor is a build-time console tool that parses TrueType/OpenType fonts from the notofonts repo to extract their Unicode coverage (cmap). It reads the font's table directory; if no table tagged 'cmap' (0x636D6170) is present, cmapOffset stays 0 and it throws a bare Exception. Every valid TrueType/OpenType font must contain a cmap, so its absence means the input is not a usable font (corrupt, a collection, an OTF stub, or a non-font file).","triggerScenarios":"Feeding the preprocessor a file that is not a well-formed font (no cmap table): a corrupt TTF, a bare text/JSON file mislabeled .ttf, an OTF with an unusual table layout, or an empty download.","commonSituations":"A notofonts checkout with a partial/incomplete font file; a network blip leaving a truncated font download; pointing the tool at a directory containing non-font artifacts; an OTF/CFF font whose tables are ordered so the cmap scan overruns.","solutions":["Validate the input is a real font (check the sfVersion magic 0x00010000 / 'OTTO' / 'true') before parsing.","Re-download/regenerate the offending font file from notofonts and confirm it opens in a font tool.","Skip non-font files in the directory scan before calling the cmap parser."],"exampleFix":"// before\nif (cmapOffset == 0) throw new Exception(\"cmap table not found\");\n\n// after\nif (cmapOffset == 0)\n{\n\tthis.Log().Warning($\"{path} has no cmap table; skipping.\");\n\treturn null; // skip this font in the build tool","handlingStrategy":"validation","validationCode":"uint magic = ReadUInt32Be(reader);\nbool isFont = magic == 0x00010000 || magic == 0x4F54544F /*OTTO*/ || magic == 0x74727565 /*true*/;\nif (!isFont) { /* skip non-font file */ }","typeGuard":"static bool LooksLikeFontHeader(uint magic) => magic == 0x00010000u || magic == 0x4F54544Fu || magic == 0x74727565u;","tryCatchPattern":"try { ParseCmap(path); }\ncatch (Exception ex) when (ex.Message.Contains(\"cmap table not found\")) { Log.Warn($\"{path} not a valid font; skipping.\"); }","preventionTips":["Validate the sfVersion magic before parsing.","Filter the input directory to .ttf/.otf files only.","Re-download truncated/corrupt font files before regenerating fallback maps."],"tags":["font","build-tool","fontfallbackpreprocessor","truetype","cmap"],"backgroundTag":null,"analyzedSha":"04183404888ea21b4e5bfa3493e8d5f15e972c3a","analyzedAt":"2026-08-13T21:08:11.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}