hnj_hyphen_hyphword: fix buffer overflow (#13)
* Fix buffer overflow * hnj_hyphen_hyphword: rewrite, improve overflow checking * hnj_hyphen_hyphword: add test to detect overflows
This commit is contained in:
parent
726a506ef1
commit
a8d50da0cc
|
@ -67,7 +67,7 @@ main(int argc, char** argv)
|
|||
char *hyphens;
|
||||
char *lcword;
|
||||
char *hyphword;
|
||||
char hword[BUFSIZE * 2];
|
||||
char *hword;
|
||||
int arg = 1;
|
||||
int optd = 1;
|
||||
int optn = 0;
|
||||
|
@ -151,12 +151,16 @@ main(int argc, char** argv)
|
|||
rep = NULL;
|
||||
pos = NULL;
|
||||
cut = NULL;
|
||||
|
||||
/* set minimum required output buffer size (2 * word_size) */
|
||||
hword = (char *) malloc((n-1)*2);
|
||||
hword[0] = '\0';
|
||||
|
||||
if ((!optd && hnj_hyphen_hyphenate(dict, lcword, n-1, hyphens)) ||
|
||||
(optd && hnj_hyphen_hyphenate2(dict, lcword, n-1, hyphens, hword, &rep, &pos, &cut))) {
|
||||
free(hyphens);
|
||||
free(lcword);
|
||||
free(hword);
|
||||
fprintf(stderr, "hyphenation error\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -202,6 +206,7 @@ main(int argc, char** argv)
|
|||
}
|
||||
free(hyphens);
|
||||
free(lcword);
|
||||
free(hword);
|
||||
}
|
||||
|
||||
fclose(wtclst);
|
||||
|
|
45
hyphen.c
45
hyphen.c
|
@ -39,6 +39,7 @@
|
|||
#include <stdlib.h> /* for NULL, malloc */
|
||||
#include <stdio.h> /* for fprintf */
|
||||
#include <string.h> /* for strdup */
|
||||
#include <limits.h> /* for INT_MAX */
|
||||
|
||||
#ifdef UNX
|
||||
#include <unistd.h> /* for exit */
|
||||
|
@ -1073,23 +1074,41 @@ int hnj_hyphen_norm(const char *word, int word_size, char * hyphens,
|
|||
}
|
||||
|
||||
/* get the word with all possible hyphenations (output: hyphword) */
|
||||
void hnj_hyphen_hyphword(const char * word, int l, const char * hyphens,
|
||||
void hnj_hyphen_hyphword(const char * word, int word_size, const char * hyphens,
|
||||
char * hyphword, char *** rep, int ** pos, int ** cut)
|
||||
{
|
||||
int hyphenslen = l + 5;
|
||||
|
||||
int i, j;
|
||||
for (i = 0, j = 0; i < l; i++, j++) {
|
||||
if (hyphens[i]&1) {
|
||||
hyphword[j] = word[i];
|
||||
if (*rep && *pos && *cut && (*rep)[i]) {
|
||||
size_t offset = j - (*pos)[i] + 1;
|
||||
strncpy(hyphword + offset, (*rep)[i], hyphenslen - offset - 1);
|
||||
hyphword[hyphenslen-1] = '\0';
|
||||
j += strlen((*rep)[i]) - (*pos)[i];
|
||||
if (word_size <= 0 || word_size > INT_MAX / 2) {
|
||||
hyphword[0] = '\0';
|
||||
return;
|
||||
}
|
||||
|
||||
/* hyphword buffer size must be at least 2 * l */
|
||||
int hyphword_size = 2 * word_size - 1;
|
||||
|
||||
int nonstandard = 0;
|
||||
if (*rep && *pos && *cut) {
|
||||
nonstandard = 1;
|
||||
}
|
||||
|
||||
int i;
|
||||
int j = 0;
|
||||
for (i = 0; i < word_size && j < hyphword_size; i++) {
|
||||
hyphword[j++] = word[i];
|
||||
if (hyphens[i]&1 && j < hyphword_size) {
|
||||
if (nonstandard && (*rep)[i] && j >= (*pos)[i]) {
|
||||
/* non-standard */
|
||||
j -= (*pos)[i];
|
||||
char *s = (*rep)[i];
|
||||
while (*s && j < hyphword_size) {
|
||||
hyphword[j++] = *s++;
|
||||
}
|
||||
i += (*cut)[i] - (*pos)[i];
|
||||
} else hyphword[++j] = '=';
|
||||
} else hyphword[j] = word[i];
|
||||
} else {
|
||||
/* standard */
|
||||
hyphword[j++] = '=';
|
||||
}
|
||||
}
|
||||
}
|
||||
hyphword[j] = '\0';
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ alt3.test \
|
|||
alt4.test \
|
||||
alt5.test \
|
||||
alt6.test \
|
||||
alt7.test \
|
||||
compound.test \
|
||||
compound2.test \
|
||||
compound3.test \
|
||||
|
@ -46,6 +47,9 @@ alt5.word \
|
|||
alt6.hyph \
|
||||
alt6.pat \
|
||||
alt6.word \
|
||||
alt7.hyph \
|
||||
alt7.pat \
|
||||
alt7.word \
|
||||
alt.hyph \
|
||||
alt.pat \
|
||||
alt.word \
|
||||
|
@ -100,6 +104,7 @@ alt3.test \
|
|||
alt4.test \
|
||||
alt5.test \
|
||||
alt6.test \
|
||||
alt7.test \
|
||||
alt.test \
|
||||
basealt2.test \
|
||||
basealt.test \
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
b=bbbbbbbbbbbbbbbbbbbbbba=a=a=a=a=a=a=a=a=a=a=a=a=a=a=a
|
||||
b=bbbbbbbbbbbbbbbbbbbbbba=b=bbbbbbbbbbbbbbbbbbbbbba=b=b
|
|
@ -0,0 +1,7 @@
|
|||
ISO8859-1
|
||||
LEFTHYPHENMIN 1
|
||||
RIGHTHYPHENMIN 1
|
||||
% Check for buffer overflows
|
||||
.a1b.
|
||||
a9a
|
||||
ab3a/b=bbbbbbbbbbbbbbbbbbbbbb,1,2
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
DIR="`dirname $0`"
|
||||
NAME="`basename $0 .test`"
|
||||
$DIR/test.sh $NAME.pat $NAME.word $NAME.hyph
|
|
@ -0,0 +1,2 @@
|
|||
abaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
abaabaababababababababababab
|
Loading…
Reference in New Issue