X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gettext-tools%2Fsrc%2Fread-mo.c;h=c3bfb22f3a186556600807b93e18bf3771151c74;hb=2d875e23d946ff9bf4d3ac469e909b83486123a4;hp=9e0220ce4338f492374ae1dfa67d7a87a472d8ab;hpb=5d61132f836323aaf2879e04abc9d4056db248a2;p=platform%2Fupstream%2Fgettext.git diff --git a/gettext-tools/src/read-mo.c b/gettext-tools/src/read-mo.c index 9e0220c..c3bfb22 100644 --- a/gettext-tools/src/read-mo.c +++ b/gettext-tools/src/read-mo.c @@ -1,5 +1,6 @@ /* Reading binary .mo files. - Copyright (C) 1995-1998, 2000-2007 Free Software Foundation, Inc. + Copyright (C) 1995-1998, 2000-2007, 2015 Free Software Foundation, + Inc. Written by Ulrich Drepper , April 1995. This program is free software: you can redistribute it and/or modify @@ -38,6 +39,7 @@ #include "message.h" #include "format.h" #include "gettext.h" +#include "xsize.h" #define _(str) gettext (str) @@ -100,8 +102,9 @@ static nls_uint32 get_uint32 (const struct binary_mo_file *bfp, size_t offset) { nls_uint32 b0, b1, b2, b3; + size_t end = xsum (offset, 4); - if (offset + 4 > bfp->size) + if (size_overflow_p (end) || end > bfp->size) error (EXIT_FAILURE, 0, _("file \"%s\" is truncated"), bfp->filename); b0 = *(unsigned char *) (bfp->data + offset + 0); @@ -121,8 +124,9 @@ get_string (const struct binary_mo_file *bfp, size_t offset, size_t *lengthp) /* See 'struct string_desc'. */ nls_uint32 s_length = get_uint32 (bfp, offset); nls_uint32 s_offset = get_uint32 (bfp, offset + 4); + size_t s_end = xsum3 (s_offset, s_length, 1); - if (s_offset + s_length + 1 > bfp->size) + if (size_overflow_p (s_end) || s_end > bfp->size) error (EXIT_FAILURE, 0, _("file \"%s\" is truncated"), bfp->filename); if (bfp->data[s_offset + s_length] != '\0') error (EXIT_FAILURE, 0, @@ -146,6 +150,7 @@ get_sysdep_string (const struct binary_mo_file *bfp, size_t offset, nls_uint32 s_offset; /* Compute the length. */ + s_offset = get_uint32 (bfp, offset); length = 0; for (i = 4; ; i += 8) { @@ -154,9 +159,15 @@ get_sysdep_string (const struct binary_mo_file *bfp, size_t offset, nls_uint32 sysdep_segment_offset; nls_uint32 ss_length; nls_uint32 ss_offset; + size_t ss_end; + size_t s_end; size_t n; + s_end = xsum (s_offset, segsize); + if (size_overflow_p (s_end) || s_end > bfp->size) + error (EXIT_FAILURE, 0, _("file \"%s\" is truncated"), bfp->filename); length += segsize; + s_offset += segsize; if (sysdepref == SEGMENTS_END) break; @@ -168,9 +179,10 @@ get_sysdep_string (const struct binary_mo_file *bfp, size_t offset, sysdep_segment_offset = header->sysdep_segments_offset + sysdepref * 8; ss_length = get_uint32 (bfp, sysdep_segment_offset); ss_offset = get_uint32 (bfp, sysdep_segment_offset + 4); - if (ss_offset + ss_length > bfp->size) + ss_end = xsum (ss_offset, ss_length); + if (size_overflow_p (ss_end) || ss_end > bfp->size) error (EXIT_FAILURE, 0, _("file \"%s\" is truncated"), bfp->filename); - if (!(ss_length > 0 && bfp->data[ss_offset + ss_length - 1] == '\0')) + if (!(ss_length > 0 && bfp->data[ss_end - 1] == '\0')) { char location[30]; sprintf (location, "sysdep_segment[%u]", (unsigned int) sysdepref); @@ -195,8 +207,6 @@ get_sysdep_string (const struct binary_mo_file *bfp, size_t offset, nls_uint32 ss_offset; size_t n; - if (s_offset + segsize > bfp->size) - error (EXIT_FAILURE, 0, _("file \"%s\" is truncated"), bfp->filename); memcpy (p, bfp->data + s_offset, segsize); p += segsize; s_offset += segsize;