Как обнаружить передачу строкового литерала к функции в C?

Я пытаюсь реализовать eqivilent версию perl's chomp() функция в C и я столкнулся с угловым случаем, куда строковый литерал передал, поскольку аргумент вызовет отказ сегментации (законно так).

Пример chomp("some literal string\n");

Есть ли определенный путь в C99, чтобы обнаружить, была ли моя функция передана строковый литерал так, чтобы я мог return не делая попытку к NUL его?

char* chomp(char *s)
{
    char *temp = s;

    if (s && *s)
    {
        s += strlen(s) - 1;
        if (*s == '\n')
        {
            *s = '\0';
        }
    }
    return temp;
}
5
задан SiegeX 23 February 2010 в 23:44
поделиться

2 ответа

Я дам вам ответы на все, что я только что сделал в Windows Server 2008 R2 которая является 64-разрядной операционной системой. Набор приложений библиотек, которые мне дали, были разработаны с помощью .net 3.5 x86 со старыми библиотеками DLL, и я застрял, потому что я установил новые клиенты x64 из Oracle.

Я нашел следующее: Установите последний клиент x64 из Oracle для Windows Server 2008. Я полагаю, что это будет клиент 2.7.0. При выборе установки убедитесь, что выполнена пользовательская установка, и выберите библиотеки .NET. Настройте файлы tnsnames и протестируйте tnsping на основе источника данных.

Далее, если выполняется 32-разрядное приложение, установите ту же версию клиента для 32-разрядного приложения. Также выполните ту же процедуру установки и выберите ту же домашнюю папку.

После завершения вы обнаружите, что у вас есть одно приложение/продукт с двумя клиентскими каталогами (Client1 и Client2).

При переходе к каталогу windows/assemblies вы обнаружите, что у вас есть ссылка на файл Oracle.DataAccess.dll (x2) с одним для x86 и одним для AMD64.

Теперь, в зависимости от того, есть ли у вас разработчики или вы сами разрабатываете на машине, вы можете быть в порядке здесь, однако, если они используют старые драйверы, то вам нужно выполнить один последний шаг.

Перейдите к папке app\name\product\version\client _ 1\odp.net\publisher policy\2.x. Здесь представлены два файла политик. используйте gacutil/i для установки Policy.2.111.Oracle.DataAccess.dll в GAC. Это перенаправит устаревшие вызовы Oracle ODP на более новые версии. Так что, если кто-то разработал с клиентом 10g, он теперь будет работать с клиентом 11.

К вашему сведению - Некоторые могут установить последнюю ODP.NET с 2.111.7.20. Сам основной клиент oracle поставляется с 2.111.7.0.. У меня не было успеха с 7.20, но нет проблем с клиентом 7.0.

-121--1390535-

Вы вправе быть обеспокоены этим. К сожалению, я не думаю, что это возможно сделать на 100% безопасно ни при одной из низкоуровневых привязок SSL/TLS, которые я искал для Perl.

По существу, вам необходимо передать имя хоста сервера, который вы хотите подключить к библиотеке SSL, до того, как начнется квитирование. Кроме того, можно организовать обратный вызов в нужный момент и прервать квитирование изнутри обратного вызова, если он не выдан. Люди, пишущие привязки Perl к OpenSSL, казалось, имели проблемы, заставляя интерфейс обратного вызова последовательно.

Метод проверки имени хоста по сертификату сервера также зависит от протокола. Так что это должен быть параметр для любой совершенной функции.

Возможно, потребуется проверить наличие привязок к библиотеке Netscape/Mozilla NSS. Это показалось довольно хорошим в этом, когда я посмотрел на это.

-121--1133019-

Есть ли определенный способ, C99 определить, была ли моя функция передана строковым литералом, чтобы я мог вернуться, не пытаясь его NUL?

Вы не должны.

Ваш API не должен пытаться испортить вещи для вызывающего абонента, только чтобы он прервался позже. Если вызывающий абонент нарушает правила, он должен выяснить, тогда и там.

Если вызывающая сторона передает не изменяемую строку функции, которая ожидает изменяемую строку, она должна segfault. Все остальное - плохой дизайн.

(Добавление: Наилучшая конструкция, конечно, будет заключаться в возврате копии строки, за освобождение которой отвечает вызывающий абонент.)

5
ответ дан 14 December 2019 в 01:06
поделиться

Я дам вам ответы на все, что я только что сделал в Windows Server 2008 R2 которая является 64-разрядной операционной системой. Прикладные номера люкс библиотек, которые я дал, были разработаны с помощью .net 3.5 x86 со старыми библиотеками DLL, и я застрял, потому что я установил новые клиенты x64 из Oracle.

Я нашел следующее: Установите последний клиент x64 из Oracle для Windows Server 2008. Я полагаю, что это будет клиент 2.7.0. При выборе установки убедитесь, что выполнена пользовательская установка, и выберите библиотеки .NET. Настройте файлы tnsnames и протестируйте tnsping на основе источника данных.

Далее, если выполняется 32-разрядное приложение, установите ту же версию клиента для 32-разрядного приложения. Также выполните ту же процедуру установки и выберите ту же домашнюю папку.

После завершения вы обнаружите, что у вас есть одно приложение/продукт с двумя клиентскими каталогами (Client1 и Client2).

При переходе к каталогу windows/assemblies вы обнаружите, что у вас есть ссылка на файл Oracle.DataAccess.dll (x2) с одним для x86 и одним для AMD64.

Теперь, в зависимости от того, есть ли у вас разработчики или вы сами разрабатываете на машине, вы можете быть в порядке здесь, однако, если они используют старые драйверы, то вам нужно выполнить один последний шаг.

Перейдите к папке app\name\product\version\client _ 1\odp.net\publisher policy\2.x. Здесь представлены два файла политика. используйте gacutil/i для установки Policy.2.111.Oracle.DataAccess.dll в GAC. Это перенаправит устаревшие вызовы Oracle ODP на более новые версии. Так что, если кто-то разработал с клиентом 10g, он теперь будет работать с клиентом 11.

К вашему сведению - Некоторые могут установить последнюю ODP.NET с 2.111.7.20. Сам основной клиент oracle поставляется с 2.111.7.0.. У меня не было успеха с 7.20, но нет проблем с клиентом 7.0.

-121--1390535-

Вы вправе быть обеспокоены этим. К сожалению, я не думаю, что это возможно сделать на 100% безопасно ни при одной из низкоуровневых привязок SSL/TLS, которые я искал для Perl.

По существу, вам необходимо передать имя хоста сервера, который вы хотите подключить к библиотеке SSL, до того, как начнется квитирование. Кроме того, можно организовать обратный вызов в нужный момент и прервать квитирование изнутри обратного вызова, если он не выдан. Люди, пишущие привязки Perl к OpenSSL, казалось, имели проблемы, заставляя интерфейс обратного вызова последовательно.

Метод проверки имени хоста по сертификату сервера также зависит от протокола. Так что это должен быть параметр для любой совершенной функции.

Возможно, потребуется проверить наличие привязок к библиотеке Netscape/Mozilla NSS. Это показалось довольно хорошим в этом, когда я посмотрел на это.

-121--1133019-

Ваш chomp должен идеально создать новый ряд и вернуть его. Невозможно определить, был ли вам передан строковый литерал или нет.Я бы предложил использовать следующую подпись для chomp :

char *chomp(const char *s); /* do not modify input parameters */

Или можно создать две различные функции и документировать их для клиентов: используйте chomp для нелитералей и chompl для буквальных последовательностей.

3
ответ дан 14 December 2019 в 01:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: