Check-in [40c17539ea]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:fixing a security issue - Cisco TALOS-2017-430 and TALOS-2017-431
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 40c17539ea56f0d82c349e83330d1d6160dd23ee
User & Date: sandro 2017-09-07 20:04:38
Context
2018-02-22
13:47
fixing security issues - Red Hat Bugzilla – Bug 1547892 check-in: 1f00f424a2 user: sandro tags: trunk
2017-09-07
20:04
fixing a security issue - Cisco TALOS-2017-430 and TALOS-2017-431 check-in: 40c17539ea user: sandro tags: trunk
2017-07-22
13:09
fixing a bug - badly parsing SSTLabels split on CONTINUE records check-in: ce4f2b2aaf user: sandro tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to config-msvc.h.

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "a.furieri@lqt.it"

/* Define to the full name of this package. */
#define PACKAGE_NAME "FreeXL"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "FreeXL 1.0.1"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "freexl"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "1.0.0e"

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1

/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */

/* Version number of package */
#define VERSION "1.0.1"

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

/* Define to empty if the keyword `volatile' does not work. Warning: valid
   code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */







|








|











|













82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "a.furieri@lqt.it"

/* Define to the full name of this package. */
#define PACKAGE_NAME "FreeXL"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "FreeXL 1.0.4"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "freexl"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "1.0.4"

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1

/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */

/* Version number of package */
#define VERSION "1.0.4"

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

/* Define to empty if the keyword `volatile' does not work. Warning: valid
   code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */

Changes to config.h.

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "a.furieri@lqt.it"

/* Define to the full name of this package. */
#define PACKAGE_NAME "FreeXL"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "FreeXL 1.0.3"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "freexl"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "1.0.3"

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1

/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */

/* Version number of package */
#define VERSION "1.0.3"

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

/* Define to empty if the keyword `volatile' does not work. Warning: valid
   code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */







|








|











|













80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "a.furieri@lqt.it"

/* Define to the full name of this package. */
#define PACKAGE_NAME "FreeXL"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "FreeXL 1.0.4"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "freexl"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "1.0.4"

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1

/* Define to 1 if your <sys/time.h> declares `struct tm'. */
/* #undef TM_IN_SYS_TIME */

/* Version number of package */
#define VERSION "1.0.4"

/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */

/* Define to `long int' if <sys/types.h> does not define. */
/* #undef off_t */

/* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */

/* Define to empty if the keyword `volatile' does not work. Warning: valid
   code using `volatile' can become incorrect without. Disable with care. */
/* #undef volatile */

Changes to configure.

1
2
3
4
5
6
7
8
9
10
...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
....
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
....
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
....
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
....
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
....
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
.....
17809
17810
17811
17812
17813
17814
17815
17816
17817
17818
17819
17820
17821
17822
17823
.....
17875
17876
17877
17878
17879
17880
17881
17882
17883
17884
17885
17886
17887
17888
17889
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for FreeXL 1.0.3.
#
# Report bugs to <a.furieri@lqt.it>.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
................................................................................
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME='FreeXL'
PACKAGE_TARNAME='freexl'
PACKAGE_VERSION='1.0.3'
PACKAGE_STRING='FreeXL 1.0.3'
PACKAGE_BUGREPORT='a.furieri@lqt.it'
PACKAGE_URL=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
................................................................................
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures FreeXL 1.0.3 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.
................................................................................
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of FreeXL 1.0.3:";;
   esac
  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
FreeXL configure 1.0.3
generated by GNU Autoconf 2.69

Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
................................................................................
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_type
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by FreeXL $as_me 1.0.3, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
................................................................................
    CYGPATH_W=echo
  fi
fi


# Define the identity of the package.
 PACKAGE='freexl'
 VERSION='1.0.3'


cat >>confdefs.h <<_ACEOF
#define PACKAGE "$PACKAGE"
_ACEOF


................................................................................
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by FreeXL $as_me 1.0.3, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@
................................................................................

Report bugs to <a.furieri@lqt.it>."

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
FreeXL config.status 1.0.3
configured by $0, generated by GNU Autoconf 2.69,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."



|







 







|
|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







1
2
3
4
5
6
7
8
9
10
...
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
....
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
....
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
....
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
....
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
....
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
.....
17809
17810
17811
17812
17813
17814
17815
17816
17817
17818
17819
17820
17821
17822
17823
.....
17875
17876
17877
17878
17879
17880
17881
17882
17883
17884
17885
17886
17887
17888
17889
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for FreeXL 1.0.4.
#
# Report bugs to <a.furieri@lqt.it>.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
................................................................................
subdirs=
MFLAGS=
MAKEFLAGS=

# Identity of this package.
PACKAGE_NAME='FreeXL'
PACKAGE_TARNAME='freexl'
PACKAGE_VERSION='1.0.4'
PACKAGE_STRING='FreeXL 1.0.4'
PACKAGE_BUGREPORT='a.furieri@lqt.it'
PACKAGE_URL=''

# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
................................................................................
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
  # Omit some internal or obsolete options to make the list less imposing.
  # This message is too long to be a string in the A/UX 3.1 sh.
  cat <<_ACEOF
\`configure' configures FreeXL 1.0.4 to adapt to many kinds of systems.

Usage: $0 [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.
................................................................................
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
_ACEOF
fi

if test -n "$ac_init_help"; then
  case $ac_init_help in
     short | recursive ) echo "Configuration of FreeXL 1.0.4:";;
   esac
  cat <<\_ACEOF

Optional Features:
  --disable-option-checking  ignore unrecognized --enable/--with options
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
    cd "$ac_pwd" || { ac_status=$?; break; }
  done
fi

test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
  cat <<\_ACEOF
FreeXL configure 1.0.4
generated by GNU Autoconf 2.69

Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
  exit
................................................................................
  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

} # ac_fn_c_check_type
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.

It was created by FreeXL $as_me 1.0.4, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  $ $0 $@

_ACEOF
exec 5>>config.log
{
................................................................................
    CYGPATH_W=echo
  fi
fi


# Define the identity of the package.
 PACKAGE='freexl'
 VERSION='1.0.4'


cat >>confdefs.h <<_ACEOF
#define PACKAGE "$PACKAGE"
_ACEOF


................................................................................
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1

cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by FreeXL $as_me 1.0.4, which was
generated by GNU Autoconf 2.69.  Invocation command line was

  CONFIG_FILES    = $CONFIG_FILES
  CONFIG_HEADERS  = $CONFIG_HEADERS
  CONFIG_LINKS    = $CONFIG_LINKS
  CONFIG_COMMANDS = $CONFIG_COMMANDS
  $ $0 $@
................................................................................

Report bugs to <a.furieri@lqt.it>."

_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
FreeXL config.status 1.0.4
configured by $0, generated by GNU Autoconf 2.69,
  with options \\"\$ac_cs_config\\"

Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."

Changes to configure.ac.

1
2
3
4
5
6
7
8
9
10
11
12
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.61)
AC_INIT(FreeXL, 1.0.3, a.furieri@lqt.it)
AC_LANG(C)
AC_CONFIG_AUX_DIR([.])
AC_CONFIG_MACRO_DIR([m4])

AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
AM_CONFIG_HEADER(config.h)




|







1
2
3
4
5
6
7
8
9
10
11
12
#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.61)
AC_INIT(FreeXL, 1.0.4, a.furieri@lqt.it)
AC_LANG(C)
AC_CONFIG_AUX_DIR([.])
AC_CONFIG_MACRO_DIR([m4])

AM_INIT_AUTOMAKE
AM_MAINTAINER_MODE
AM_CONFIG_HEADER(config.h)

Changes to src/freexl.c.

947
948
949
950
951
952
953















954
955
956
957
958
959
960
....
1391
1392
1393
1394
1395
1396
1397
1398

1399
1400
1401
1402
1403
1404
1405
....
1433
1434
1435
1436
1437
1438
1439
1440

1441
1442
1443
1444
1445
1446
1447
....
1494
1495
1496
1497
1498
1499
1500
1501

1502
1503
1504
1505
1506
1507
1508
....
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
....
1668
1669
1670
1671
1672
1673
1674

1675
1676
1677
1678
1679
1680
1681
1682
1683
....
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
....
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
....
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
....
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
....
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
....
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
....
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
....
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
....
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
....
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
....
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
....
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
....
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
....
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
....
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
....
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
....
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
....
3661
3662
3663
3664
3665
3666
3667

3668
3669
3670
3671
3672
3673
3674
3675
3676
....
3784
3785
3786
3787
3788
3789
3790








3791
3792
3793
3794
3795
3796
3797
....
3963
3964
3965
3966
3967
3968
3969

3970
3971
3972
3973
3974
3975
3976
3977
3978
	  p_cell->type = FREEXL_CELL_NULL;
	  return FREEXL_OK;
      }
    p_cell->type = FREEXL_CELL_SST_TEXT;
    p_cell->value.sst_value = text;
    return FREEXL_OK;
}
















static fat_chain *
alloc_fat_chain (int swap, unsigned short sector_shift,
		 unsigned int directory_start)
{
/* allocating the FAT chain */
    fat_chain *chain = malloc (sizeof (fat_chain));
................................................................................
	return FREEXL_CFBF_SEEK_ERROR;
    if (chain->sector_size == 4096)
	max_fat = 1024;
    else
	max_fat = 128;

/* reading a FAT sector */
    if (fread (buf, 1, chain->sector_size, xls) != chain->sector_size)

	return FREEXL_CFBF_READ_ERROR;

    for (i_fat = 0; i_fat < max_fat; i_fat++)
      {
	  int ret;
	  biff_word32 fat;
	  memcpy (fat.bytes, p_buf, 4);
................................................................................

    while (1)
      {
	  where = (next_sector + 1) * chain->sector_size;
	  if (fseek (xls, where, SEEK_SET) != 0)
	      return FREEXL_CFBF_SEEK_ERROR;
	  /* reading a DIFAT sector */
	  if (fread (&difat, 1, chain->sector_size, xls) != chain->sector_size)

	      return FREEXL_CFBF_READ_ERROR;
	  blocks++;
	  if (chain->swap)
	    {
		for (i_difat = 0; i_difat < max_difat; i_difat++)
		    swap32 (difat + i_difat);
	    }
................................................................................
    if (fseek (xls, where, SEEK_SET) != 0)
	return FREEXL_CFBF_SEEK_ERROR;
    while (block < num_sectors)
      {
	  unsigned char *p_buf = buf;
	  block++;
	  /* reading a miniFAT sector */
	  if (fread (&buf, 1, chain->sector_size, xls) != chain->sector_size)

	      return FREEXL_CFBF_READ_ERROR;
	  for (i_fat = 0; i_fat < max_fat; i_fat++)
	    {
		int ret;
		biff_word32 fat;
		memcpy (fat.bytes, p_buf, 4);
		p_buf += 4;
................................................................................
/* attempting to read and check FAT header */
    cfbf_header header;
    fat_chain *chain = NULL;
    int i_fat;
    int ret;
    unsigned char *p_fat = header.fat_sector_map;

    if (fread (&header, 1, 512, workbook->xls) != 512)
      {
	  *err_code = FREEXL_CFBF_READ_ERROR;
	  return NULL;
      }
    if (swap)
      {
	  /* BIG endian arch: swap required */
................................................................................
	  unsigned int size;
	  long where = (sector + 1) * workbook->fat->sector_size;
	  if (fseek (workbook->xls, where, SEEK_SET) != 0)
	    {
		*errcode = FREEXL_CFBF_SEEK_ERROR;
		return 0;
	    }

	  if (fread (buf, 1, workbook->fat->sector_size, workbook->xls) !=
	      workbook->fat->sector_size)
	    {
		*errcode = FREEXL_CFBF_READ_ERROR;
		return 0;
	    }
	  size = workbook->fat->sector_size;
	  if ((len + size) > workbook->fat->miniFAT_len)
	      size = workbook->fat->miniFAT_len - len;
................................................................................
    record_size.value = size;

    while (1)
      {
	  /* looping on BIFF records */
	  if (!first)
	    {
		if (fread (&buf, 1, 4, workbook->xls) != 4)
		    return 0;
		memcpy (record_type.bytes, buf, 2);
		memcpy (record_size.bytes, buf + 2, 2);
	    }
	  else
	      first = 0;
	  if (swap)
................................................................................

	  if (record_type.value == BIFF_INTEGER_2
	      && workbook->biff_version == FREEXL_BIFF_VER_2)
	    {
		/* INTEGER marker found */
		biff_word16 word16;

		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		if (word16.value > *rows)
		    *rows = word16.value;
................................................................................
	      || (record_type.value == BIFF_NUMBER
		  && (workbook->biff_version == FREEXL_BIFF_VER_3
		      || workbook->biff_version == FREEXL_BIFF_VER_4)))
	    {
		/* NUMBER marker found */
		biff_word16 word16;

		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		if (word16.value > *rows)
		    *rows = word16.value;
................................................................................
	      || (record_type.value == BIFF_BOOLERR
		  && (workbook->biff_version == FREEXL_BIFF_VER_3
		      || workbook->biff_version == FREEXL_BIFF_VER_4)))
	    {
		/* BOOLERR marker found */
		biff_word16 word16;

		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		if (word16.value > *rows)
		    *rows = word16.value;
................................................................................
	  if (record_type.value == BIFF_RK
	      && (workbook->biff_version == FREEXL_BIFF_VER_3
		  || workbook->biff_version == FREEXL_BIFF_VER_4))
	    {
		/* RK marker found */
		biff_word16 word16;

		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		if (word16.value > *rows)
		    *rows = word16.value;
................................................................................
	      || (record_type.value == BIFF_LABEL
		  && (workbook->biff_version == FREEXL_BIFF_VER_3
		      || workbook->biff_version == FREEXL_BIFF_VER_4)))
	    {
		/* LABEL marker found */
		biff_word16 word16;

		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		if (word16.value > *rows)
		    *rows = word16.value;
................................................................................
    biff_word16 record_type;
    biff_word16 record_size;
    unsigned char buf[16];
    unsigned short format_index = 0;

/* attempting to get the main BOF */
    rewind (workbook->xls);
    if (fread (&buf, 1, 4, workbook->xls) != 4)
	return 0;
    memcpy (record_type.bytes, buf, 2);
    memcpy (record_size.bytes, buf + 2, 2);
    if (swap)
      {
	  /* BIG endian arch: swap required */
	  swap16 (&record_type);
................................................................................
    if (fseek (workbook->xls, where, SEEK_CUR) != 0)
	return 0;

    while (1)
      {
	  /* looping on BIFF records */

	  if (fread (&buf, 1, 4, workbook->xls) != 4)
	      return 0;
	  memcpy (record_type.bytes, buf, 2);
	  memcpy (record_size.bytes, buf + 2, 2);
	  if (swap)
	    {
		/* BIG endian arch: swap required */
		swap16 (&record_type);
		swap16 (&record_size);
	    }

	  if (record_type.value == BIFF_SHEETSOFFSET)
	    {
/* unsupported BIFF4W format */
		return 0;
	    }

	  if (record_type.value == BIFF_EOF)
	    {
		/* EOF marker found: the current stream is terminated */
		return 1;
	    }

	  if (record_type.value == BIFF_CODEPAGE)
	    {
		/* CODEPAGE marker found */
		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;
		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		workbook->biff_code_page = word16.value;
		if (workbook->ok_bof == 1)
		    workbook->biff_book_code_page = word16.value;
................................................................................
		    return 0;
		continue;
	    }

	  if (record_type.value == BIFF_DATEMODE)
	    {
		/* DATEMODE marker found */
		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;
		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		workbook->biff_date_mode = word16.value;
		continue;
	    }
................................................................................
		char *utf8_string;
		unsigned int len;
		int err;
		unsigned char *p_string;
		int is_date = 0;
		int is_datetime = 0;
		int is_time = 0;
		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		if (workbook->biff_version == FREEXL_BIFF_VER_2
		    || workbook->biff_version == FREEXL_BIFF_VER_3)
		  {
		      len = *workbook->record;
		      p_string = workbook->record + 1;
................................................................................
		  && workbook->biff_version == FREEXL_BIFF_VER_3)
	      || (record_type.value == BIFF_XF_4
		  && workbook->biff_version == FREEXL_BIFF_VER_4))
	    {
		/* XF [Extended Format] marker found */
		unsigned char format;
		unsigned short s_format = 0;
		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;
		switch (workbook->biff_version)
		  {
		  case FREEXL_BIFF_VER_2:
		      format = *(workbook->record + 2);
		      format &= 0x3F;
		      s_format = format;
................................................................................
		      || workbook->biff_version == FREEXL_BIFF_VER_4)))
	    {
		/* DIMENSION marker found */
		biff_word16 word16;
		unsigned int rows;
		unsigned short columns;
		char *utf8_name;
		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record + 2, 2);
		if (swap)
		    swap16 (&word16);
		rows = word16.value;
		memcpy (word16.bytes, workbook->record + 6, 2);
................................................................................
		int ret;
		unsigned char format;

		if (!check_legacy_undeclared_dimension
		    (workbook, swap, record_type.value, record_size.value))
		    return 0;

		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		row = word16.value;
		memcpy (word16.bytes, workbook->record + 2, 2);
................................................................................
		int is_time;
		int ret;

		if (!check_legacy_undeclared_dimension
		    (workbook, swap, record_type.value, record_size.value))
		    return 0;

		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		row = word16.value;
		memcpy (word16.bytes, workbook->record + 2, 2);
................................................................................
		unsigned char value;
		int ret;

		if (!check_legacy_undeclared_dimension
		    (workbook, swap, record_type.value, record_size.value))
		    return 0;

		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		row = word16.value;
		memcpy (word16.bytes, workbook->record + 2, 2);
................................................................................
		int is_time;
		int ret;

		if (!check_legacy_undeclared_dimension
		    (workbook, swap, record_type.value, record_size.value))
		    return 0;

		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		row = word16.value;
		memcpy (word16.bytes, workbook->record + 2, 2);
................................................................................
		unsigned char *p_string;
		int ret;

		if (!check_legacy_undeclared_dimension
		    (workbook, swap, record_type.value, record_size.value))
		    return 0;

		if (fread
		    (workbook->record, 1, record_size.value,
		     workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		row = word16.value;
		memcpy (word16.bytes, workbook->record + 2, 2);
................................................................................
static int
read_cfbf_sector (biff_workbook * workbook, unsigned char *buf)
{
/* attempting to read a physical sector from the CFBF stream */
    long where = (workbook->current_sector + 1) * workbook->fat->sector_size;
    if (fseek (workbook->xls, where, SEEK_SET) != 0)
	return FREEXL_CFBF_SEEK_ERROR;

    if (fread (buf, 1, workbook->fat->sector_size, workbook->xls) !=
	workbook->fat->sector_size)
	return FREEXL_CFBF_READ_ERROR;
    return FREEXL_OK;
}

static int
read_cfbf_next_sector (biff_workbook * workbook, int *errcode)
{
................................................................................
/ Sandro 2011-09-04
/ apparently a record-type 0x0000 and a record-size 0
/ seems to be an alternative way to mark EOF
*/
    if (record_type.value == 0x0000 && record_size.value == 0)
	return -1;









/* saving the current record */
    workbook->record_type = record_type.value;
    workbook->record_size = record_size.value;

    if (((workbook->p_in + workbook->record_size) - workbook->sector_buf) >
	workbook->sector_end)
      {
................................................................................
    else
	max_entries = 4;

    where = (sector + 1) * workbook->fat->sector_size;
    if (fseek (workbook->xls, where, SEEK_SET) != 0)
	return FREEXL_CFBF_SEEK_ERROR;
/* reading a FAT Directory block [sector] */

    if (fread (dir_block, 1, workbook->fat->sector_size, workbook->xls) !=
	workbook->fat->sector_size)
	return FREEXL_CFBF_READ_ERROR;
    workbook_start = 0xFFFFFFFF;
    for (i_entry = 0; i_entry < max_entries; i_entry++)
      {
	  /* scanning dir entries until Workbook found */
	  p_entry = dir_block + (i_entry * 128);
	  ret =







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|
>







 







|
>







 







|
>







 







|







 







>
|
|







 







|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|







 







|












|












|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







|
|
|







 







>
|
|







 







>
>
>
>
>
>
>
>







 







>
|
|







947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
....
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
....
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
....
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
....
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
....
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
....
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
....
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
....
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
....
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
....
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
....
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
....
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
....
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
....
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
....
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
....
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
....
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
....
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
....
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
....
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
....
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
....
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
....
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
....
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
....
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
	  p_cell->type = FREEXL_CELL_NULL;
	  return FREEXL_OK;
      }
    p_cell->type = FREEXL_CELL_SST_TEXT;
    p_cell->value.sst_value = text;
    return FREEXL_OK;
}

static size_t
xls_fread (size_t bufsz, void *buf, size_t size, size_t nmemb, FILE * fl)
{
/* 
/ Sandro 2017-09-07
/ secure version of "fread" checking against buffer overflows 
/---------------------------
/ expected to fix the issue reported by
/ Cisco [TALOS-2017-431]
*/
    if ((size * nmemb) > bufsz)
	return 0;
    return fread (buf, size, nmemb, fl);
}

static fat_chain *
alloc_fat_chain (int swap, unsigned short sector_shift,
		 unsigned int directory_start)
{
/* allocating the FAT chain */
    fat_chain *chain = malloc (sizeof (fat_chain));
................................................................................
	return FREEXL_CFBF_SEEK_ERROR;
    if (chain->sector_size == 4096)
	max_fat = 1024;
    else
	max_fat = 128;

/* reading a FAT sector */
    if (xls_fread (sizeof (buf), buf, 1, chain->sector_size, xls) !=
	chain->sector_size)
	return FREEXL_CFBF_READ_ERROR;

    for (i_fat = 0; i_fat < max_fat; i_fat++)
      {
	  int ret;
	  biff_word32 fat;
	  memcpy (fat.bytes, p_buf, 4);
................................................................................

    while (1)
      {
	  where = (next_sector + 1) * chain->sector_size;
	  if (fseek (xls, where, SEEK_SET) != 0)
	      return FREEXL_CFBF_SEEK_ERROR;
	  /* reading a DIFAT sector */
	  if (xls_fread (sizeof (difat), &difat, 1, chain->sector_size, xls) !=
	      chain->sector_size)
	      return FREEXL_CFBF_READ_ERROR;
	  blocks++;
	  if (chain->swap)
	    {
		for (i_difat = 0; i_difat < max_difat; i_difat++)
		    swap32 (difat + i_difat);
	    }
................................................................................
    if (fseek (xls, where, SEEK_SET) != 0)
	return FREEXL_CFBF_SEEK_ERROR;
    while (block < num_sectors)
      {
	  unsigned char *p_buf = buf;
	  block++;
	  /* reading a miniFAT sector */
	  if (xls_fread (sizeof (buf), &buf, 1, chain->sector_size, xls) !=
	      chain->sector_size)
	      return FREEXL_CFBF_READ_ERROR;
	  for (i_fat = 0; i_fat < max_fat; i_fat++)
	    {
		int ret;
		biff_word32 fat;
		memcpy (fat.bytes, p_buf, 4);
		p_buf += 4;
................................................................................
/* attempting to read and check FAT header */
    cfbf_header header;
    fat_chain *chain = NULL;
    int i_fat;
    int ret;
    unsigned char *p_fat = header.fat_sector_map;

    if (xls_fread (sizeof (header), &header, 1, 512, workbook->xls) != 512)
      {
	  *err_code = FREEXL_CFBF_READ_ERROR;
	  return NULL;
      }
    if (swap)
      {
	  /* BIG endian arch: swap required */
................................................................................
	  unsigned int size;
	  long where = (sector + 1) * workbook->fat->sector_size;
	  if (fseek (workbook->xls, where, SEEK_SET) != 0)
	    {
		*errcode = FREEXL_CFBF_SEEK_ERROR;
		return 0;
	    }
	  if (xls_fread
	      (sizeof (buf), buf, 1, workbook->fat->sector_size,
	       workbook->xls) != workbook->fat->sector_size)
	    {
		*errcode = FREEXL_CFBF_READ_ERROR;
		return 0;
	    }
	  size = workbook->fat->sector_size;
	  if ((len + size) > workbook->fat->miniFAT_len)
	      size = workbook->fat->miniFAT_len - len;
................................................................................
    record_size.value = size;

    while (1)
      {
	  /* looping on BIFF records */
	  if (!first)
	    {
		if (xls_fread (sizeof (buf), &buf, 1, 4, workbook->xls) != 4)
		    return 0;
		memcpy (record_type.bytes, buf, 2);
		memcpy (record_size.bytes, buf + 2, 2);
	    }
	  else
	      first = 0;
	  if (swap)
................................................................................

	  if (record_type.value == BIFF_INTEGER_2
	      && workbook->biff_version == FREEXL_BIFF_VER_2)
	    {
		/* INTEGER marker found */
		biff_word16 word16;

		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		if (word16.value > *rows)
		    *rows = word16.value;
................................................................................
	      || (record_type.value == BIFF_NUMBER
		  && (workbook->biff_version == FREEXL_BIFF_VER_3
		      || workbook->biff_version == FREEXL_BIFF_VER_4)))
	    {
		/* NUMBER marker found */
		biff_word16 word16;

		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		if (word16.value > *rows)
		    *rows = word16.value;
................................................................................
	      || (record_type.value == BIFF_BOOLERR
		  && (workbook->biff_version == FREEXL_BIFF_VER_3
		      || workbook->biff_version == FREEXL_BIFF_VER_4)))
	    {
		/* BOOLERR marker found */
		biff_word16 word16;

		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		if (word16.value > *rows)
		    *rows = word16.value;
................................................................................
	  if (record_type.value == BIFF_RK
	      && (workbook->biff_version == FREEXL_BIFF_VER_3
		  || workbook->biff_version == FREEXL_BIFF_VER_4))
	    {
		/* RK marker found */
		biff_word16 word16;

		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		if (word16.value > *rows)
		    *rows = word16.value;
................................................................................
	      || (record_type.value == BIFF_LABEL
		  && (workbook->biff_version == FREEXL_BIFF_VER_3
		      || workbook->biff_version == FREEXL_BIFF_VER_4)))
	    {
		/* LABEL marker found */
		biff_word16 word16;

		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		if (word16.value > *rows)
		    *rows = word16.value;
................................................................................
    biff_word16 record_type;
    biff_word16 record_size;
    unsigned char buf[16];
    unsigned short format_index = 0;

/* attempting to get the main BOF */
    rewind (workbook->xls);
    if (xls_fread (sizeof (buf), &buf, 1, 4, workbook->xls) != 4)
	return 0;
    memcpy (record_type.bytes, buf, 2);
    memcpy (record_size.bytes, buf + 2, 2);
    if (swap)
      {
	  /* BIG endian arch: swap required */
	  swap16 (&record_type);
................................................................................
    if (fseek (workbook->xls, where, SEEK_CUR) != 0)
	return 0;

    while (1)
      {
	  /* looping on BIFF records */

	  if (xls_fread (sizeof (buf), &buf, 1, 4, workbook->xls) != 4)
	      return 0;
	  memcpy (record_type.bytes, buf, 2);
	  memcpy (record_size.bytes, buf + 2, 2);
	  if (swap)
	    {
		/* BIG endian arch: swap required */
		swap16 (&record_type);
		swap16 (&record_size);
	    }

	  if (record_type.value == BIFF_SHEETSOFFSET)
	    {
		/* unsupported BIFF4W format */
		return 0;
	    }

	  if (record_type.value == BIFF_EOF)
	    {
		/* EOF marker found: the current stream is terminated */
		return 1;
	    }

	  if (record_type.value == BIFF_CODEPAGE)
	    {
		/* CODEPAGE marker found */
		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;
		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		workbook->biff_code_page = word16.value;
		if (workbook->ok_bof == 1)
		    workbook->biff_book_code_page = word16.value;
................................................................................
		    return 0;
		continue;
	    }

	  if (record_type.value == BIFF_DATEMODE)
	    {
		/* DATEMODE marker found */
		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;
		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		workbook->biff_date_mode = word16.value;
		continue;
	    }
................................................................................
		char *utf8_string;
		unsigned int len;
		int err;
		unsigned char *p_string;
		int is_date = 0;
		int is_datetime = 0;
		int is_time = 0;
		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		if (workbook->biff_version == FREEXL_BIFF_VER_2
		    || workbook->biff_version == FREEXL_BIFF_VER_3)
		  {
		      len = *workbook->record;
		      p_string = workbook->record + 1;
................................................................................
		  && workbook->biff_version == FREEXL_BIFF_VER_3)
	      || (record_type.value == BIFF_XF_4
		  && workbook->biff_version == FREEXL_BIFF_VER_4))
	    {
		/* XF [Extended Format] marker found */
		unsigned char format;
		unsigned short s_format = 0;
		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;
		switch (workbook->biff_version)
		  {
		  case FREEXL_BIFF_VER_2:
		      format = *(workbook->record + 2);
		      format &= 0x3F;
		      s_format = format;
................................................................................
		      || workbook->biff_version == FREEXL_BIFF_VER_4)))
	    {
		/* DIMENSION marker found */
		biff_word16 word16;
		unsigned int rows;
		unsigned short columns;
		char *utf8_name;
		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record + 2, 2);
		if (swap)
		    swap16 (&word16);
		rows = word16.value;
		memcpy (word16.bytes, workbook->record + 6, 2);
................................................................................
		int ret;
		unsigned char format;

		if (!check_legacy_undeclared_dimension
		    (workbook, swap, record_type.value, record_size.value))
		    return 0;

		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		row = word16.value;
		memcpy (word16.bytes, workbook->record + 2, 2);
................................................................................
		int is_time;
		int ret;

		if (!check_legacy_undeclared_dimension
		    (workbook, swap, record_type.value, record_size.value))
		    return 0;

		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		row = word16.value;
		memcpy (word16.bytes, workbook->record + 2, 2);
................................................................................
		unsigned char value;
		int ret;

		if (!check_legacy_undeclared_dimension
		    (workbook, swap, record_type.value, record_size.value))
		    return 0;

		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		row = word16.value;
		memcpy (word16.bytes, workbook->record + 2, 2);
................................................................................
		int is_time;
		int ret;

		if (!check_legacy_undeclared_dimension
		    (workbook, swap, record_type.value, record_size.value))
		    return 0;

		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		row = word16.value;
		memcpy (word16.bytes, workbook->record + 2, 2);
................................................................................
		unsigned char *p_string;
		int ret;

		if (!check_legacy_undeclared_dimension
		    (workbook, swap, record_type.value, record_size.value))
		    return 0;

		if (xls_fread
		    (sizeof (workbook->record), workbook->record, 1,
		     record_size.value, workbook->xls) != record_size.value)
		    return 0;

		memcpy (word16.bytes, workbook->record, 2);
		if (swap)
		    swap16 (&word16);
		row = word16.value;
		memcpy (word16.bytes, workbook->record + 2, 2);
................................................................................
static int
read_cfbf_sector (biff_workbook * workbook, unsigned char *buf)
{
/* attempting to read a physical sector from the CFBF stream */
    long where = (workbook->current_sector + 1) * workbook->fat->sector_size;
    if (fseek (workbook->xls, where, SEEK_SET) != 0)
	return FREEXL_CFBF_SEEK_ERROR;
    if (xls_fread
	(sizeof (biff_workbook), buf, 1, workbook->fat->sector_size,
	 workbook->xls) != workbook->fat->sector_size)
	return FREEXL_CFBF_READ_ERROR;
    return FREEXL_OK;
}

static int
read_cfbf_next_sector (biff_workbook * workbook, int *errcode)
{
................................................................................
/ Sandro 2011-09-04
/ apparently a record-type 0x0000 and a record-size 0
/ seems to be an alternative way to mark EOF
*/
    if (record_type.value == 0x0000 && record_size.value == 0)
	return -1;

/*
/ Sandro 2017-09-07
/ fixing a security issue reported by
/ Cisco [TALOS-2017-430]
*/
    if (record_size.value > sizeof (workbook->record))
	return -1;

/* saving the current record */
    workbook->record_type = record_type.value;
    workbook->record_size = record_size.value;

    if (((workbook->p_in + workbook->record_size) - workbook->sector_buf) >
	workbook->sector_end)
      {
................................................................................
    else
	max_entries = 4;

    where = (sector + 1) * workbook->fat->sector_size;
    if (fseek (workbook->xls, where, SEEK_SET) != 0)
	return FREEXL_CFBF_SEEK_ERROR;
/* reading a FAT Directory block [sector] */
    if (xls_fread
	(sizeof (dir_block), dir_block, 1, workbook->fat->sector_size,
	 workbook->xls) != workbook->fat->sector_size)
	return FREEXL_CFBF_READ_ERROR;
    workbook_start = 0xFFFFFFFF;
    for (i_entry = 0; i_entry < max_entries; i_entry++)
      {
	  /* scanning dir entries until Workbook found */
	  p_entry = dir_block + (i_entry * 128);
	  ret =