summaryrefslogtreecommitdiff
path: root/client/mysqlbinlog.cc
Commit message (Collapse)AuthorAgeFilesLines
* merge from mysql-5.1 to mysql-5.5Sujatha Sivakumar2013-03-181-15/+31
|\
| * Bug#14771299 OUT-OF-BOUND READS WRITE IN MYSQLBINLOGSujatha Sivakumar2013-03-181-15/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: ======= Found using AddressSanitizer testing. The mysqlbinlog utility may result in out-of-bound heap buffer reads and thus, undefined behaviour, when processing RBR events in the old (pre-5.1 GA) format. The following code in process_event() would only be correct if Rows_log_event was the base class for Write,Update,Delete_rows_log_event_old classes: case PRE_GA_WRITE_ROWS_EVENT: case PRE_GA_DELETE_ROWS_EVENT: case PRE_GA_UPDATE_ROWS_EVENT: ... Rows_log_event *e= (Rows_log_event*) ev; Table_map_log_event *ignored_map= print_event_info->m_table_map_ignored.get_table(e->get_table_id()); ... if (e->get_flags(Rows_log_event::STMT_END_F)) { ... } However, Rows_log_event is only the base class for the Write,Update_Delete_rows_event family of classes, but not for their *_old counterparts. So the above typecasts are incorrect for the old-format RBR events and may result (and do result according to AddressSanitizer reports) in reading memory outside of the previously allocated on heap buffer. Fix: === The above mentioned invalid type cast has been replaced with appropriate old counterpart. Note:The above mentioned issue is present only mysql-5.1 and 5.5. This is fixed in mysql-5.6 and above as part of Bug#55790. Hence few of the relevant changes of Bug#55790 are being back ported to fix the current issue.
* | BUG#15891524: RLI_FAKE MODE IS NOT UNSET AFTER BINLOG REPLAYNuno Carvalho2012-11-201-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When a binlog is replayed into a server, e.g.: $ mysqlbinlog binlog.000001 | mysql it sets a pseudo slave mode on the client connection in order to server be able to read binlog events, there is, a format description event is needed to correctly read following events. Also this pseudo slave mode applies to the current connection replication rules that are needed to correctly apply binlog events. If a binlog dump is sourced on a connection, this pseudo slave mode will remains after it, what will apply unexpected rules from customer perspective to following commands. Added a new SET statement to binlog dump that will unset pseudo slave mode at the end of dump file.
* | upmerge from mysql-5.1=>mysql-5.5Rohit Kalhans2012-08-081-1/+12
|\ \ | |/
| * BUG#11757312: MYSQLBINLOG DOES NOT ACCEPT INPUT FROM STDINRohit Kalhans2012-08-081-1/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | WHEN STDIN IS A PIPE Problem: Mysqlbinlog does not accept the input from STDIN when STDIN is a pipe. This prevents the users from passing the input file through a shell pipe. Background: The my_seek() function does not check if the file descriptor passed to it is regular (seekable) file. The check_header() function in mysqlbinlog calls the my_b_seek() unconditionally and it fails when the underlying file is a PIPE. Resolution: We resolve this problem by checking if the underlying file is a regular file by using my_fstat() before calling my_b_seek(). If the underlying file is not seekable we skip the call to my_b_seek() in check_header().
* | Merge of patch for Bug#13928675 from mysql-5.1.Nirbhay Choubey2012-08-071-1/+1
|\ \ | |/
| * Bug#13928675 MYSQL CLIENT COPYRIGHT NOTICE MUSTNirbhay Choubey2012-08-071-1/+1
| | | | | | | | | | | | | | | | | | | | SHOW 2012 INSTEAD OF 2011 * Added a new macro to hold the current year : COPYRIGHT_NOTICE_CURRENT_YEAR * Modified ORACLE_WELCOME_COPYRIGHT_NOTICE macro to take the initial year as parameter and pick current year from the above mentioned macro.
* | merge from 5.1 to 5.5Sujatha Sivakumar2012-07-101-1/+12
|\ \ | |/
| * BUG#11762670:MY_B_WRITE RETURN VALUE IGNOREDSujatha Sivakumar2012-07-101-1/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: ======= The return value from my_b_write is ignored by: `my_b_write_quoted', `my_b_write_bit',`Query_log_event::print_query_header' Most callers of `my_b_printf' ignore the return value. `log_event.cc' has many calls to it. Analysis: ======== `my_b_write' is used to write data into a file. If the write fails it sets appropriate error number and error message through my_error() function call and sets the IO_CACHE::error == -1. `my_b_printf' function is also used to write data into a file, it internally invokes my_b_write to do the write operation. Upon success it returns number of characters written to file and on error it returns -1 and sets the error through my_error() and also sets IO_CACHE::error == -1. Most of the event specific print functions for example `Create_file_log_event::print', `Execute_load_log_event::print' etc are the ones which make several calls to the above two functions and they do not check for the return value after the 'print' call. All the above mentioned abuse cases deal with the client side. Fix: === As part of bug fix a check for IO_CACHE::error == -1 has been added at a very high level after the call to the 'print' function. There are few more places where the return value of "my_b_write" is ignored those are mentioned below. +++ mysys/mf_iocache2.c 2012-06-04 07:03:15 +0000 @@ -430,7 +430,8 @@ memset(buffz, '0', minimum_width - length2); else memset(buffz, ' ', minimum_width - length2); - my_b_write(info, buffz, minimum_width - length2); +++ sql/log.cc 2012-06-08 09:04:46 +0000 @@ -2388,7 +2388,12 @@ { end= strxmov(buff, "# administrator command: ", NullS); buff_len= (ulong) (end - buff); - my_b_write(&log_file, (uchar*) buff, buff_len); At these places appropriate return value handlers have been added.
* | Bug#14238406 NEW COMPILATION WARNINGS WITH GCC 4.7 (-WERROR=NARROWING)Jon Olav Hauglid2012-06-291-2/+2
|\ \ | |/ | | Manual merge from mysql-5.1 to mysql-5.5
| * Bug#14238406 NEW COMPILATION WARNINGS WITH GCC 4.7 (-WERROR=NARROWING)Jon Olav Hauglid2012-06-291-2/+2
| | | | | | | | | | This patch fixes various compilation warnings of the type "error: narrowing conversion of 'x' from 'datatype1' to 'datatype2'
* | upmerge from mysql-5.1 branch -> mysql-5.5 branchRohit Kalhans2012-05-291-1/+20
|\ \ | |/
| * Bug#11762667: MYSQLBINLOG IGNORES ERRORS WHILE WRITING OUTPUTRohit Kalhans2012-05-291-1/+20
| | | | | | | | | | | | | | | | | | | | Problem: mysqlbinlog exits without any error code in case of file write error. It is because of the fact that the calls to Log_event::print() method does not return a value and the thus any error were being ignored. Resolution: We resolve this problem by checking for the IO_CACHE::error == -1 after every call to Log_event:: print() and terminating the further execution.
* | BUG#12695969Luis Soares2011-07-111-1/+1
|\ \ | |/ | | | | | | | | | | | | | | | | | | | | Manually merged from mysql-5.1: - fixed mysqlbinlog copyright year: 2001 --> 2000 - fixed address in license header conflicts ========= - client/mysqlbinlog.cc - include/welcome_copyright_notice.h
| * BUG#12695969Luis Soares2011-07-111-4/+2
| |\ | | | | | | | | | | | | | | | | | | Manually merged mysql-5.0 into mysql-5.1. conflicts ========= client/mysqlibinlog.cc
| | * BUG#12695969: FIX OUTDATED COPYRIGHT NOTICES IN REPLACTIONLuis Soares2011-07-111-7/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | CLIENT TOOLS The fix is to backport part of revision: - alexander.nozdrin@oracle.com-20101006150613-ls60rb2tq5dpyb5c from mysql-5.5. In detail, we add the oracle welcome notice header file proposed in the original patch and include/use it in client/mysqlbinlog.cc, replacing the existing and obsolete notice.
| * | Updated/added copyright headersKent Boortz2011-07-031-5/+14
| |\ \
* | \ \ Updated/added copyright headersKent Boortz2011-06-301-2/+4
|\ \ \ \ | |/ / /
| * | | Updated/added copyright headersKent Boortz2011-06-301-2/+4
| |\ \ \ | | | |/ | | |/|
| | * | Updated/added copyright headersKent Boortz2011-06-301-2/+5
| | | |
* | | | Fixed cast warnings in introducing the pluggable authentication clientGeorgi Kodinov2011-06-061-2/+2
| | | | | | | | | | | | | | | | options.
* | | | BUG#12354268Luis Soares2011-05-061-1/+2
|\ \ \ \ | | |_|/ | |/| | Automerge from mysql-5.1 into mysql-5.5.
| * | | BUG#12354268: MYSQLBINLOG --BASE64-OUTPUT=DECODE-ROWS DOES NOTLuis Soares2011-05-051-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | WORK WITH --START-POSITION If setting --start-position to start after the FD event, mysqlbinlog will output an error stating that it has not found an FD event. However, its not that mysqlbinlog does not find it but rather that it does not processes it in the regular way (i.e., it does not print it). Given that one is using --base64-output=DECODE-ROWS then not printing it is actually fine. To fix this, we make mysqlbinlog not to complain when it has not printed the FD event, is outputing in base64, but is decoding the rows.
* | | | Merged BUG#11766427, BUG#59539 from 5.1 to 5.5.Sven Sandberg2011-03-251-3/+11
|\ \ \ \ | |/ / / | | | | | | | | No conflicts.
| * | | BUG#11766427, BUG#59539: Filter by server id in mysqlbinlog failsSven Sandberg2011-03-251-3/+11
| |/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Problem: mysqlbinlog --server-id may filter out Format_description_log_events. If mysqlbinlog does not process the Format_description_log_event, then mysqlbinlog cannot read the rest of the binary log correctly. This can have the effect that mysqlbinlog crashes, generates an error, or generates output that causes mysqld to crash, generate an error, or corrupt data. Fix: Never filter out Format_description_log_events. Also, never filter out Rotate_log_events.
* | | Bug#58139 : default-auth option not recognized in MySQL standardNirbhay Choubey2011-01-161-0/+15
| | | | | | | | | | | | | | | | | | | | | command line clients. Postfix covering other mysql standard clients like mysql_upgrade, mysqlbinlog, mysqlcheck, mysqlimport, mysqlshow and mysqlslap.
* | | wL#5625: Deprecate mysqlbinlog options --base64-output=always and ↵Sven Sandberg2010-10-291-4/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | --base64-output Adds deprecation warning for the mysqlbinlog options --base64-output=always and --base64-output. A warning is printed when the flags are used, and also when running mysqlbinlog --help.
* | | Fix for Bug#57094 (Copyright notice incorrect?).Alexander Nozdrin2010-10-061-5/+3
| | | | | | | | | | | | | | | | | | | | | The fix is to: - introduce ORACLE_WELCOME_COPYRIGHT_NOTICE define to have a single place to specify copyright notice; - replace custom copyright notices with ORACLE_WELCOME_COPYRIGHT_NOTICE in programs.
* | | Merge of mysql-trunk-bugfixing into mysql-trunk-merge.Davi Arnaut2010-07-151-29/+18
|\ \ \
| * | | WL#5486: Remove code for unsupported platformsDavi Arnaut2010-07-151-12/+0
| | | | | | | | | | | | Remove Netware specific code.
| * | | BUG 54744: automerged bzr bundle from bug report.Luis Soares2010-07-091-0/+1
| |\ \ \
| | * | | BUG#54744: valgrind reports leak for mysqlbinlogLuis Soares2010-07-081-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The server was not cleaning up some dbug allocated memory before exiting. This is not a real problem, as this memory would be deallocated anyway. Nonetheless, we improve the mysqlbinlog exit procedure, wrt to memory book-keeping, when no parameter is given. To fix this, we deploy a call to my_end() before the thread exits.
| * | | | Bug#34043: Server loops excessively in _checkchunk() when safemalloc is enabledDavi Arnaut2010-07-081-17/+17
| |/ / / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Essentially, the problem is that safemalloc is excruciatingly slow as it checks all allocated blocks for overrun at each memory management primitive, yielding a almost exponential slowdown for the memory management functions (malloc, realloc, free). The overrun check basically consists of verifying some bytes of a block for certain magic keys, which catches some simple forms of overrun. Another minor problem is violation of aliasing rules and that its own internal list of blocks is prone to corruption. Another issue with safemalloc is rather the maintenance cost as the tool has a significant impact on the server code. Given the magnitude of memory debuggers available nowadays, especially those that are provided with the platform malloc implementation, maintenance of a in-house and largely obsolete memory debugger becomes a burden that is not worth the effort due to its slowness and lack of support for detecting more common forms of heap corruption. Since there are third-party tools that can provide the same functionality at a lower or comparable performance cost, the solution is to simply remove safemalloc. Third-party tools can provide the same functionality at a lower or comparable performance cost. The removal of safemalloc also allows a simplification of the malloc wrappers, removing quite a bit of kludge: redefinition of my_malloc, my_free and the removal of the unused second argument of my_free. Since free() always check whether the supplied pointer is null, redudant checks are also removed. Also, this patch adds unit testing for my_malloc and moves my_realloc implementation into the same file as the other memory allocation primitives.
| * | | Revert patch for BUG#54744.Luis Soares2010-07-081-1/+0
| | | |
| * | | BUG#54744: valgrind reports leak for mysqlbinlogLuis Soares2010-07-061-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The server was not cleaning up dbug allocated memory before exiting. This is not a real problem, as this memory would be deallocated anyway. Nonetheless, we improve the mysqlbinlog exit procedure, wrt to memory book-keeping, when no parameter is given. To fix this, we deploy a call to my_thread_end() before the thread exits, which will also free pending dbug related allocated blocks.
* | | | Merge of mysql-5.1-bugteam into mysql-trunk-merge.Davi Arnaut2010-07-091-1/+1
|\ \ \ \ | |/ / / |/| / / | |/ /
| * | Bug#45288: pb2 returns a lot of compilation warnings on linuxDavi Arnaut2010-07-091-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | Although the C standard mandates that sprintf return the number of bytes written, some very ancient systems (i.e. SunOS 4) returned a pointer to the buffer instead. Since these systems are not supported anymore and are hopefully long dead by now, simply remove the portability wrapper that dealt with this discrepancy. The autoconf check was causing trouble with GCC.
* | | Merge of mysql-5.1-bugteam into mysql-trunk-merge.Davi Arnaut2010-06-101-33/+32
|\ \ \ | |/ /
| * | Bug#42733: Type-punning warnings when compiling MySQL --Davi Arnaut2010-06-101-34/+33
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | strict aliasing violations. Essentially, the problem is that large parts of the server were developed in simpler times (last decades, pre C99 standard) when strict aliasing and compilers supporting such optimizations were rare to non-existent. Thus, when compiling the server with a modern compiler that uses strict aliasing rules to perform optimizations, there are several places in the code that might trigger undefined behavior. As evinced by some recent bugs, GCC does a somewhat good of job misoptimizing such code, but on the other hand also gives warnings about suspicious code. One problem is that the warnings aren't always accurate, yet we can't afford to just shut them off as we might miss real cases. False-positive cases are aggravated mostly by casts that are likely to trigger undefined behavior. The solution is to start a cleanup process focused on fixing and reducing the amount of strict-aliasing related warnings produced by GCC and others compilers. A good deal of noise reduction can be achieved by just removing useless casts that are product of historical cruft and are likely to trigger undefined behavior if dereferenced.
* | | Manual merge of mysql-5.1-bugteam toAlexey Kopytov2010-04-191-1/+1
|\ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | mysql-trunk-merge. Conflicts: Text conflict in sql/sql_priv.h
| * | | WL#5030: Split and remove mysql_priv.hMats Kindahl2010-03-311-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch: - Moves all definitions from the mysql_priv.h file into header files for the component where the variable is defined - Creates header files if the component lacks one - Eliminates all include directives from mysql_priv.h - Eliminates all circular include cycles - Rename time.cc to sql_time.cc - Rename mysql_priv.h to sql_priv.h
* | | | Manual merge of mysql-5.1-bugteam into mysql-trunk-merge.Alexey Kopytov2010-04-031-3/+1
|\ \ \ \ | |/ / / |/| / / | |/ / | | | | | | | | | | | | Conflicts: Text conflict in mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result Text conflict in sql/log.cc Text conflict in sql/set_var.cc Text conflict in sql/sql_class.cc
| * | Bug #50407 mysqlbinlog --database=X produces bad output for SAVEPOINTs2010-03-281-3/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When mysqlbinlog was given the --database=X flag, it always printed 'ROLLBACK TO', but the corresponding 'SAVEPOINT' statement was not printed. The replicated filter(replicated-do/ignore-db) and binlog filter (binlog-do/ignore-db) has the same problem. They are solved in this patch together. After this patch, We always check whether the query is 'SAVEPOINT' statement or not. Because this is a literal check, 'SAVEPOINT' and 'ROLLBACK TO' statements are also binlogged in uppercase with no any comments. The binlog before this patch can be handled correctly except one case that any comments are in front of the keywords. for example: /* bla bla */ SAVEPOINT a; /* bla bla */ ROLLBACK TO a;
| * | BUG#48993: valgrind errors in mysqlbinlogLuis Soares2010-02-171-3/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I found three issues during the analysis: 1. Memory leak caused by temp_buf not being freed; 2. Memory leak caused when handling argv; 3. Conditional jump that depended on unitialized values. Issue #1 -------- DESCRIPTION: when mysqlbinlog is reading from a remote location the event temp_buf references the incoming stream (in NET object), which is not freed by mysqlbinlog explicitly. On the other hand, when it is reading local binary log, it points to a temporary buffer that needs to be explicitly freed. For both cases, the temp_buf was not freed by mysqlbinlog, instead was set to 0. This clearly disregards the free required in the second case, thence creating a memory leak. FIX: we make temp_buf to be conditionally freed depending on the value of remote_opt. Found out that similar fix is already in most recent codebases. Issue #2 -------- DESCRIPTION: load_defaults is called by parse_args, and it reads default options from configuration files and put them BEFORE the arguments that are already in argc and argv. This is done resorting to MEM_ROOT. However, parse_args calls handle_options immediately after which changes argv. Later when freeing the defaults, pointers to MEM_ROOT won't match, causing the memory not to be freed: void free_defaults(char **argv) { MEM_ROOT ptr memcpy_fixed((char*) &ptr,(char *) argv - sizeof(ptr), sizeof(ptr)); free_root(&ptr,MYF(0)); } FIX: we remove load_defaults from parse_args and call it before. Then we save argv with defaults in defaults_argv BEFORE calling parse_args (which inside can then call handle_options at will). Actually, found out that this is in fact kind of a backport for BUG#38468 into 5.1, so I merged in the test case as well and added error check for load_defaults call. Fix based on: revid:zhenxing.he@sun.com-20091002081840-uv26f0flw4uvo33y Issue #3 -------- DESCRIPTION: the structure st_print_event_info constructor would not initialize the sql_mode member, although it did for sql_mode_inited (set to false). This would later raise the warning in valgrind when printing the sql_mode in the event header, as this print out is protected by a check against sql_mode_inited and sql_mode variables. Given that sql_mode was not initialized valgrind would output the warning. FIX: we add initialization of sql_mode to the st_print_event_info constructor.
* | | Manual merge from mysql-trunk-merge.Alexander Nozdrin2010-02-241-9/+9
|\ \ \ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: - client/mysql.cc - client/mysqldump.c - configure.in - mysql-test/r/csv.result - mysql-test/r/func_time.result - mysql-test/r/show_check.result - mysql-test/r/sp-error.result - mysql-test/r/sp.result - mysql-test/r/sp_trans.result - mysql-test/r/type_blob.result - mysql-test/r/type_timestamp.result - mysql-test/r/warnings.result - mysql-test/suite/rpl/r/rpl_sp.result - sql/mysql_priv.h - sql/mysqld.cc - sql/sp.cc - sql/sql_base.cc - sql/sql_table.cc - sql/sql_trigger.cc - sql/sql_view.cc - sql/table.h - sql/share/errmsg.txt - mysql-test/suite/sys_vars/r/log_bin_trust_routine_creators_basic.result
| * \ \ Manual merge of mysql-5.1-bugteam into mysql-trunk-merge.Alexey Kopytov2010-02-091-9/+9
| |\ \ \ | | |/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Conflicts: Text conflict in .bzr-mysql/default.conf Text conflict in mysql-test/suite/rpl/r/rpl_slow_query_log.result Text conflict in mysql-test/suite/rpl/t/rpl_slow_query_log.test Conflict adding files to server-tools. Created directory. Conflict because server-tools is not versioned, but has versioned children. Versioned directory. Conflict adding files to server-tools/instance-manager. Created directory. Conflict because server-tools/instance-manager is not versioned, but has versioned children. Versioned directory. Contents conflict in server-tools/instance-manager/options.cc Text conflict in sql/mysqld.cc
| | * | Recommit of Bug#49447.Staale Smedseng2010-02-041-9/+9
| | | |
| * | | Manual merge of mysql-5.1-bugteam into mysql-trunk-merge.Alexey Kopytov2010-01-241-2/+6
| |\ \ \ | | |/ /
| | * | WL#5154 Remove deprecated 4.1 featuresMagne Mahre2010-01-211-2/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Several items said to be deprecated in the 4.1 manual have never been removed. This worklog adds deprecation warnings when these items are used, and warns the user that the items will be removed in MySQL 5.6. A couple of previously deprecation decision have been reversed (see single file comments)
* | | | WL#5154 Remove deprecated 4.1 featuresMagne Mahre2010-02-171-6/+1
| | | | | | | | | | | | | | | | | | | | | | | | A set of program options and variables was deprecated in MySQL 5.1, and is hereby removed.