02-test_errstr.t 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #! /usr/bin/env perl
  2. # Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
  3. #
  4. # Licensed under the Apache License 2.0 (the "License"). You may not use
  5. # this file except in compliance with the License. You can obtain a copy
  6. # in the file LICENSE in the source distribution or at
  7. # https://www.openssl.org/source/license.html
  8. use strict;
  9. no strict 'refs'; # To be able to use strings as function refs
  10. use OpenSSL::Test;
  11. use OpenSSL::Test::Utils;
  12. use Errno qw(:POSIX);
  13. use POSIX qw(strerror);
  14. # We actually have space for up to 4095 error messages,
  15. # numerically speaking... but we're currently only using
  16. # numbers 1 through 127.
  17. # This constant should correspond to the same constant
  18. # defined in crypto/err/err.c, or at least must not be
  19. # assigned a greater number.
  20. use constant NUM_SYS_STR_REASONS => 127;
  21. setup('test_errstr');
  22. # In a cross compiled situation, there are chances that our
  23. # application is linked against different C libraries than
  24. # perl, and may thereby get different error messages for the
  25. # same error.
  26. # The safest is not to test under such circumstances.
  27. plan skip_all => 'This is unsupported for cross compiled configurations'
  28. if config('CROSS_COMPILE');
  29. plan skip_all => 'OpenSSL is configured "no-autoerrinit" or "no-err"'
  30. if disabled('autoerrinit') || disabled('err');
  31. # These are POSIX error names, which Errno implements as functions
  32. # (this is documented)
  33. my @posix_errors = @{$Errno::EXPORT_TAGS{POSIX}};
  34. if ($^O eq 'MSWin32') {
  35. # On Windows, these errors have been observed to not always be loaded by
  36. # apps/openssl, while they are in perl, which causes a difference that we
  37. # consider a false alarm. So we skip checking these errors.
  38. # Because we can't know exactly what symbols exist in a perticular perl
  39. # version, we resort to discovering them directly in the Errno package
  40. # symbol table.
  41. my @error_skiplist = qw(
  42. ENETDOWN
  43. ENETUNREACH
  44. ENETRESET
  45. ECONNABORTED
  46. EISCONN
  47. ENOTCONN
  48. ESHUTDOWN
  49. ETOOMANYREFS
  50. ETIMEDOUT
  51. EHOSTDOWN
  52. EHOSTUNREACH
  53. EALREADY
  54. EINPROGRESS
  55. ESTALE
  56. EUCLEAN
  57. ENOTNAM
  58. ENAVAIL
  59. ENOMEDIUM
  60. ENOKEY
  61. );
  62. @posix_errors =
  63. grep {
  64. my $x = $_;
  65. ! grep {
  66. exists $Errno::{$_} && $x == $Errno::{$_}
  67. } @error_skiplist
  68. } @posix_errors;
  69. }
  70. plan tests => scalar @posix_errors
  71. +1 # Checking that error 128 gives 'reason(128)'
  72. +1 # Checking that error 0 gives the library name
  73. ;
  74. foreach my $errname (@posix_errors) {
  75. my $errnum = "Errno::$errname"->();
  76. SKIP: {
  77. skip "Error $errname ($errnum) isn't within our range", 1
  78. if $errnum > NUM_SYS_STR_REASONS;
  79. my $perr = eval {
  80. # Set $! to the error number...
  81. local $! = $errnum;
  82. # ... and $! will give you the error string back
  83. $!
  84. };
  85. # We know that the system reasons are in OpenSSL error library 2
  86. my @oerr = run(app([ qw(openssl errstr), sprintf("2%06x", $errnum) ]),
  87. capture => 1);
  88. $oerr[0] =~ s|\R$||;
  89. $oerr[0] =~ s|.*system library:||g; # The actual message is last
  90. ok($oerr[0] eq $perr, "($errnum) '$oerr[0]' == '$perr'");
  91. }
  92. }
  93. my @after = run(app([ qw(openssl errstr 2000080) ]), capture => 1);
  94. $after[0] =~ s|\R$||;
  95. $after[0] =~ s|.*system library:||g;
  96. ok($after[0] eq "reason(128)", "(128) '$after[0]' == 'reason(128)'");
  97. my @zero = run(app([ qw(openssl errstr 2000000) ]), capture => 1);
  98. $zero[0] =~ s|\R$||;
  99. $zero[0] =~ s|.*system library:||g;
  100. ok($zero[0] eq "system library", "(0) '$zero[0]' == 'system library'");