Načtení 2D pole v C

Re:Načtení 2D pole v C
« Odpověď #30 kdy: 21. 11. 2022, 20:07:32 »
Toto su malicherne nedostatky, ktore sa daju lahko osetrit.
Asi máme jiný názor na to, co jsou malicherné nedostatky. Já vidím tři kritické bezpečnostní chyby.

Keby si mal nejaku sebareflexiu, tak by si namiesto kritiky radsej postol vlastny funkcny kod, co sa ale nestalo.
Kdybys měl nějakou sebereflexi, poděkoval bys za kostruktivní code review.


alex6bbc

  • *****
  • 1 663
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #31 kdy: 21. 11. 2022, 20:48:56 »
tu to je jak v zidovske skole.

je to zacatecnik, takze ukazat jak funguje pole na stacku je v poradku.
a ze to je v realu chyba nevadi, protoze se zaroven muze ukazat co se stane kdyz se prejede nektery index.
jakmile se nauci pointery, pak se muze naucit jak alokovat pole na heapu.
a taky se to muze nejprve naucit pro 100x100 a pozdeji treba pomoci realloc kdyz bude matice rust.
takze povidani o bezpecnostnich chybach je pro takoveho zacatecnika predcasna optimalizace.

Re:Načtení 2D pole v C
« Odpověď #32 kdy: 21. 11. 2022, 21:06:45 »
a ze to je v realu chyba nevadi, protoze se zaroven muze ukazat co se stane kdyz se prejede nektery index.
V reálu je to undefined behavior, takže se může stát cokoliv. Začátečník na to bude koukat a nebude chápat, co se děje. Proto není C vhodný jazyk pro začátečníka. Když už s tím ale někdo začíná, je mu od začátku potřeba vysvětlovat, co je to undefined behavior, protože když to nebude vědět, nebude rozumnět tomu, proč to nefunguje (a může to dělat cokoliv).
jakmile se nauci pointery, pak se muze naucit jak alokovat pole na heapu.
Jde to napsat bezpečně i se staticky alokovaným polem. S tím je vhodné začít.

Ink

  • *****
  • 668
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #33 kdy: 21. 11. 2022, 21:08:04 »
Toto su malicherne nedostatky, ktore sa daju lahko osetrit.
Asi máme jiný názor na to, co jsou malicherné nedostatky. Já vidím tři kritické bezpečnostní chyby.

Keby si mal nejaku sebareflexiu, tak by si namiesto kritiky radsej postol vlastny funkcny kod, co sa ale nestalo.
Kdybys měl nějakou sebereflexi, poděkoval bys za kostruktivní code review.

Je to super, jak z toho školního příkladu chcete udělat skoro produkční kód. Docela by mě zajímalo, co na to původní tazatel. Začal dost bezradně a tohle je jiný level. Mimochodem, co jsou ty tři chyby? Já tam vidím přetečení řádku nebo sloupce a pokud dobře rozumím, co se děje s inicializací toho pole, tak pokud není deklarováno jako static (nebo není vynulováno něčím jako int matrix[MAX_ROWS][MAX_COLS] = {0};), je v případě, že tam ta čísla v některých řádcích chybí (řídká matice?), v některých pozicích nedefinovaná hodnota. Jinak ale přidat dynamickou alokaci podle potřeby, umět načíst dlouhé řádky a je to?

Re:Načtení 2D pole v C
« Odpověď #34 kdy: 21. 11. 2022, 21:22:33 »
Je to super, jak z toho školního příkladu chcete udělat skoro produkční kód.
Je v pořádku, že je ve školním projektu undefined behavior na třech místech? S tím, že jsou to kritické bezpečnostní chyby?

Mimochodem, co jsou ty tři chyby?
  • Buffer overflow na počet řádků.
  • Buffer overflow na počet sloupců.
  • Neinicializovaná matrix. Prakticky celou neinicializovanou matrix je možné vypsat, to je hodně dat. Tím to ale nekončí. V kombinaci s buffer overflow je možné vypsat úplně všechno, co je na zásobníku. Celý zásobník procesu, ke kterému se útočník snadno dostane. To může být fakt hodně potenciálně citlivých dat. Jako chápu, že to většina lidí neřeší, ale kritická bezpečnostní chyba to prostě je.


Ink

  • *****
  • 668
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #35 kdy: 21. 11. 2022, 22:22:58 »
Je to super, jak z toho školního příkladu chcete udělat skoro produkční kód.
Je v pořádku, že je ve školním projektu undefined behavior na třech místech? S tím, že jsou to kritické bezpečnostní chyby?

Souhlasím s tím, co jsi psal výše, tedy že C je jazyk nevhodný pro začátečníky (plný pastí, dodávám).

Mimochodem, co jsou ty tři chyby?
  • Buffer overflow na počet řádků.
  • Buffer overflow na počet sloupců.
  • Neinicializovaná matrix. Prakticky celou neinicializovanou matrix je možné vypsat, to je hodně dat. Tím to ale nekončí. V kombinaci s buffer overflow je možné vypsat úplně všechno, co je na zásobníku. Celý zásobník procesu, ke kterému se útočník snadno dostane. To může být fakt hodně potenciálně citlivých dat. Jako chápu, že to většina lidí neřeší, ale kritická bezpečnostní chyba to prostě je.

Jasně, dík.

alex6bbc

  • *****
  • 1 663
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #36 kdy: 21. 11. 2022, 23:01:17 »
Je to super, jak z toho školního příkladu chcete udělat skoro produkční kód.
Je v pořádku, že je ve školním projektu undefined behavior na třech místech? S tím, že jsou to kritické bezpečnostní chyby?

Souhlasím s tím, co jsi psal výše, tedy že C je jazyk nevhodný pro začátečníky (plný pastí, dodávám).

Mimochodem, co jsou ty tři chyby?
  • Buffer overflow na počet řádků.
  • Buffer overflow na počet sloupců.
  • Neinicializovaná matrix. Prakticky celou neinicializovanou matrix je možné vypsat, to je hodně dat. Tím to ale nekončí. V kombinaci s buffer overflow je možné vypsat úplně všechno, co je na zásobníku. Celý zásobník procesu, ke kterému se útočník snadno dostane. To může být fakt hodně potenciálně citlivých dat. Jako chápu, že to většina lidí neřeší, ale kritická bezpečnostní chyba to prostě je.

Jasně, dík.

na to stejne prijde postupem casu jak bude sam experimentovat.

mikrom

  • ****
  • 370
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #37 kdy: 22. 11. 2022, 00:05:05 »
...
na to stejne prijde postupem casu jak bude sam experimentovat.
presne tak, ak bude s tym experimentovat i tie "kritické bezpečnostní chyby" si najde a odstrani sam   

mikrom

  • ****
  • 370
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #38 kdy: 22. 11. 2022, 00:14:02 »
Otázka zní, zda vůbec používat funkci scanf() a zda by nebylo lepší udělat si vlastní konečný automat a načítat si ta čísla po znacích. Je to dost triviální.

...
Přesto mi nepřijde to řešení s konečným automatem v takovémto případě špatné - vyřeší celkem jednoduše řádkování atd. Znaménko, whitespace apod. jsou úplně v pohodě, ošetřit "správně" invalidní znak je triviální, poskládání integeru z dekadického zápisu je triviální. Řešit hexa číslo je zvláštní, že se int nevejde do mezí typu je sice možné, ale co na tom vyřeší scanf()? Co když někdo napíše do vstupu stočíslicovou hodnotu?

Ked to je pre teba take trivialne tak sem ukaz funkcny kod s tym konecnym automatom  8)

Re:Načtení 2D pole v C
« Odpověď #39 kdy: 22. 11. 2022, 07:56:46 »
presne tak, ak bude s tym experimentovat i tie "kritické bezpečnostní chyby" si najde a odstrani sam
To co jsi vyrobil, je klasický buffer overflow s přepsáním zásobníku a návratové adresy na něm, což je ta úplně nejkritičtější a velmi snadno zneužitelná chyba. Začátečník si nic sám neodstaní a učit ho tohle opravdu není dobrý nápad. Fakt bych nepsal "kritické bezpečnostní chyby" v uvozovkách, tím jenom dokazuješ, že bezpečnosti moc nerozumíš. Doporučil bych ti používat paměťove bezpečný jazyk a držet se od C dál. To bych ostatně doporučil úplně všem, protože praxe ukázala, že psát bezpečný software v C neumí nikdo. Takový člověk prostě neexistuje, nedá se to uhlídat.

Karmelos

  • *****
  • 1 060
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #40 kdy: 22. 11. 2022, 09:29:09 »

Mimochodem, co jsou ty tři chyby?
  • Buffer overflow na počet řádků.
  • Buffer overflow na počet sloupců.
  • Neinicializovaná matrix. Prakticky celou neinicializovanou matrix je možné vypsat, to je hodně dat. Tím to ale nekončí. V kombinaci s buffer overflow je možné vypsat úplně všechno, co je na zásobníku. Celý zásobník procesu, ke kterému se útočník snadno dostane. To může být fakt hodně potenciálně citlivých dat. Jako chápu, že to většina lidí neřeší, ale kritická bezpečnostní chyba to prostě je.

hele a když už vidíš ty chyby, tak bude jiste triviální pro tebe je opravit - postnul bys prosím správný příklad jak to ošetřit? Poukázáním - máš tam chybu - se někdo, kdo o tom nemá ani páru, nic nenaučí... Já třeba v C vůbec nedělám, tak trošku znám základy, ale mikromův příklad mi přišel OK....
Gréta je nejlepší.

Re:Načtení 2D pole v C
« Odpověď #41 kdy: 22. 11. 2022, 09:55:01 »
tu to je jak v zidovske skole.

je to zacatecnik, takze ukazat jak funguje pole na stacku je v poradku.
...
takze povidani o bezpecnostnich chybach je pro takoveho zacatecnika predcasna optimalizace.

Dovolím si mírně nesouhlasit. Jsem javista, v Cčku nedělám (evidentně štěstí pro mne i pro Cčko), ale jak jsem pochopil, tak C je to jazyk efektivní a rychlý, ale psát v něm je jako manipulovat s granátem, s prstem permanentně na pojistce. Souhlasil bych s těmi, co říkají, že např. správné ošetření vstupů tady není jen nadstavba, ale základ vzhledem k povaze "zbraně" se kterou si tady někdo chce začít dobrovolně hrát.

Tak jako tak to je zajímavá a poučná diskuze (nejen pro začátečníka). Přiznávám na rovinu, mne v hlavě hned svítily kontrolky, že přetečení indexů není v cyklech ošetřeno, ale to o té "zubaté" matici a neinicializované paměti mne napadlo až po přečtení komentáře... Mina, na kterou bych třeba sám šlápnul.

Re:Načtení 2D pole v C
« Odpověď #42 kdy: 22. 11. 2022, 12:47:22 »
Čau, zde jsem napsal blog o pointerech a na konci je i příklad na dynamickou alokaci matice:

https://www.abclinuxu.cz/blog/apra/2021/2/ukazatele-jazyk-c

Myslím, že by ti to mohlo hodně pomoct.

Pokud bys měl zájem o konzultace, můj email je rubyac@seznam.cz


Re:Načtení 2D pole v C
« Odpověď #43 kdy: 22. 11. 2022, 13:08:48 »
Diskuse se zajímavě rozjela.
Nicméně všichni mají pravdu!
Avšak je důležité co na to říká ten "student", protože on by to měl psát dle jemu známých a získatelných informacích z přednášek, a ty matice jsou někde ke konci semestru. Tzn. on nemusí ani tušit o nějakých standardních postupech.

Myslel jsem, že na těchto VŠ cvičeních jde spíše o správný postup a jeho objevení, než o ošetření všech možných stavů.

Proto se obávám, že tazatel možná ani nechápe proč se tu diskutuje o pointerech, alokacích atd.

mikrom

  • ****
  • 370
    • Zobrazit profil
    • E-mail
Re:Načtení 2D pole v C
« Odpověď #44 kdy: 22. 11. 2022, 17:26:46 »
Tu je fix predosleho programu:

ocakam dalsie code review  ;)

matrix.c
Kód: [Vybrat]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_ROWS 100
#define MAX_COLS 100
#define MAX_LINE_LENGTH 256

int main()
{
    FILE *fp;
    char data_line[MAX_LINE_LENGTH];
    char *matrix_element;
    int i, j, max_i, max_j;
    int matrix[MAX_ROWS][MAX_COLS] = { 0 };

    fp = fopen("matrix.dat","r");

    printf("Reading data from the file:\n\n");
    max_j = 0;
    i = 0;
    while (fgets(data_line, MAX_LINE_LENGTH, fp) != NULL) {
        // Remove trailing \n
        data_line[strcspn(data_line, "\n")] = 0;

        // split line into matrix elements
        matrix_element = strtok(data_line, ",;\t ");
        j = 0;
        while(matrix_element != NULL) {
            printf("%s ", matrix_element);
            // populate matrix
            if ((i < MAX_ROWS) && (j < MAX_COLS)) {
               matrix[i][j] = atoi(matrix_element);
            }
            j++;
            if (max_j < j) max_j = j;

            matrix_element = strtok(NULL, ",;\t ");
        }
        printf("\n");
        i++;
    }
    max_i = i;
    fclose(fp);
    printf("..Done.\n\n");
    printf("Datafile contains %d rows and %d columns\n\n", max_i, max_j);

    // eventually, adapt maximum indexes to the size of the matrix
    if (max_i > MAX_ROWS) {
        printf("WARNING: matrix contains only %d rows of %d data rows from the file\n",
               MAX_ROWS, max_i);
        max_i = MAX_ROWS;
    }
    if (max_j > MAX_COLS) {
        printf("WARNING: matrix contains only %d columns of %d data columns from the file\n",
               MAX_COLS, max_j);
        max_j = MAX_COLS;
    }

    // now print the matrix
    printf("\nThe matrix is:\n\n");
    for (i = 0; i < max_i; i++) {
        for (j = 0; j < max_j; j++) {
            printf("%d\t", matrix[i][j]);
        }
        printf("\n");
    }

    return 0;
}

Malo by to spracovat aj zubatu maticu, ze chybajuce prvky budu nuly
Kód: [Vybrat]
1  2
5  6  7  8