bugGNU Octave - Bugs: bug #55400, contour3 causes...

 
 

bug #55400: contour3 causes heap-buffer-overflow with memory sanitizer

Submitter:  Dmitri A. Sergatskov <dasergatskov>
Submitted:  Sun 06 Jan 2019 01:16:35 AM UTC
 
Category:  Plotting Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Segfault, Bus Error, etc.
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * 5.0.1 Operating System:  * Any
* Mandatory Fields

Add a New Comment (Rich Markup)
   

Comment Type & Canned Response:
       

 

Sun 06 Jan 2019 01:59:26 PM UTC, comment #5: 

Thanks for testing.

I pushed the patch here:
http://hg.savannah.gnu.org/hgweb/octave/rev/a8b8b0726b08

Closing as fixed.

Markus Mützel <mmuetzel>
Project Member
Sun 06 Jan 2019 01:51:31 PM UTC, comment #4: 

Yes, this patch solve those crashes.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Sun 06 Jan 2019 10:43:06 AM UTC, comment #3: 

Thanks for reporting.
I am still not able to correctly set up the build with asan.

Could you please try if the attached diff fixes this issue for you?

(file #45882)

Markus Mützel <mmuetzel>
Project Member
Sun 06 Jan 2019 02:43:40 AM UTC, comment #2: 

The others affected are ezsurfc, surfc, and meshc.
The rest of demos go through.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Sun 06 Jan 2019 01:27:31 AM UTC, comment #1: 

I got the same crash (pointing to graphics.cc:9456)
doing "demo ezmeshc"

Perhaps the title should be not specific to contour3.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Sun 06 Jan 2019 01:16:35 AM UTC, original submission:  

When compiled with address sanitizer (with or without Qt)
contour3(peaks(19)) causes:

octave:1> contour3(peaks(19))
=================================================================
==8114==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x606001488c00 at pc 0x7fc08d71a9b4 bp 0x7ffc92a0b8d0 sp 0x7ffc92a0b8c0
READ of size 8 at 0x606001488c00 thread T0
    #0 0x7fc08d71a9b3 in patch::properties::update_data() ../libinterp/corefcn/graphics.cc:9456
    #1 0x7fc08d7ab9b3 in patch::properties::update_faces() libinterp/corefcn/graphics.h:9385
    #2 0x7fc08d7a8310 in patch::properties::set_faces(octave_value const&) libinterp/corefcn/graphics.h:9079
    #3 0x7fc08d5c613e in patch::properties::set(caseless_str const&, octave_value const&) libinterp/corefcn/graphics-props.cc:4584
    #4 0x7fc08d7755a6 in base_graphics_object::set(caseless_str const&, octave_value const&) libinterp/corefcn/graphics.h:2689
    #5 0x7fc08d498929 in graphics_object::set_value_or_default(caseless_str const&, octave_value const&) ../libinterp/corefcn/graphics.cc:2652
    #6 0x7fc08d497994 in graphics_object::set(octave_value_list const&) ../libinterp/corefcn/graphics.cc:2431
    #7 0x7fc08d49a0d0 in xset ../libinterp/corefcn/graphics.cc:2825
    #8 0x7fc08d750f84 in make_graphics_object ../libinterp/corefcn/graphics.cc:12475
    #9 0x7fc08d7547a0 in F__go_patch__(octave_value_list const&, int) ../libinterp/corefcn/graphics.cc:12693
    #10 0x7fc08cc38190 in octave_builtin::call(octave::tree_evaluator&, int, octave_value_list const&) ../libinterp/octave-value/ov-builtin.cc:65
    #11 0x7fc08d0a7efe in octave::tree_evaluator::visit_index_expression(octave::tree_index_expression&) ../libinterp/parse-tree/pt-eval.cc:2007
    #12 0x7fc08d0e3444 in octave::tree_index_expression::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-idx.h:102
    #13 0x7fc08cd0bda1 in octave::tree_evaluator::evaluate(octave::tree_expression*, int) ../libinterp/parse-tree/pt-eval.h:312
    #14 0x7fc08d0fd957 in octave::tm_row_const::init(octave::tree_argument_list const&, octave::tree_evaluator&) ../libinterp/parse-tree/pt-tm-const.cc:168
    #15 0x7fc08d104fbf in octave::tm_row_const::tm_row_const(octave::tree_argument_list const&, octave::tree_evaluator&) ../libinterp/parse-tree/pt-tm-const.h:154
    #16 0x7fc08d100471 in octave::tm_const::init(octave::tree_matrix const&) ../libinterp/parse-tree/pt-tm-const.cc:308
    #17 0x7fc08d0c2512 in octave::tm_const::tm_const(octave::tree_matrix const&, octave::tree_evaluator&) (/home/dima/src/octave/gcc_asan_min/libinterp/.libs/liboctinterp.so.6+0x173f512)
    #18 0x7fc08d0a9d2e in octave::tree_evaluator::visit_matrix(octave::tree_matrix&) ../libinterp/parse-tree/pt-eval.cc:2226
    #19 0x7fc08d0ebb9e in octave::tree_matrix::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-mat.h:70
    #20 0x7fc08cd0bda1 in octave::tree_evaluator::evaluate(octave::tree_expression*, int) ../libinterp/parse-tree/pt-eval.h:312
    #21 0x7fc08d0aefc1 in octave::tree_evaluator::visit_simple_assignment(octave::tree_simple_assignment&) ../libinterp/parse-tree/pt-eval.cc:2680
    #22 0x7fc08d085c9a in octave::tree_simple_assignment::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-assign.h:84
    #23 0x7fc08cd0bda1 in octave::tree_evaluator::evaluate(octave::tree_expression*, int) ../libinterp/parse-tree/pt-eval.h:312
    #24 0x7fc08d0b027b in octave::tree_evaluator::visit_statement(octave::tree_statement&) ../libinterp/parse-tree/pt-eval.cc:2775
    #25 0x7fc08d0facc6 in octave::tree_statement::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:119
    #26 0x7fc08d0b095c in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) ../libinterp/parse-tree/pt-eval.cc:2844
    #27 0x7fc08cd0c9cc in octave::tree_statement_list::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:194
    #28 0x7fc08d0b10e0 in octave::tree_evaluator::visit_switch_command(octave::tree_switch_command&) ../libinterp/parse-tree/pt-eval.cc:2919
    #29 0x7fc08d0f7af6 in octave::tree_switch_command::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-select.h:276
    #30 0x7fc08d0b00a6 in octave::tree_evaluator::visit_statement(octave::tree_statement&) ../libinterp/parse-tree/pt-eval.cc:2753
    #31 0x7fc08d0facc6 in octave::tree_statement::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:119
    #32 0x7fc08d0b095c in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) ../libinterp/parse-tree/pt-eval.cc:2844
    #33 0x7fc08cd0c9cc in octave::tree_statement_list::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:194
    #34 0x7fc08d0b2e68 in octave::tree_evaluator::visit_while_command(octave::tree_while_command&) ../libinterp/parse-tree/pt-eval.cc:3172
    #35 0x7fc08d0eb28c in octave::tree_while_command::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-loop.h:95
    #36 0x7fc08d0b00a6 in octave::tree_evaluator::visit_statement(octave::tree_statement&) ../libinterp/parse-tree/pt-eval.cc:2753
    #37 0x7fc08d0facc6 in octave::tree_statement::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:119
    #38 0x7fc08d0b095c in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) ../libinterp/parse-tree/pt-eval.cc:2844
    #39 0x7fc08cd0c9cc in octave::tree_statement_list::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:194
    #40 0x7fc08d0a70f7 in octave::tree_evaluator::visit_if_command_list(octave::tree_if_command_list&) ../libinterp/parse-tree/pt-eval.cc:1862
    #41 0x7fc08d089d2e in octave::tree_if_command_list::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-select.h:115
    #42 0x7fc08d0a6d09 in octave::tree_evaluator::visit_if_command(octave::tree_if_command&) ../libinterp/parse-tree/pt-eval.cc:1840
    #43 0x7fc08d0f7a0e in octave::tree_if_command::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-select.h:148
    #44 0x7fc08d0b00a6 in octave::tree_evaluator::visit_statement(octave::tree_statement&) ../libinterp/parse-tree/pt-eval.cc:2753
    #45 0x7fc08d0facc6 in octave::tree_statement::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:119
    #46 0x7fc08d0b095c in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) ../libinterp/parse-tree/pt-eval.cc:2844
    #47 0x7fc08cd0c9cc in octave::tree_statement_list::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:194
    #48 0x7fc08d0a5040 in octave::tree_evaluator::execute_user_function(octave_user_function&, int, octave_value_list const&) ../libinterp/parse-tree/pt-eval.cc:1694
    #49 0x7fc08ce8bf8e in octave_user_function::call(octave::tree_evaluator&, int, octave_value_list const&) ../libinterp/octave-value/ov-usr-fcn.cc:455
    #50 0x7fc08d0a7efe in octave::tree_evaluator::visit_index_expression(octave::tree_index_expression&) ../libinterp/parse-tree/pt-eval.cc:2007
    #51 0x7fc08d0e3444 in octave::tree_index_expression::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-idx.h:102
    #52 0x7fc08cd0bda1 in octave::tree_evaluator::evaluate(octave::tree_expression*, int) ../libinterp/parse-tree/pt-eval.h:312
    #53 0x7fc08d0b027b in octave::tree_evaluator::visit_statement(octave::tree_statement&) ../libinterp/parse-tree/pt-eval.cc:2775
    #54 0x7fc08d0facc6 in octave::tree_statement::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:119
    #55 0x7fc08d0b095c in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) ../libinterp/parse-tree/pt-eval.cc:2844
    #56 0x7fc08cd0c9cc in octave::tree_statement_list::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:194
    #57 0x7fc08d0a5040 in octave::tree_evaluator::execute_user_function(octave_user_function&, int, octave_value_list const&) ../libinterp/parse-tree/pt-eval.cc:1694
    #58 0x7fc08ce8bf8e in octave_user_function::call(octave::tree_evaluator&, int, octave_value_list const&) ../libinterp/octave-value/ov-usr-fcn.cc:455
    #59 0x7fc08d0a7efe in octave::tree_evaluator::visit_index_expression(octave::tree_index_expression&) ../libinterp/parse-tree/pt-eval.cc:2007
    #60 0x7fc08d0e3444 in octave::tree_index_expression::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-idx.h:102
    #61 0x7fc08d0c056d in octave::tree_evaluator::evaluate_n(octave::tree_expression*, int) ../libinterp/parse-tree/pt-eval.h:343
    #62 0x7fc08d0ab20e in octave::tree_evaluator::visit_multi_assignment(octave::tree_multi_assignment&) ../libinterp/parse-tree/pt-eval.cc:2319
    #63 0x7fc08d085de0 in octave::tree_multi_assignment::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-assign.h:153
    #64 0x7fc08cd0bda1 in octave::tree_evaluator::evaluate(octave::tree_expression*, int) ../libinterp/parse-tree/pt-eval.h:312
    #65 0x7fc08d0b027b in octave::tree_evaluator::visit_statement(octave::tree_statement&) ../libinterp/parse-tree/pt-eval.cc:2775
    #66 0x7fc08d0facc6 in octave::tree_statement::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:119
    #67 0x7fc08d0b095c in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) ../libinterp/parse-tree/pt-eval.cc:2844
    #68 0x7fc08cd0c9cc in octave::tree_statement_list::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:194
    #69 0x7fc08d0b2a22 in octave::tree_evaluator::visit_unwind_protect_command(octave::tree_unwind_protect_command&) ../libinterp/parse-tree/pt-eval.cc:3100
    #70 0x7fc08d0db1d4 in octave::tree_unwind_protect_command::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-except.h:148
    #71 0x7fc08d0b00a6 in octave::tree_evaluator::visit_statement(octave::tree_statement&) ../libinterp/parse-tree/pt-eval.cc:2753
    #72 0x7fc08d0facc6 in octave::tree_statement::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:119
    #73 0x7fc08d0b095c in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) ../libinterp/parse-tree/pt-eval.cc:2844
    #74 0x7fc08cd0c9cc in octave::tree_statement_list::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:194
    #75 0x7fc08d0a5040 in octave::tree_evaluator::execute_user_function(octave_user_function&, int, octave_value_list const&) ../libinterp/parse-tree/pt-eval.cc:1694
    #76 0x7fc08ce8bf8e in octave_user_function::call(octave::tree_evaluator&, int, octave_value_list const&) ../libinterp/octave-value/ov-usr-fcn.cc:455
    #77 0x7fc08d0a7efe in octave::tree_evaluator::visit_index_expression(octave::tree_index_expression&) ../libinterp/parse-tree/pt-eval.cc:2007
    #78 0x7fc08d0e3444 in octave::tree_index_expression::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-idx.h:102
    #79 0x7fc08cd0bda1 in octave::tree_evaluator::evaluate(octave::tree_expression*, int) ../libinterp/parse-tree/pt-eval.h:312
    #80 0x7fc08d0b027b in octave::tree_evaluator::visit_statement(octave::tree_statement&) ../libinterp/parse-tree/pt-eval.cc:2775
    #81 0x7fc08d0facc6 in octave::tree_statement::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:119
    #82 0x7fc08d0b095c in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) ../libinterp/parse-tree/pt-eval.cc:2844
    #83 0x7fc08cd0c9cc in octave::tree_statement_list::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-stmt.h:194
    #84 0x7fc08d09614f in octave::tree_evaluator::repl(bool) ../libinterp/parse-tree/pt-eval.cc:105
    #85 0x7fc08d855d50 in octave::interpreter::main_loop() ../libinterp/corefcn/interpreter.cc:949
    #86 0x7fc08d852df3 in octave::interpreter::execute() ../libinterp/corefcn/interpreter.cc:694
    #87 0x7fc08c1c8d5e in octave::cli_application::execute() ../libinterp/octave.cc:391
    #88 0x402954 in main ../src/main-cli.cc:92
    #89 0x7fc0863fa412 in __libc_start_main (/lib64/libc.so.6+0x24412)
    #90 0x4022ad in _start (/home/dima/src/octave/gcc_asan_min/src/.libs/lt-octave-cli+0x4022ad)

0x606001488c00 is located 0 bytes to the right of 64-byte region [0x606001488bc0,0x606001488c00)
allocated by thread T0 here:
    #0 0x7fc08e423650 in operator new[](unsigned long) (/lib64/libasan.so.5+0xf1650)
    #1 0x7fc08c27fc6a in Array<double>::ArrayRep::ArrayRep(double*, long) ../liboctave/array/Array.h:140
    #2 0x7fc08c3faf49 in Array<double>::make_unique() ../liboctave/array/Array.h:191
    #3 0x7fc08c3f86e9 in Array<double>::elem(long) ../liboctave/array/Array.h:490
    #4 0x7fc08c73ba17 in Array<double>::elem(long, long) ../liboctave/array/Array.h:494
    #5 0x7fc08ce3286a in Array<double>::operator()(long, long) ../liboctave/array/Array.h:503
    #6 0x7fc08d71a934 in patch::properties::update_data() ../libinterp/corefcn/graphics.cc:9452
    #7 0x7fc08d7ab9b3 in patch::properties::update_faces() libinterp/corefcn/graphics.h:9385
    #8 0x7fc08d7a8310 in patch::properties::set_faces(octave_value const&) libinterp/corefcn/graphics.h:9079
    #9 0x7fc08d5c613e in patch::properties::set(caseless_str const&, octave_value const&) libinterp/corefcn/graphics-props.cc:4584
    #10 0x7fc08d7755a6 in base_graphics_object::set(caseless_str const&, octave_value const&) libinterp/corefcn/graphics.h:2689
    #11 0x7fc08d498929 in graphics_object::set_value_or_default(caseless_str const&, octave_value const&) ../libinterp/corefcn/graphics.cc:2652
    #12 0x7fc08d497994 in graphics_object::set(octave_value_list const&) ../libinterp/corefcn/graphics.cc:2431
    #13 0x7fc08d49a0d0 in xset ../libinterp/corefcn/graphics.cc:2825
    #14 0x7fc08d750f84 in make_graphics_object ../libinterp/corefcn/graphics.cc:12475
    #15 0x7fc08d7547a0 in F__go_patch__(octave_value_list const&, int) ../libinterp/corefcn/graphics.cc:12693
    #16 0x7fc08cc38190 in octave_builtin::call(octave::tree_evaluator&, int, octave_value_list const&) ../libinterp/octave-value/ov-builtin.cc:65
    #17 0x7fc08d0a7efe in octave::tree_evaluator::visit_index_expression(octave::tree_index_expression&) ../libinterp/parse-tree/pt-eval.cc:2007
    #18 0x7fc08d0e3444 in octave::tree_index_expression::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-idx.h:102
    #19 0x7fc08cd0bda1 in octave::tree_evaluator::evaluate(octave::tree_expression*, int) ../libinterp/parse-tree/pt-eval.h:312
    #20 0x7fc08d0fd957 in octave::tm_row_const::init(octave::tree_argument_list const&, octave::tree_evaluator&) ../libinterp/parse-tree/pt-tm-const.cc:168
    #21 0x7fc08d104fbf in octave::tm_row_const::tm_row_const(octave::tree_argument_list const&, octave::tree_evaluator&) ../libinterp/parse-tree/pt-tm-const.h:154
    #22 0x7fc08d100471 in octave::tm_const::init(octave::tree_matrix const&) ../libinterp/parse-tree/pt-tm-const.cc:308
    #23 0x7fc08d0c2512 in octave::tm_const::tm_const(octave::tree_matrix const&, octave::tree_evaluator&) (/home/dima/src/octave/gcc_asan_min/libinterp/.libs/liboctinterp.so.6+0x173f512)
    #24 0x7fc08d0a9d2e in octave::tree_evaluator::visit_matrix(octave::tree_matrix&) ../libinterp/parse-tree/pt-eval.cc:2226
    #25 0x7fc08d0ebb9e in octave::tree_matrix::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-mat.h:70
    #26 0x7fc08cd0bda1 in octave::tree_evaluator::evaluate(octave::tree_expression*, int) ../libinterp/parse-tree/pt-eval.h:312
    #27 0x7fc08d0aefc1 in octave::tree_evaluator::visit_simple_assignment(octave::tree_simple_assignment&) ../libinterp/parse-tree/pt-eval.cc:2680
    #28 0x7fc08d085c9a in octave::tree_simple_assignment::accept(octave::tree_walker&) ../libinterp/parse-tree/pt-assign.h:84
    #29 0x7fc08cd0bda1 in octave::tree_evaluator::evaluate(octave::tree_expression*, int) ../libinterp/parse-tree/pt-eval.h:312

SUMMARY: AddressSanitizer: heap-buffer-overflow ../libinterp/corefcn/graphics.cc:9456 in patch::properties::update_data()
Shadow bytes around the buggy address:
  0x0c0c80289130: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
  0x0c0c80289140: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c0c80289150: fa fa fa fa 00 00 00 00 00 00 00 00 fa fa fa fa
  0x0c0c80289160: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
  0x0c0c80289170: fd fd fd fd fa fa fa fa 00 00 00 00 00 00 00 00
=>0x0c0c80289180:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c80289190: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c802891a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c802891b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c802891c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c802891d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==8114==ABORTING

This particular trace is on octave w/o qt.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #45882:  bug55400_heap-buffer-overflow.diff added by mmuetzel (561B - application/octet-stream)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by mmuetzel (Updated the item)
  • -email is unavailable- added by dasergatskov (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only project members can vote.

     

     

     

     

    Follow 4 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2019-01-06 mmuetzel StatusNone Fixed
        Open/ClosedOpen Closed
        Operating SystemGNU/Linux Any
    2019-01-06 mmuetzel Attached File- Added bug55400_heap-buffer-overflow.diff, #45882

    Back to the top


    Powered by Savane 3.9