diff --git a/liblouis/compileTranslationTable.c b/liblouis/compileTranslationTable.c --- a/liblouis/compileTranslationTable.c +++ b/liblouis/compileTranslationTable.c @@ -365,12 +365,13 @@ char * showString (widechar const *chars, int length) { -/*Translate a string of characters to the encoding used in character -* operands */ + /*Translate a string of characters to the encoding used in character + * operands */ int charPos; int bufPos = 0; + static char scratchBuf[MAXSTRING]; scratchBuf[bufPos++] = '\''; - for (charPos = 0; charPos < length; charPos++) + for (charPos = 0; charPos < length && bufPos < (MAXSTRING-2); charPos++) { if (chars[charPos] >= 32 && chars[charPos] < 127) scratchBuf[bufPos++] = (char) chars[charPos]; @@ -407,7 +408,7 @@ leadingZeros = 0; break; } - if ((bufPos + leadingZeros + hexLength + 4) >= sizeof (scratchBuf)) + if ((bufPos + leadingZeros + hexLength + 4) >= (MAXSTRING-2)) break; scratchBuf[bufPos++] = '\\'; scratchBuf[bufPos++] = escapeLetter; @@ -422,87 +423,88 @@ return scratchBuf; } +typedef struct intCharTupple { + int key; + char value; +} intCharTupple; + +/** + * Mapping between braille dot and textual representation as used in dots operands + */ +const static intCharTupple dotMapping[] = { + {B1, '1'}, + {B2, '2'}, + {B3, '3'}, + {B4, '4'}, + {B5, '5'}, + {B6, '6'}, + {B7, '7'}, + {B8, '8'}, + {B9, '9'}, + {B10, 'A'}, + {B11, 'B'}, + {B12, 'C'}, + {B13, 'D'}, + {B14, 'E'}, + {B15, 'F'}, + 0 +}; + +/** + * Translate a sequence of dots to the encoding used in dots operands. + */ char * showDots (widechar const *dots, int length) { -/* Translate a sequence of dots to the encoding used in dots operands. -*/ int bufPos = 0; - int dotsPos; - for (dotsPos = 0; bufPos < sizeof (scratchBuf) && dotsPos < length; - dotsPos++) - { - if ((dots[dotsPos] & B1)) - scratchBuf[bufPos++] = '1'; - if ((dots[dotsPos] & B2)) - scratchBuf[bufPos++] = '2'; - if ((dots[dotsPos] & B3)) - scratchBuf[bufPos++] = '3'; - if ((dots[dotsPos] & B4)) - scratchBuf[bufPos++] = '4'; - if ((dots[dotsPos] & B5)) - scratchBuf[bufPos++] = '5'; - if ((dots[dotsPos] & B6)) - scratchBuf[bufPos++] = '6'; - if ((dots[dotsPos] & B7)) - scratchBuf[bufPos++] = '7'; - if ((dots[dotsPos] & B8)) - scratchBuf[bufPos++] = '8'; - if ((dots[dotsPos] & B9)) - scratchBuf[bufPos++] = '9'; - if ((dots[dotsPos] & B10)) - scratchBuf[bufPos++] = 'A'; - if ((dots[dotsPos] & B11)) - scratchBuf[bufPos++] = 'B'; - if ((dots[dotsPos] & B12)) - scratchBuf[bufPos++] = 'C'; - if ((dots[dotsPos] & B13)) - scratchBuf[bufPos++] = 'D'; - if ((dots[dotsPos] & B14)) - scratchBuf[bufPos++] = 'E'; - if ((dots[dotsPos] & B15)) - scratchBuf[bufPos++] = 'F'; - if ((dots[dotsPos] == B16)) - scratchBuf[bufPos++] = '0'; - if (dotsPos != length - 1) - scratchBuf[bufPos++] = '-'; + static char scratchBuf[MAXSTRING]; + for (int dotsPos = 0; dotsPos < length && bufPos < (MAXSTRING-1); dotsPos++) { + for (int mappingPos = 0; dotMapping[mappingPos].key; mappingPos++) { + if ((dots[dotsPos] & dotMapping[mappingPos].key) && (bufPos < (MAXSTRING-1))) + scratchBuf[bufPos++] = dotMapping[mappingPos].value; } + if ((dots[dotsPos] == B16) && (bufPos < (MAXSTRING-1))) + scratchBuf[bufPos++] = '0'; + if ((dotsPos != length - 1) && (bufPos < (MAXSTRING-1))) + scratchBuf[bufPos++] = '-'; + } scratchBuf[bufPos] = 0; - return &scratchBuf[0]; + return scratchBuf; } +/** + * Mapping between character attribute and textual representation + */ +const static intCharTupple attributeMapping[] = { + {CTC_Space, 's'}, + {CTC_Letter, 'l'}, + {CTC_Digit, 'd'}, + {CTC_Punctuation, 'p'}, + {CTC_UpperCase, 'U'}, + {CTC_LowerCase, 'u'}, + {CTC_Math, 'm'}, + {CTC_Sign, 'S'}, + {CTC_LitDigit, 'D'}, + {CTC_Class1, 'w'}, + {CTC_Class2, 'x'}, + {CTC_Class3, 'y'}, + {CTC_Class4, 'z'}, + 0 +}; + +/** + * Show attributes using the letters used after the $ in multipass + * opcodes. + */ char * showAttributes (TranslationTableCharacterAttributes a) { -/* Show attributes using the letters used after the $ in multipass -* opcodes. */ int bufPos = 0; - if ((a & CTC_Space)) - scratchBuf[bufPos++] = 's'; - if ((a & CTC_Letter)) - scratchBuf[bufPos++] = 'l'; - if ((a & CTC_Digit)) - scratchBuf[bufPos++] = 'd'; - if ((a & CTC_Punctuation)) - scratchBuf[bufPos++] = 'p'; - if ((a & CTC_UpperCase)) - scratchBuf[bufPos++] = 'U'; - if ((a & CTC_LowerCase)) - scratchBuf[bufPos++] = 'u'; - if ((a & CTC_Math)) - scratchBuf[bufPos++] = 'm'; - if ((a & CTC_Sign)) - scratchBuf[bufPos++] = 'S'; - if ((a & CTC_LitDigit)) - scratchBuf[bufPos++] = 'D'; - if ((a & CTC_Class1)) - scratchBuf[bufPos++] = 'w'; - if ((a & CTC_Class2)) - scratchBuf[bufPos++] = 'x'; - if ((a & CTC_Class3)) - scratchBuf[bufPos++] = 'y'; - if ((a & CTC_Class4)) - scratchBuf[bufPos++] = 'z'; + static char scratchBuf[MAXSTRING]; + for (int mappingPos = 0; attributeMapping[mappingPos].key; mappingPos++) { + if ((a & attributeMapping[mappingPos].key) && bufPos < (MAXSTRING - 1)) + scratchBuf[bufPos++] = attributeMapping[mappingPos].value; + } scratchBuf[bufPos] = 0; return scratchBuf; } @@ -592,9 +594,10 @@ if (pch == '\\' && ch == 10) { nested->linelen--; + pch = ch; continue; } - if (ch == 10 || nested->linelen >= MAXSTRING) + if (ch == 10 || nested->linelen >= MAXSTRING-1) break; nested->line[nested->linelen++] = (widechar) ch; pch = ch; @@ -957,43 +960,22 @@ return 1; } +/** + * Print out dot numbers + * + * @return a string containing the dot numbers. The longest possible + * output is "\123456789ABCDEF0/" + */ static char * unknownDots (widechar dots) { -/*Print out dot numbers */ static char buffer[20]; int k = 1; buffer[0] = '\\'; - if ((dots & B1)) - buffer[k++] = '1'; - if ((dots & B2)) - buffer[k++] = '2'; - if ((dots & B3)) - buffer[k++] = '3'; - if ((dots & B4)) - buffer[k++] = '4'; - if ((dots & B5)) - buffer[k++] = '5'; - if ((dots & B6)) - buffer[k++] = '6'; - if ((dots & B7)) - buffer[k++] = '7'; - if ((dots & B8)) - buffer[k++] = '8'; - if ((dots & B9)) - buffer[k++] = '9'; - if ((dots & B10)) - buffer[k++] = 'A'; - if ((dots & B11)) - buffer[k++] = 'B'; - if ((dots & B12)) - buffer[k++] = 'C'; - if ((dots & B13)) - buffer[k++] = 'D'; - if ((dots & B14)) - buffer[k++] = 'E'; - if ((dots & B15)) - buffer[k++] = 'F'; + for (int mappingPos = 0; dotMapping[mappingPos].key; mappingPos++) { + if (dots & dotMapping[mappingPos].key) + buffer[k++] = dotMapping[mappingPos].value; + } buffer[k++] = '/'; buffer[k] = 0; return buffer; @@ -1557,6 +1539,11 @@ { compileWarning (nested, "invalid UTF-8. Assuming Latin-1."); result->chars[out++] = token->chars[lastIn]; + if (out >= MAXSTRING) + { + result->length = out; + return 1; + } in = lastIn + 1; continue; } @@ -1582,7 +1569,7 @@ CharsString wideIn; CharsString result; int k; - for (k = 0; inString[k] && k < MAXSTRING; k++) + for (k = 0; inString[k] && k < MAXSTRING-1; k++) wideIn.chars[k] = inString[k]; wideIn.chars[k] = 0; wideIn.length = k; @@ -1713,7 +1700,7 @@ CharsString wideIn; CharsString result; int k; - for (k = 0; inString[k] && k < MAXSTRING; k++) + for (k = 0; inString[k] && k < MAXSTRING-1; k++) wideIn.chars[k] = inString[k]; wideIn.chars[k] = 0; wideIn.length = k; @@ -3244,8 +3231,7 @@ static int compileBrailleIndicator (FileInfo * nested, char *ermsg, - TranslationTableOpcode opcode, - TranslationTableOffset * rule) + TranslationTableOpcode opcode) { CharsString token; CharsString cells; @@ -3253,7 +3239,6 @@ if (parseDots (nested, &cells, &token)) if (!addRule (nested, opcode, NULL, &cells, 0, 0)) return 0; - *rule = newRuleOffset; return 1; } @@ -3869,18 +3854,22 @@ case CTO_Undefined: ok = compileBrailleIndicator (nested, "undefined character opcode", - CTO_Undefined, &table->undefined); + CTO_Undefined); + if (ok) + table->undefined = newRuleOffset; break; case CTO_CapitalSign: ok = - compileBrailleIndicator (nested, "capital sign", CTO_CapitalRule, - &table->capitalSign); + compileBrailleIndicator (nested, "capital sign", CTO_CapitalRule); + if (ok) + table->capitalSign = newRuleOffset; break; case CTO_BeginCapitalSign: ok = compileBrailleIndicator (nested, "begin capital sign", - CTO_BeginCapitalRule, - &table->beginCapitalSign); + CTO_BeginCapitalRule); + if (ok) + table->beginCapitalSign = newRuleOffset; break; case CTO_LenBegcaps: ok = table->lenBeginCaps = compileNumber (nested); @@ -3888,33 +3877,39 @@ case CTO_EndCapitalSign: ok = compileBrailleIndicator (nested, "end capitals sign", - CTO_EndCapitalRule, &table->endCapitalSign); + CTO_EndCapitalRule); + if (ok) + table->endCapitalSign = newRuleOffset; break; case CTO_FirstWordCaps: ok = compileBrailleIndicator (nested, "first word capital sign", - CTO_FirstWordCapsRule, - &table->firstWordCaps); + CTO_FirstWordCapsRule); + if (ok) + table->firstWordCaps = newRuleOffset; break; case CTO_LastWordCapsBefore: ok = compileBrailleIndicator (nested, "capital sign before last word", - CTO_LastWordCapsBeforeRule, - &table->lastWordCapsBefore); + CTO_LastWordCapsBeforeRule); + if (ok) + table->lastWordCapsBefore = newRuleOffset; break; case CTO_LastWordCapsAfter: ok = compileBrailleIndicator (nested, "capital sign after last word", - CTO_LastWordCapsAfterRule, - &table->lastWordCapsAfter); + CTO_LastWordCapsAfterRule); + if (ok) + table->lastWordCapsAfter = newRuleOffset; break; case CTO_LenCapsPhrase: ok = table->lenCapsPhrase = compileNumber (nested); break; case CTO_LetterSign: ok = - compileBrailleIndicator (nested, "letter sign", CTO_LetterRule, - &table->letterSign); + compileBrailleIndicator (nested, "letter sign", CTO_LetterRule); + if (ok) + table->letterSign = newRuleOffset; break; case CTO_NoLetsignBefore: if (getRuleCharsText (nested, &ruleChars)) @@ -3959,52 +3954,60 @@ break; case CTO_NumberSign: ok = - compileBrailleIndicator (nested, "number sign", CTO_NumberRule, - &table->numberSign); + compileBrailleIndicator (nested, "number sign", CTO_NumberRule); + if (ok) + table->numberSign = newRuleOffset; break; case CTO_FirstWordItal: ok = compileBrailleIndicator (nested, "first word italic", - CTO_FirstWordItalRule, - &table->firstWordItal); + CTO_FirstWordItalRule); + if (ok) + table->firstWordItal = newRuleOffset; break; case CTO_ItalSign: case CTO_LastWordItalBefore: ok = compileBrailleIndicator (nested, "first word italic before", - CTO_LastWordItalBeforeRule, - &table->lastWordItalBefore); + CTO_LastWordItalBeforeRule); + if (ok) + table->lastWordItalBefore = newRuleOffset; break; case CTO_LastWordItalAfter: ok = compileBrailleIndicator (nested, "last word italic after", - CTO_LastWordItalAfterRule, - &table->lastWordItalAfter); + CTO_LastWordItalAfterRule); + if (ok) + table->lastWordItalAfter = newRuleOffset; break; case CTO_BegItal: case CTO_FirstLetterItal: ok = compileBrailleIndicator (nested, "first letter italic", - CTO_FirstLetterItalRule, - &table->firstLetterItal); + CTO_FirstLetterItalRule); + if (ok) + table->firstLetterItal = newRuleOffset; break; case CTO_EndItal: case CTO_LastLetterItal: ok = compileBrailleIndicator (nested, "last letter italic", - CTO_LastLetterItalRule, - &table->lastLetterItal); + CTO_LastLetterItalRule); + if (ok) + table->lastLetterItal = newRuleOffset; break; case CTO_SingleLetterItal: ok = compileBrailleIndicator (nested, "single letter italic", - CTO_SingleLetterItalRule, - &table->singleLetterItal); + CTO_SingleLetterItalRule); + if (ok) + table->singleLetterItal = newRuleOffset; break; case CTO_ItalWord: ok = - compileBrailleIndicator (nested, "italic word", CTO_ItalWordRule, - &table->italWord); + compileBrailleIndicator (nested, "italic word", CTO_ItalWordRule); + if (ok) + table->italWord = newRuleOffset; break; case CTO_LenItalPhrase: ok = table->lenItalPhrase = compileNumber (nested); @@ -4012,46 +4015,53 @@ case CTO_FirstWordBold: ok = compileBrailleIndicator (nested, "first word bold", - CTO_FirstWordBoldRule, - &table->firstWordBold); + CTO_FirstWordBoldRule); + if (ok) + table->firstWordBold = newRuleOffset; break; case CTO_BoldSign: case CTO_LastWordBoldBefore: ok = compileBrailleIndicator (nested, "last word bold before", - CTO_LastWordBoldBeforeRule, - &table->lastWordBoldBefore); + CTO_LastWordBoldBeforeRule); + if (ok) + table->lastWordBoldBefore = newRuleOffset; break; case CTO_LastWordBoldAfter: ok = compileBrailleIndicator (nested, "last word bold after", - CTO_LastWordBoldAfterRule, - &table->lastWordBoldAfter); + CTO_LastWordBoldAfterRule); + if (ok) + table->lastWordBoldAfter = newRuleOffset; break; case CTO_BegBold: case CTO_FirstLetterBold: ok = compileBrailleIndicator (nested, "first letter bold", - CTO_FirstLetterBoldRule, - &table->firstLetterBold); + CTO_FirstLetterBoldRule); + if (ok) + table->firstLetterBold = newRuleOffset; break; case CTO_EndBold: case CTO_LastLetterBold: ok = compileBrailleIndicator (nested, "last letter bold", - CTO_LastLetterBoldRule, - &table->lastLetterBold); + CTO_LastLetterBoldRule); + if (ok) + table->lastLetterBold = newRuleOffset; break; case CTO_SingleLetterBold: ok = compileBrailleIndicator (nested, "single letter bold", - CTO_SingleLetterBoldRule, - &table->singleLetterBold); + CTO_SingleLetterBoldRule); + if (ok) + table->singleLetterBold = newRuleOffset; break; case CTO_BoldWord: ok = - compileBrailleIndicator (nested, "bold word", CTO_BoldWordRule, - &table->boldWord); + compileBrailleIndicator (nested, "bold word", CTO_BoldWordRule); + if (ok) + table->boldWord = newRuleOffset; break; case CTO_LenBoldPhrase: ok = table->lenBoldPhrase = compileNumber (nested); @@ -4059,46 +4069,53 @@ case CTO_FirstWordUnder: ok = compileBrailleIndicator (nested, "first word underline", - CTO_FirstWordUnderRule, - &table->firstWordUnder); + CTO_FirstWordUnderRule); + if (ok) + table->firstWordUnder = newRuleOffset; break; case CTO_UnderSign: case CTO_LastWordUnderBefore: ok = compileBrailleIndicator (nested, "last word underline before", - CTO_LastWordUnderBeforeRule, - &table->lastWordUnderBefore); + CTO_LastWordUnderBeforeRule); + if (ok) + table->lastWordUnderBefore = newRuleOffset; break; case CTO_LastWordUnderAfter: ok = compileBrailleIndicator (nested, "last word underline after", - CTO_LastWordUnderAfterRule, - &table->lastWordUnderAfter); + CTO_LastWordUnderAfterRule); + if (ok) + table->lastWordUnderAfter = newRuleOffset; break; case CTO_BegUnder: case CTO_FirstLetterUnder: ok = compileBrailleIndicator (nested, "first letter underline", - CTO_FirstLetterUnderRule, - &table->firstLetterUnder); + CTO_FirstLetterUnderRule); + if (ok) + table->firstLetterUnder = newRuleOffset; break; case CTO_EndUnder: case CTO_LastLetterUnder: ok = compileBrailleIndicator (nested, "last letter underline", - CTO_LastLetterUnderRule, - &table->lastLetterUnder); + CTO_LastLetterUnderRule); + if (ok) + table->lastLetterUnder = newRuleOffset; break; case CTO_SingleLetterUnder: ok = compileBrailleIndicator (nested, "single letter underline", - CTO_SingleLetterUnderRule, - &table->singleLetterUnder); + CTO_SingleLetterUnderRule); + if (ok) + table->singleLetterUnder = newRuleOffset; break; case CTO_UnderWord: ok = - compileBrailleIndicator (nested, "underlined word", CTO_UnderWordRule, - &table->underWord); + compileBrailleIndicator (nested, "underlined word", CTO_UnderWordRule); + if (ok) + table->underWord = newRuleOffset; break; case CTO_LenUnderPhrase: ok = table->lenUnderPhrase = compileNumber (nested); @@ -4106,12 +4123,16 @@ case CTO_BegComp: ok = compileBrailleIndicator (nested, "begin computer braille", - CTO_BegCompRule, &table->begComp); + CTO_BegCompRule); + if (ok) + table->begComp = newRuleOffset; break; case CTO_EndComp: ok = compileBrailleIndicator (nested, "end computer braslle", - CTO_EndCompRule, &table->endComp); + CTO_EndCompRule); + if (ok) + table->endComp = newRuleOffset; break; case CTO_Syllable: table->syllables = 1; @@ -4748,10 +4769,10 @@ includeFile (FileInfo * nested, CharsString * includedFile) { int k; - char includeThis[MAXSTRING]; + char includeThis[MAXSTRING+1]; char **tableFiles; int rv; - for (k = 0; k < includedFile->length; k++) + for (k = 0; k < includedFile->length && k < MAXSTRING; k++) includeThis[k] = (char) includedFile->chars[k]; includeThis[k] = 0; tableFiles = resolveTable (includeThis, nested->fileName); diff --git a/tools/lou_translate.c b/tools/lou_translate.c --- a/tools/lou_translate.c +++ b/tools/lou_translate.c @@ -71,7 +71,7 @@ { translen = BUFSIZE; k = 0; - while ((ch = getchar ()) != '\n' && ch != EOF && k < BUFSIZE) + while ((ch = getchar ()) != '\n' && ch != EOF && k < BUFSIZE-1) charbuf[k++] = ch; if (ch == EOF && k == 0) break;