~ubuntu-branches/ubuntu/natty/mysql-5.1/natty-proposed

« back to all changes in this revision

Viewing changes to cmd-line-utils/libedit/eln.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 08:30:45 UTC
  • mfrom: (1.4.1)
  • Revision ID: package-import@ubuntu.com-20120222083045-2rd53r4bnyx7qus4
Tags: 5.1.61-0ubuntu0.11.04.1
* SECURITY UPDATE: Update to 5.1.61 to fix multiple security issues
  (LP: #937869)
  - http://www.oracle.com/technetwork/topics/security/cpujan2012-366304.html
  - CVE-2011-2262
  - CVE-2012-0075
  - CVE-2012-0112
  - CVE-2012-0113
  - CVE-2012-0114
  - CVE-2012-0115
  - CVE-2012-0116
  - CVE-2012-0117
  - CVE-2012-0118
  - CVE-2012-0119
  - CVE-2012-0120
  - CVE-2012-0484
  - CVE-2012-0485
  - CVE-2012-0486
  - CVE-2012-0487
  - CVE-2012-0488
  - CVE-2012-0489
  - CVE-2012-0490
  - CVE-2012-0491
  - CVE-2012-0492
  - CVE-2012-0493
  - CVE-2012-0494
  - CVE-2012-0495
  - CVE-2012-0496

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*      $NetBSD: eln.c,v 1.13 2011/08/16 16:25:15 christos Exp $        */
 
2
 
 
3
/*-
 
4
 * Copyright (c) 2009 The NetBSD Foundation, Inc.
 
5
 * All rights reserved.
 
6
 *
 
7
 * Redistribution and use in source and binary forms, with or without
 
8
 * modification, are permitted provided that the following conditions
 
9
 * are met:
 
10
 * 1. Redistributions of source code must retain the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer.
 
12
 * 2. Redistributions in binary form must reproduce the above copyright
 
13
 *    notice, this list of conditions and the following disclaimer in the
 
14
 *    documentation and/or other materials provided with the distribution.
 
15
 * 3. All advertising materials mentioning features or use of this software
 
16
 *    must display the following acknowledgement:
 
17
 *        This product includes software developed by the NetBSD
 
18
 *        Foundation, Inc. and its contributors.
 
19
 * 4. Neither the name of The NetBSD Foundation nor the names of its
 
20
 *    contributors may be used to endorse or promote products derived
 
21
 *    from this software without specific prior written permission.
 
22
 *
 
23
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 
24
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 
25
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
26
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 
27
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
28
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
29
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
30
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
31
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
32
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
33
 * POSSIBILITY OF SUCH DAMAGE.
 
34
 */
 
35
#include "config.h"
 
36
#if !defined(lint) && !defined(SCCSID)
 
37
#endif /* not lint && not SCCSID */
 
38
 
 
39
#include "histedit.h"
 
40
#include "el.h"
 
41
#include "read.h"
 
42
#include <stdarg.h>
 
43
#include <stdio.h>
 
44
#include <stdlib.h>
 
45
 
 
46
public int
 
47
el_getc(EditLine *el, char *cp)
 
48
{
 
49
        int num_read;
 
50
        wchar_t wc = 0;
 
51
 
 
52
        num_read = el_wgetc (el, &wc);
 
53
 
 
54
        if (num_read > 0)
 
55
                *cp = (char)wc;
 
56
        return num_read;
 
57
}
 
58
 
 
59
 
 
60
public void
 
61
el_push(EditLine *el, const char *str)
 
62
{
 
63
        /* Using multibyte->wide string decoding works fine under single-byte
 
64
         * character sets too, and Does The Right Thing. */
 
65
        el_wpush(el, ct_decode_string(str, &el->el_lgcyconv));
 
66
}
 
67
 
 
68
 
 
69
public const char *
 
70
el_gets(EditLine *el, int *nread)
 
71
{
 
72
        const wchar_t *tmp;
 
73
 
 
74
        tmp = el_wgets(el, nread);
 
75
        return ct_encode_string(tmp, &el->el_lgcyconv);
 
76
}
 
77
 
 
78
 
 
79
public int
 
80
el_parse(EditLine *el, int argc, const char *argv[])
 
81
{
 
82
        int ret;
 
83
        const wchar_t **wargv;
 
84
 
 
85
        wargv = (const wchar_t **)
 
86
            ct_decode_argv(argc, argv, &el->el_lgcyconv);
 
87
        if (!wargv)
 
88
                return -1;
 
89
        ret = el_wparse(el, argc, wargv);
 
90
        ct_free_argv(wargv);
 
91
 
 
92
        return ret;
 
93
}
 
94
 
 
95
 
 
96
public int
 
97
el_set(EditLine *el, int op, ...)
 
98
{
 
99
        va_list ap;
 
100
        int ret;
 
101
 
 
102
        if (!el)
 
103
                return -1;
 
104
        va_start(ap, op);
 
105
 
 
106
        switch (op) {
 
107
        case EL_PROMPT:         /* el_pfunc_t */
 
108
        case EL_RPROMPT: {
 
109
                el_pfunc_t p = va_arg(ap, el_pfunc_t);
 
110
                ret = prompt_set(el, p, 0, op, 0);
 
111
                break;
 
112
        }
 
113
 
 
114
        case EL_RESIZE: {
 
115
                el_zfunc_t p = va_arg(ap, el_zfunc_t);
 
116
                void *arg = va_arg(ap, void *);
 
117
                ret = ch_resizefun(el, p, arg);
 
118
                break;
 
119
        }
 
120
 
 
121
        case EL_TERMINAL:       /* const char * */
 
122
                ret = el_wset(el, op, va_arg(ap, char *));
 
123
                break;
 
124
 
 
125
        case EL_EDITOR:         /* const wchar_t * */
 
126
                ret = el_wset(el, op, ct_decode_string(va_arg(ap, char *),
 
127
                    &el->el_lgcyconv));
 
128
                break;
 
129
 
 
130
        case EL_SIGNAL:         /* int */
 
131
        case EL_EDITMODE:
 
132
        case EL_UNBUFFERED:
 
133
        case EL_PREP_TERM:
 
134
                ret = el_wset(el, op, va_arg(ap, int));
 
135
                break;
 
136
 
 
137
        case EL_BIND:   /* const char * list -> const wchar_t * list */
 
138
        case EL_TELLTC:
 
139
        case EL_SETTC:
 
140
        case EL_ECHOTC:
 
141
        case EL_SETTY: {
 
142
                const char *argv[20];
 
143
                int i;
 
144
                const wchar_t **wargv;
 
145
                for (i = 1; i < (int)__arraycount(argv); ++i)
 
146
                        if ((argv[i] = va_arg(ap, char *)) == NULL)
 
147
                            break;
 
148
                argv[0] = NULL;
 
149
                wargv = (const wchar_t **)
 
150
                    ct_decode_argv(i, argv, &el->el_lgcyconv);
 
151
                if (!wargv) {
 
152
                    ret = -1;
 
153
                    goto out;
 
154
                }
 
155
                /*
 
156
                 * AFAIK we can't portably pass through our new wargv to
 
157
                 * el_wset(), so we have to reimplement the body of
 
158
                 * el_wset() for these ops.
 
159
                 */
 
160
                switch (op) {
 
161
                case EL_BIND:
 
162
                        wargv[0] = STR("bind");
 
163
                        ret = map_bind(el, i, wargv);
 
164
                        break;
 
165
                case EL_TELLTC:
 
166
                        wargv[0] = STR("telltc");
 
167
                        ret = terminal_telltc(el, i, wargv);
 
168
                        break;
 
169
                case EL_SETTC:
 
170
                        wargv[0] = STR("settc");
 
171
                        ret = terminal_settc(el, i, wargv);
 
172
                        break;
 
173
                case EL_ECHOTC:
 
174
                        wargv[0] = STR("echotc");
 
175
                        ret = terminal_echotc(el, i, wargv);
 
176
                        break;
 
177
                case EL_SETTY:
 
178
                        wargv[0] = STR("setty");
 
179
                        ret = tty_stty(el, i, wargv);
 
180
                        break;
 
181
                default:
 
182
                        ret = -1;
 
183
                }
 
184
                ct_free_argv(wargv);
 
185
                break;
 
186
        }
 
187
 
 
188
        /* XXX: do we need to change el_func_t too? */
 
189
        case EL_ADDFN: {          /* const char *, const char *, el_func_t */
 
190
                const char *args[2];
 
191
                el_func_t func;
 
192
                wchar_t **wargv;
 
193
 
 
194
                args[0] = va_arg(ap, const char *);
 
195
                args[1] = va_arg(ap, const char *);
 
196
                func = va_arg(ap, el_func_t);
 
197
 
 
198
                wargv = ct_decode_argv(2, args, &el->el_lgcyconv);
 
199
                if (!wargv) {
 
200
                    ret = -1;
 
201
                    goto out;
 
202
                }
 
203
                // XXX: The two strdup's leak
 
204
                ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
 
205
                    func);
 
206
                ct_free_argv(wargv);
 
207
                break;
 
208
        }
 
209
        case EL_HIST: {           /* hist_fun_t, const char * */
 
210
                hist_fun_t fun = va_arg(ap, hist_fun_t);
 
211
                void *ptr = va_arg(ap, void *);
 
212
                ret = hist_set(el, fun, ptr);
 
213
                el->el_flags |= NARROW_HISTORY;
 
214
                break;
 
215
        }
 
216
        /* XXX: do we need to change el_rfunc_t? */
 
217
        case EL_GETCFN:         /* el_rfunc_t */
 
218
                ret = el_wset(el, op, va_arg(ap, el_rfunc_t));
 
219
                el->el_flags |= NARROW_READ;
 
220
                break;
 
221
        case EL_CLIENTDATA:     /* void * */
 
222
                ret = el_wset(el, op, va_arg(ap, void *));
 
223
                break;
 
224
        case EL_SETFP: {          /* int, FILE * */
 
225
                int what = va_arg(ap, int);
 
226
                FILE *fp = va_arg(ap, FILE *);
 
227
                ret = el_wset(el, op, what, fp);
 
228
                break;
 
229
        }
 
230
        case EL_PROMPT_ESC: /* el_pfunc_t, char */
 
231
        case EL_RPROMPT_ESC: {
 
232
                el_pfunc_t p = va_arg(ap, el_pfunc_t);
 
233
                char c = (char)va_arg(ap, int);
 
234
                ret = prompt_set(el, p, c, op, 0);
 
235
                break;
 
236
        }
 
237
        default:
 
238
                ret = -1;
 
239
                break;
 
240
        }
 
241
 
 
242
out:
 
243
        va_end(ap);
 
244
        return ret;
 
245
}
 
246
 
 
247
 
 
248
public int
 
249
el_get(EditLine *el, int op, ...)
 
250
{
 
251
        va_list ap;
 
252
        int ret;
 
253
 
 
254
        if (!el)
 
255
                return -1;
 
256
 
 
257
        va_start(ap, op);
 
258
 
 
259
        switch (op) {
 
260
        case EL_PROMPT:         /* el_pfunc_t * */
 
261
        case EL_RPROMPT: {
 
262
                el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
 
263
                ret = prompt_get(el, p, 0, op);
 
264
                break;
 
265
        }
 
266
 
 
267
        case EL_PROMPT_ESC: /* el_pfunc_t *, char **/
 
268
        case EL_RPROMPT_ESC: {
 
269
                el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
 
270
                char *c = va_arg(ap, char *);
 
271
                wchar_t wc = 0;
 
272
                ret = prompt_get(el, p, &wc, op);
 
273
                *c = (char)wc;
 
274
                break;
 
275
        }
 
276
 
 
277
        case EL_EDITOR: {
 
278
                const char **p = va_arg(ap, const char **);
 
279
                const wchar_t *pw;
 
280
                ret = el_wget(el, op, &pw);
 
281
                *p = ct_encode_string(pw, &el->el_lgcyconv);
 
282
                if (!el->el_lgcyconv.csize)
 
283
                        ret = -1;
 
284
                break;
 
285
        }
 
286
 
 
287
        case EL_TERMINAL:       /* const char ** */
 
288
                ret = el_wget(el, op, va_arg(ap, const char **));
 
289
                break;
 
290
 
 
291
        case EL_SIGNAL:         /* int * */
 
292
        case EL_EDITMODE:
 
293
        case EL_UNBUFFERED:
 
294
        case EL_PREP_TERM:
 
295
                ret = el_wget(el, op, va_arg(ap, int *));
 
296
                break;
 
297
 
 
298
        case EL_GETTC: {
 
299
                char *argv[20];
 
300
                static char gettc[] = "gettc";
 
301
                int i;
 
302
                for (i = 1; i < (int)__arraycount(argv); ++i)
 
303
                        if ((argv[i] = va_arg(ap, char *)) == NULL)
 
304
                                break;
 
305
                argv[0] = gettc;
 
306
                ret = terminal_gettc(el, i, argv);
 
307
                break;
 
308
        }
 
309
 
 
310
        /* XXX: do we need to change el_rfunc_t? */
 
311
        case EL_GETCFN:         /* el_rfunc_t */
 
312
                ret = el_wget(el, op, va_arg(ap, el_rfunc_t *));
 
313
                break;
 
314
 
 
315
        case EL_CLIENTDATA:     /* void ** */
 
316
                ret = el_wget(el, op, va_arg(ap, void **));
 
317
                break;
 
318
 
 
319
        case EL_GETFP: {          /* int, FILE ** */
 
320
                int what = va_arg(ap, int);
 
321
                FILE **fpp = va_arg(ap, FILE **);
 
322
                ret = el_wget(el, op, what, fpp);
 
323
                break;
 
324
        }
 
325
 
 
326
        default:
 
327
                ret = -1;
 
328
                break;
 
329
        }
 
330
 
 
331
        va_end(ap);
 
332
        return ret;
 
333
}
 
334
 
 
335
 
 
336
const LineInfo *
 
337
el_line(EditLine *el)
 
338
{
 
339
        const LineInfoW *winfo = el_wline(el);
 
340
        LineInfo *info = &el->el_lgcylinfo;
 
341
        size_t offset;
 
342
        const Char *p;
 
343
 
 
344
        info->buffer   = ct_encode_string(winfo->buffer, &el->el_lgcyconv);
 
345
 
 
346
        offset = 0;
 
347
        for (p = winfo->buffer; p < winfo->cursor; p++)
 
348
                offset += ct_enc_width(*p);
 
349
        info->cursor = info->buffer + offset;
 
350
 
 
351
        offset = 0;
 
352
        for (p = winfo->buffer; p < winfo->lastchar; p++)
 
353
                offset += ct_enc_width(*p);
 
354
        info->lastchar = info->buffer + offset;
 
355
 
 
356
        return info;
 
357
}
 
358
 
 
359
 
 
360
int
 
361
el_insertstr(EditLine *el, const char *str)
 
362
{
 
363
        return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv));
 
364
}