Project

General

Profile

Backport #8070 ยป backport-8034-ruby_1_9_3.diff

luislavena (Luis Lavena), 03/14/2013 02:03 PM

View differences:

ChangeLog
1
Thu Mar 14 12:53:15 2013  Luis Lavena  <luislavena@gmail.com>
2

  
3
	* win32/file.c (get_user_from_path):  add internal function that retrieves
4
	  username from supplied path (refactored).
5
	* win32/file.c (rb_file_expand_path_internal):  refactor expansion of user
6
	  home to use get_user_from_path and cover dir_string corner cases.
7
	  [ruby-core:53168] [Bug #8034]
8

  
9
Sun Mar 10 23:38:15 2013  Luis Lavena  <luislavena@gmail.com>
10

  
11
	* win32/file.c (rb_file_expand_path_internal):  Expand home directory when
12
	  used as second parameter (dir_string).  [ruby-core:53168] [Bug #8034]
13
	* test/ruby/test_file_exhaustive.rb: add test to verify.
14

  
1 15
Tue Feb 26 09:53:59 2013  NARUSE, Yui  <naruse@ruby-lang.org>
2 16

  
3 17
	* st.c (st_add_direct): int is not always same with st_index_t.  some
test/ruby/test_file_exhaustive.rb
413 413
    end
414 414
  end
415 415

  
416
  UnknownUserHome = "~foo_bar_baz_unknown_user_wahaha".freeze
417

  
416 418
  def test_expand_path_home
417 419
    assert_kind_of(String, File.expand_path("~")) if ENV["HOME"]
418
    assert_raise(ArgumentError) { File.expand_path("~foo_bar_baz_unknown_user_wahaha") }
419
    assert_raise(ArgumentError) { File.expand_path("~foo_bar_baz_unknown_user_wahaha", "/") }
420
    assert_raise(ArgumentError) { File.expand_path(UnknownUserHome) }
421
    assert_raise(ArgumentError) { File.expand_path(UnknownUserHome, "/") }
420 422
    begin
421 423
      bug3630 = '[ruby-core:31537]'
422 424
      home = ENV["HOME"]
......
440 442
    end
441 443
  end
442 444

  
445
  def test_expand_path_home_dir_string
446
    home = ENV["HOME"]
447
    new_home = "#{DRIVE}/UserHome"
448
    ENV["HOME"] = new_home
449
    bug8034 = "[ruby-core:53168]"
450

  
451
    assert_equal File.join(new_home, "foo"), File.expand_path("foo", "~"), bug8034
452
    assert_equal File.join(new_home, "bar", "foo"), File.expand_path("foo", "~/bar"), bug8034
453

  
454
    assert_raise(ArgumentError) { File.expand_path(".", UnknownUserHome) }
455
    assert_nothing_raised(ArgumentError) { File.expand_path("#{DRIVE}/", UnknownUserHome) }
456
  ensure
457
    ENV["HOME"] = home
458
  end
459

  
443 460
  def test_expand_path_remove_trailing_alternative_data
444 461
    assert_equal File.join(@rootdir, "aaa"), File.expand_path("#{@rootdir}/aaa::$DATA")
445 462
    assert_equal File.join(@rootdir, "aa:a"), File.expand_path("#{@rootdir}/aa:a:$DATA")
win32/file.c
317 317
    return size;
318 318
}
319 319

  
320
static inline VALUE
321
get_user_from_path(wchar_t **wpath, int offset, UINT cp, UINT path_cp, rb_encoding *path_encoding)
322
{
323
    VALUE result, tmp;
324
    wchar_t *wuser = *wpath + offset;
325
    wchar_t *pos = wuser;
326
    char *user;
327
    size_t size;
328

  
329
    while (!IS_DIR_SEPARATOR_P(*pos) && *pos != '\0')
330
     pos++;
331

  
332
    *pos = '\0';
333
    convert_wchar_to_mb(wuser, &user, &size, cp);
334

  
335
    /* convert to VALUE and set the path encoding */
336
    if (path_cp == INVALID_CODE_PAGE) {
337
	tmp = rb_enc_str_new(user, size, rb_utf8_encoding());
338
	result = rb_str_encode(tmp, rb_enc_from_encoding(path_encoding), 0, Qnil);
339
	rb_str_resize(tmp, 0);
340
    }
341
    else {
342
	result = rb_enc_str_new(user, size, path_encoding);
343
    }
344

  
345
    if (user)
346
	xfree(user);
347

  
348
    return result;
349
}
350

  
320 351
VALUE
321 352
rb_file_expand_path_internal(VALUE fname, VALUE dname, int abs_mode, int long_name, VALUE result)
322 353
{
323 354
    size_t size = 0, wpath_len = 0, wdir_len = 0, whome_len = 0;
324 355
    size_t buffer_len = 0;
325 356
    char *fullpath = NULL;
326
    wchar_t *wfullpath = NULL, *wpath = NULL, *wpath_pos = NULL, *wdir = NULL;
357
    wchar_t *wfullpath = NULL, *wpath = NULL, *wpath_pos = NULL;
358
    wchar_t *wdir = NULL, *wdir_pos = NULL;
327 359
    wchar_t *whome = NULL, *buffer = NULL, *buffer_pos = NULL;
328 360
    UINT path_cp, cp;
329 361
    VALUE path = fname, dir = dname;
......
404 436
	}
405 437
    }
406 438
    else if (abs_mode == 0 && wpath_len >= 2 && wpath_pos[0] == L'~') {
407
	wchar_t *wuser = wpath_pos + 1;
408
	wchar_t *pos = wuser;
409
	char *user;
410

  
411
	/* tainted if expanding '~' */
412
	tainted = 1;
413

  
414
	while (!IS_DIR_SEPARATOR_P(*pos) && *pos != '\0')
415
	    pos++;
439
	result = get_user_from_path(&wpath_pos, 1, cp, path_cp, path_encoding);
416 440

  
417
	*pos = '\0';
418
	convert_wchar_to_mb(wuser, &user, &size, cp);
419

  
420
	/* convert to VALUE and set the path encoding */
421
	if (path_cp == INVALID_CODE_PAGE) {
422
	    VALUE tmp = rb_enc_str_new(user, size, rb_utf8_encoding());
423
	    result = rb_str_encode(tmp, rb_enc_from_encoding(path_encoding), 0, Qnil);
424
	    rb_str_resize(tmp, 0);
425
	}
426
	else {
427
	    result = rb_enc_str_new(user, size, path_encoding);
428
	}
429

  
430
	xfree(wpath);
431
	if (user)
432
	    xfree(user);
441
	if (wpath)
442
	    xfree(wpath);
433 443

  
434 444
	rb_raise(rb_eArgError, "can't find user %s", StringValuePtr(result));
435 445
    }
......
442 452
	}
443 453

  
444 454
	/* convert char * to wchar_t */
445
	convert_mb_to_wchar(dir, &wdir, NULL, &wdir_len, cp);
455
	convert_mb_to_wchar(dir, &wdir, &wdir_pos, &wdir_len, cp);
456

  
457
	if (abs_mode == 0 && wdir_len > 0 && wdir_pos[0] == L'~' &&
458
	    (wdir_len == 1 || IS_DIR_SEPARATOR_P(wdir_pos[1]))) {
459
	    /* tainted if expanding '~' */
460
	    tainted = 1;
446 461

  
447
	if (wdir_len >= 2 && wdir[1] == L':') {
462
	    whome = home_dir();
463
	    if (whome == NULL) {
464
		xfree(wpath);
465
		xfree(wdir);
466
		rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `~'");
467
	    }
468
	    whome_len = wcslen(whome);
469

  
470
	    if (PathIsRelativeW(whome) && !(whome_len >= 2 && IS_DIR_UNC_P(whome))) {
471
		xfree(wpath);
472
		xfree(wdir);
473
		rb_raise(rb_eArgError, "non-absolute home");
474
	    }
475

  
476
	    /* exclude ~ from the result */
477
	    wdir_pos++;
478
	    wdir_len--;
479

  
480
	    /* exclude separator if present */
481
	    if (wdir_len && IS_DIR_SEPARATOR_P(wdir_pos[0])) {
482
		wdir_pos++;
483
		wdir_len--;
484
	    }
485
	}
486
	else if (wdir_len >= 2 && wdir[1] == L':') {
448 487
	    dir_drive = wdir[0];
449 488
	    if (wpath_len && IS_DIR_SEPARATOR_P(wpath_pos[0])) {
450 489
		wdir_len = 2;
......
466 505
		    wdir_len = pos - 1;
467 506
	    }
468 507
	}
508
	else if (abs_mode == 0 && wdir_len >= 2 && wdir_pos[0] == L'~') {
509
	    result = get_user_from_path(&wdir_pos, 1, cp, path_cp, path_encoding);
510
	    if (wpath)
511
		xfree(wpath);
512

  
513
	    if (wdir)
514
		xfree(wdir);
515

  
516
	    rb_raise(rb_eArgError, "can't find user %s", StringValuePtr(result));
517
	}
469 518
    }
470 519

  
471 520
    /* determine if we ignore dir or not */
......
515 564
	if (!tainted && OBJ_TAINTED(dir))
516 565
	    tainted = 1;
517 566

  
518
	wcsncpy(buffer_pos, wdir, wdir_len);
567
	wcsncpy(buffer_pos, wdir_pos, wdir_len);
519 568
	buffer_pos += wdir_len;
520 569
    }
521 570