Fråga om Strängar.

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
SeniorLemuren
Inlägg: 8368
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Fråga om Strängar.

Inlägg av SeniorLemuren »

Ja men meningen är ju att jag skall skriva något på displayen. Jag skickar ju inte en tom sträng för utskrift, det känns ju lite onödigt.
sodjan
EF Sponsor
Inlägg: 43240
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Fråga om Strängar.

Inlägg av sodjan »

> Pascal-strängar är ju inte bättre, om du deklarerar en sträng på 10 tecken så finns det inget
> som hindrar att du skriver 40 i första byten och därmed hamnar långt utanför strängen.

Jag vet inte hur man "skriver i första byten", posta gärna ett exempel. Jag tror
normalt inte att man över huvudtaget kommer åt den, det är helt internt.

Vi kan kolla några små exempel. Först i C:

Kod: Markera allt

$ type str_c.c
# include "stdio"
char *text [5];
void main()
{
  *text = "ABCDEFGH\0";
  printf("%s", *text);
}
$ cc str_c
$ link str_c
$ run str_c
ABCDEFGH
$ 
Vi har alltså sagt att vi vill ha en sträng med 5 tecken, men det är inget problem
att skriva en längre sträng, så länge som vi får det, *C* hindrar oss inte.
Men om vi försöker med att lägga ett tecken lite "längre bort" så spricker det.
Visst, vi får ett "informal message", men det går att undertrycka med en switch...

Kod: Markera allt

$ type str_c.c
# include "stdio"
char *text [5];
void main()
{
  text[100000] = "A";
  printf("%s", *text);
}
$ cc/nowarnings str_c
$ link str_c
$ run str_c
%SYSTEM-F-ACCVIO, access violation, reason mask=04, virtual address=0000000000091A80, PC=00000000000200C8, PS=0000001B
%TRACE-F-TRACEBACK, symbolic stack dump follows
  image    module    routine             line      rel PC           abs PC      
 STR_C  STR_C  main                      1608 00000000000000C8 00000000000200C8
 STR_C  STR_C  __main                    1606 0000000000000064 0000000000020064
                                            0 FFFFFFFF8038BC44 FFFFFFFF8038BC44
%TRACE-I-END, end of TRACE stack dump
$ 
"ACCVIO", d.v.s att vi har försökt skriva där vi inte får skriva, men *försökt*.

Pascal hanterar det lite annorlunda.
Först ett exempel som är OK:

Kod: Markera allt

$ type str_pas.pas
program str(output);
var
  text : string(5);
begin
  text := "ABCDE";
  writeln(text);
end.
$ pas str_pas
$ link str_pas
$ run str_pas
ABCDE
$ 
Fungerar som förväntat. Sedan med ett exempel med en för lång sträng:

Kod: Markera allt

$ type str_pas.pas
program str(output);
var
  text : string(5);
begin
  text := "ABCDEF";
  writeln(text);
end.
$ pas str_pas
$ link str_pas
$ run str_pas
%PAS-F-STRASGLEN, string assignment length error
%TRACE-F-TRACEBACK, symbolic stack dump follows
  image    module    routine             line      rel PC           abs PC      
 STR_PAS  STR  STR                          5 00000000000000C8 00000000000200C8
                                            0 FFFFFFFF8038BC44 FFFFFFFF8038BC44
%TRACE-I-END, end of TRACE stack dump
$ 
Här får vi alltså ett runtime error. Den stora skillnaden är att vi inte ens *försöker*
skriva utanför strängen, Pascal hindrar oss från det.

Kod: Markera allt

STRASGLEN, string assignment length error
  Explanation: Your program attempted to assign to a string variable a
    character string that is longer than the declared maximum length of the
    variable (if the variable’s type is VARYING) or that is not of the same
    length as the variable (if the variable’s type is PACKED ARRAY OF
    CHAR).
  User Action: Correct the program so that the string is of a correct length
    for the variable to which it is being assigned
Det är alltså Pascal runtime miljön som säger ifrån, inte OS'et i sig.
Om man har ett OS som inte har bra minnesskydd, där man t.ex kan skriva
till areaor som har exekverbar kod, så förvärras det hela. D.v.s att man inte
skulle få t.ex en ACCVIO som ovan utan det skulle krascha på ett mer
okontrollerat sätt. Eller så uppstår det en "exploit". C's perkare är en
annan källa till problem, men som sagt, så länge man bara inte kan skriva
till minnesareaor som har exekverbar kod, så är det rellativt lungt.

> För att klara sig undan såna grejer så måste man förutom att hålla reda på strängens nuvarande
längd även hålla reda på den max tillåtna, och då börjar vi får lite avancerade strängstrukturer:)

Ja, poängen är alltså att vissa språk gör det åt dig. :-)
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46872
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Fråga om Strängar.

Inlägg av TomasL »

Det måste betyda att Pascal inte kompilerar till exekverbar kod, utan till pseudokod, vilken sedan körs av en runtime-modul, på samma sätt som BASIC, JAVA .NET mfl.
Skillnaden är ju att C kompilerar till exekverbar kod, alltså finns det ingen runtime-modul som kan övervaka detta.
Sedan har jag en känsla av att varningar för sådana här saker är beroende på vilka verktyg man använder.
Användarvisningsbild
lgrfbs
Inlägg: 7285
Blev medlem: 28 januari 2005, 15:48:53
Ort: X-län
Kontakt:

Re: Fråga om Strängar.

Inlägg av lgrfbs »

I de Pascal dialekter jag hobbyjobbat så kommer det ut riktiga exe filer
Så om kompilatorn i Pascal hindra mig från att göra dumheter ser jag det som en bra funktion.
Användarvisningsbild
TomasL
EF Sponsor
Inlägg: 46872
Blev medlem: 23 september 2006, 23:54:55
Ort: Borås
Kontakt:

Re: Fråga om Strängar.

Inlägg av TomasL »

Jo, men i sodjans exempel så är det ju inte kompilatorn som varnar, eftersom varningen kommer från en runtime-modul vid exekveringen.
(i C-fallet är det väl OSet som varnar)
Användarvisningsbild
SeniorLemuren
Inlägg: 8368
Blev medlem: 26 maj 2009, 12:20:37
Ort: Kristinehamn

Re: Fråga om Strängar.

Inlägg av SeniorLemuren »

Anledningen till att jag längtade efter Pascal var att jag har programmerat mer än 5000 timmar professionellt (Delphi) och aldrig behövt fundera på hur filerna hanteras internt.

Det finns verktyg för att manipulera filerna precis hur man önskar utan att behöva bekymra sig om hur detta hanteras internt. Programmen som genereras av Delphi behöver ingen runtimemodul utan fungerar självständigt.
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Re: Fråga om Strängar.

Inlägg av vfr »

Pascal, rent allmänt, kompilerar till exekverbar kod. Ingen skillnad mot C. Men just i Sodjans exempel så ser det ut som att den varianten av Pascal faktiskt gör så.
xxargs
Inlägg: 10189
Blev medlem: 23 september 2006, 14:28:27
Ort: Södertälje

Re: Fråga om Strängar.

Inlägg av xxargs »

Pascal har väl i alla tider kompilerat till mellankod ala P-kod och sedan är det lite upp till kompileringsmiljön om P-koden behålls i sin helhet och sedan skarva på en runtimemaskin som läser av P-koden i 'exe'-paketet eller kompilera hela vägen till för plattformen och os-miljön passande maskinkod.

Dom flesta språks kompilatorer gör en psedokod under kompileringen och mycket av optimeringsarbetet på den högre nivån görs i det steget och senare från den optimerade mellankoden har man en optimeringsprocess på den från mellankoden genererade maskinkodsmiljön för aktuell plattform och det är då man måste optimera avseende cache-hantering, pipeline, om det det går att parallellisera, om man optimera för fart eller minnessnålhet etc.

Så det är nog ganska korrekt och jämföra med java och motsvarande med Pascal men med skillnaden att Pascal var först med mellan/psedokoden i sitt runtimepaket och var det redan på ABC80-tiden som var den miljön jag första gången stötte på Pascal

Det var där jag också lärde mig att Pascal var ett språk där man lekte och byggde hus med färdiga legobitar - inte hur man snickrade nya legobitar från grunden för att pilla på en viss adress för ett IO som inte finns i några funktionsbibliotek och hantera tidskritiska saker som att skriva en mjukvaru-UART och det som var där som gjorde att i mina ögon Pascal åkte åt sidan som användbart språk på lågnivågrottning eftersom det fans inget lågnivåstöd för att komma åt den förbaskade V24-gränssittet på ABC80 på något sätt (och som var den akuta behovet) som någon visste hur man gjorde (i ABC80-basic kunde man använda PEEK och POKE för att trycka in maskinkod och exekvera det vilket gjorde att basic var mer användbar än Pascal i det här fallet...) ... - några år senare stötte jag på språket C, vilket var mycket bättre i min smak när man skulle grotta lågnivå - dock är 'C' är i många fall att betrakta som högnivåassembler och man måste programmera lika noggrant som just att man håller på med assembler och dess resursallokering och att hålla reda på vad man gör och det är därför som C är dominerande på microcontroller och OS-språk eftersom ett OS handlar mycket om att fingra på riktigt lågnivå och många fall tidkritiskt nästan hela tiden.

C är att betrakta som en mycket vass skalpell som kan göra stordåd med en säker hand - men med osäker hand så kan det bli storslakt då denna inte har några skyddsräcken/småbarnskydd som annars skulle hindra i finliret

Redan på den tiden jag stötte på Pascal runt 1982 eller så var portabiliteten argumentet för att använda P-kod och mycket av resonemanget kändes sedan igen när Java kom och var nytt - och åter igen stötte man på bekymret hur man gjorde själva legobitarna som man sedan skulle byggde med...
sodjan
EF Sponsor
Inlägg: 43240
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Fråga om Strängar.

Inlägg av sodjan »

Kompilatorn jag kör är ingen P-kod variant. Det är en "vanlig" kompilator.
Det syns bl.a på att det hela länkas precis som vanligt.

Skillnaden är att Pascal-koden kollar index till arrayer eller "strängar" i runtime
och att C inte gör det. C försöker bara skriva och OS'et slår den på fingrarna
(om OS'et är smart nog att göra det!). Pascal kommer att kolla indexet *innan*
accessen mot minnet och ge ett runtime error om det är utanför gränserna.

> Jo, men i sodjans exempel så är det ju inte kompilatorn som varnar,

Nej. Men det är ju kompilatorn (och standarden för språket) som har skapat
koden som varnar, så indirekt kommer ju varningen (eller felet) p.g.a av något
som kompilatorn har skapat, så att säga. :-)

> Det måste betyda att Pascal inte kompilerar till exekverbar kod, utan till pseudokod,

Nej, det blir maskinkod direkt. Här är kompilatorlistan

Kod: Markera allt

$ pascal /nooptimize /list /machine_code str_pas
$
$ type STR_PAS.LIS
STR                             Source Code Listing              2-JAN-2014 12:13:45  HP Pascal Alpha V6.1-116          Page 1
01                                                               2-JAN-2014 02:34:22  USER:<JANNE.STRING>STR_PAS.PAS;20

IDC-PL-SL

     0  0             1 program str(output);
     0  0             2 var
     0  0             3   text : string(5);
     0  0             4 begin
     0  1             5   text := "ABCDEF";
     0  1             6   writeln(text);
     0  0             7 end.



















STR                             Machine Code Listing             2-JAN-2014 12:13:45  HP Pascal Alpha V6.1-116          Page 2
01                                                               2-JAN-2014 02:34:22  USER:<JANNE.STRING>STR_PAS.PAS;20

IDC-PL-SL

                                .PSECT  $CODE$, OCTA, PIC, CON, REL, LCL, SHR,-
                                        EXE, NORD, NOWRT
             0000       STR:
23DEFFD0     0000               LDA     SP, -48(SP)
B77E0000     0004               STQ     R27, (SP)
B75E0018     0008               STQ     R26, 24(SP)
B45E0020     000C               STQ     R2, 32(SP)
B7BE0028     0010               STQ     FP, 40(SP)
63FF0000     0014               TRAPB
47FE041D     0018               MOV     SP, FP
47FB0402     001C               MOV     R27, R2
47FE0400     0020               MOV     SP, R0
47E0B401     0024               MOV     5, R1                                                                               ; 000003
B03D0010     0028               STL     R1, TEXT%TYPE                           ; R1, 16(FP)
47E0F411     002C               MOV     7, R17
B23D0014     0030               STL     R17, 20(FP)
23DEFFF0     0034               LDA     SP, -16(SP)
47FE0401     0038               MOV     SP, R1
47FE0400     003C               MOV     SP, R0
B43D0008     0040               STQ     R1, 8(FP)
47E0D413     0044               MOV     6, R19                                                                              ; 000005
4260B7B0     0048               CMPULE  R19, 5, R16
2FFE0000     004C               UNOP
E6000029     0050               BEQ     R16, L$3
             0054       L$2:
A61D0008     0054               LDQ     R16, 8(FP)
47E0B401     0058               MOV     5, R1
42610532     005C               SUBQ    R19, R1, R18
46410CD3     0060               CMOVGT  R18, R1, R19
F2000027     0064               BLBS    R16, L$4
             0068       L$5:
2C100000     0068               LDQ_U   R0, (R16)
4A700372     006C               INSWL   R19, R16, R18
48100240     0070               MSKWL   R0, R16, R0
44120400     0074               BIS     R0, R18, R0
3C100000     0078               STQ_U   R0, (R16)
22100002     007C               LDA     R16, 2(R16)
47F30411     0080               MOV     R19, R17
22420040     0084               LDA     R18, 64(R2)
A7420038     0088               LDQ     R26, 56(R2)
2FFE0000     008C               UNOP
6B5A4000     0090               JSR     R26, OTS$MOVE                           ; R26, R26
A41D0008     0094               LDQ     R0, 8(FP)                                                                           ; 000006
A2200000     0098               LDL     R17, (R0)
4A261731     009C               SLL     R17, 48, R17
4A261691     00A0               SRL     R17, 48, R17
A43D0008     00A4               LDQ     R1, 8(FP)
22410002     00A8               LDA     R18, 2(R1)
A6020030     00AC               LDQ     R16, 48(R2)
47E07419     00B0               MOV     3, R25
A7420050     00B4               LDQ     R26, 80(R2)
A7620058     00B8               LDQ     R27, 88(R2)
2FFE0000     00BC               UNOP
6B5A4000     00C0               JSR     R26, PAS$WRITE_STRING                   ; R26, R26
A6020030     00C4               LDQ     R16, 48(R2)












STR                             Machine Code Listing             2-JAN-2014 12:13:45  HP Pascal Alpha V6.1-116          Page 3
01                              STR                              2-JAN-2014 02:34:22  USER:<JANNE.STRING>STR_PAS.PAS;20

IDC-PL-SL

47E03419     00C8               MOV     1, R25
A7420060     00CC               LDQ     R26, 96(R2)
A7620068     00D0               LDQ     R27, 104(R2)
6B5A4000     00D4               JSR     R26, PAS$WRITELN2                       ; R26, R26
47E03400     00D8               MOV     1, R0                                                                               ; 000007
63FF0000     00DC               TRAPB
47FD041E     00E0               MOV     FP, SP
A75D0018     00E4               LDQ     R26, 24(FP)
A45D0020     00E8               LDQ     R2, 32(FP)
A7BD0028     00EC               LDQ     FP, 40(FP)
23DE0030     00F0               LDA     SP, 48(SP)
6BFA8001     00F4               RET     R26
             00F8       L$3:                                                                                                ; 000005
221FBFF6     00F8               MOV     -16394, R16
000000AA     00FC               GENTRAP
C3FFFFD4     0100               BR      L$2
             0104       L$4:
2C100001     0104               LDQ_U   R0, 1(R16)
4A700AF2     0108               INSWH   R19, R16, R18
48100A40     010C               MSKWH   R0, R16, R0
44120400     0110               BIS     R0, R18, R0
3C100001     0114               STQ_U   R0, 1(R16)
C3FFFFD3     0118               BR      L$5

Routine Size: 284 bytes,    Routine Base: $CODE$ + 0000


                                .PSECT  $LINK$, OCTA, NOPIC, CON, REL, LCL,-
                                        NOSHR, NOEXE, RD, NOWRT

             0000               ; Stack-Frame invocation descriptor
                                Entry point:           STR
                                Entry Length:          28
                                Static Handler:        PAS$HANDLER2
                                Registers used:        R0-R2, R16-R20, R25-R26, R28-FP
                                Registers saved:       R2, FP
                                Fixed Stack Size:      48
00000000                        ; Handler data for PAS$HANDLER2
00000000
00000000
00000000

00000000     0030               .ADDRESS PAS$FV_OUTPUT
             0038               .CODE_ADDRESS OTS$MOVE
44434241     0040               .ASCII  \ABCDEF\
    4645     0044

             0050               .LINKAGE PAS$WRITE_STRING
             0060               .LINKAGE PAS$WRITELN2


















                                Pascal Compilation Statistics    2-JAN-2014 12:13:45  HP Pascal Alpha V6.1-116          Page 4
                                                                 2-JAN-2014 02:34:22  USER:<JANNE.STRING>STR_PAS.PAS;20

PSECT SUMMARY

          Name                     Bytes                         Attributes

  $CODE$                                284    pic, con, rel, lcl,   shr,   exe, nord, nowrt, align(4)
  $LINK$                                112  nopic, con, rel, lcl, noshr, noexe,   rd, nowrt, align(4)


COMMAND QUALIFIERS

  PASCAL/NOOPTIMIZE/LIST/MACHINE_CODE STR_PAS

  /ALIGN=NATURAL
  /NOANALYSIS_DATA
  /ARCHITECTURE=GENERIC
  /ASSUME=(ACCURACY_SENSITIVE,NOBYTE_ALIGNED_POINTERS)
  /CDD_QUAD_TYPE=EMPTY_RECORD
  /CHECK=(BOUNDS,NOCASE_SELECTORS,DECLARATIONS,NOOVERFLOW,
          NOPOINTERS,NOSUBRANGE)
  /CONSTANT=NONE
  /NOCROSS_REFERENCE
  /DEBUG=(NOSYMBOLS,TRACEBACK)
  /NODESIGN
  /NODIAGNOSTICS
  /ENUMERATION_SIZE=LONG
  /NOENVIRONMENT
  /ERROR_LIMIT=30
  /FLOAT=G_FLOAT
  /GRANULARITY=QUADWORD
  /IDENT=01
  /INCLUDE=None Specified
  /LIST=USER:<JANNE.STRING>STR_PAS.LIS;17
  /MACHINE
  /MATH_LIBRARY=ACCURATE
  /OBJECT=USER:<JANNE.STRING>STR_PAS.OBJ;25
  /OPTIMIZE=(LEVEL=0,TUNE=GENERIC,INLINE=NONE)
  /PEN_CHECKING_STYLE=COMPILATION_TIME
  /NOPLATFORMS
  /PSECT_MODEL=NOMULTILANGUAGE
  /SHOW=(DICTIONARY,INCLUDE,HEADER,SOURCE,NOSTRUCTURE_LAYOUT,STATISTICS)
  /NOSTANDARD
  /TERMINAL=NONE
  /NOTIE
  /USAGE=(NOUNCERTAIN,UNINITIALIZED,NOUNUSED,VOLATILE,EMPTY_RECORDS,
          PACKED_ACTUALS,UNSUPPORTED_CDD,NOPERFORMANCE,NONGRNACC,NOUNCALLABLE)
  /WARNINGS
  /ZERO_HEAP






















                                Pascal Compilation Statistics    2-JAN-2014 12:13:45  HP Pascal Alpha V6.1-116          Page 5
                                                                 2-JAN-2014 02:34:22  USER:<JANNE.STRING>STR_PAS.PAS;20

COMPILER INTERNAL TIMING

        Phase                          CPU    Elapsed    Page      I/O
                                     seconds  seconds   faults    count
    Initialization                      0.01     0.00       16        0
    Source analysis                     0.00     0.00       50        1
    Symbol Table and IL Generation      0.00     0.00       28        0
      Symbol Table Conversion           0.00     0.00        8        0
      CIL Generation                    0.00     0.00       18        0
      CIL Fixup                         0.00     0.00        0        0
    Pointer type alias analysis         0.00     0.00        0        0
    IL expansion                        0.00     0.00       28        0
    Optimization                        0.00     0.00        0        0
      Dominator tree construction       0.00     0.00        0        0
      Loop dominator insertion          0.00     0.00        0        0
      Lifetime analysis                 0.00     0.00        0        0
      IDEF computation                  0.00     0.00        0        0
      DATAFLOW computation              0.00     0.00        2        0
      Loop transforms                   0.00     0.00        0        0
      BR loop/branch optimization       0.00     0.00        0        0
      Strength reduction                0.00     0.00        0        0
      Loop unroll/Loop optimization     0.00     0.00        0        0
      Test replacement                  0.00     0.00        0        0
      Profitability determination       0.00     0.00        0        0
      Profitability reordering          0.00     0.00        0        0
      Use propagation                   0.00     0.00        0        0
      Split lifetime analysis           0.00     0.00        0        0
      Base Binding                      0.00     0.00        0        0
    Code Generation                     0.00     0.00       59        0
      Context analysis                  0.00     0.00       23        0
      Register History                  0.00     0.00        0        0
      Temporary allocation              0.00     0.00        7        0
      Code emission                     0.00     0.00       20        0
    Final                               0.00     0.00       18        0
      Peepholing                        0.00     0.00        5        0
      Final flow analysis               0.00     0.00        0        0
      Object scheduling                 0.00     0.00        0        0
      Branch/jump resolution            0.00     0.00        7        0
    Object module generation            0.00     0.00       19        0
    DST generation                      0.00     0.00        0        0
    Listing                             0.00     0.00        3        0
  Compiler totals                       0.03     0.12      368       25

COMPILATION STATISTICS

  CPU time:          0.03 seconds
  Elapsed time:      0.12 seconds
  Pagefaults:         368
  I/O Count:           25
  Source lines:         7

  14000 lines per CPU minute.
$ 
Jag kan inte läsa koden rakt av, men det känns som att kollen av stränglängden görs här:

Kod: Markera allt

47E0D413     0044               MOV     6, R19                                                                              ; 000005
4260B7B0     0048               CMPULE  R19, 5, R16
2FFE0000     004C               UNOP
E6000029     0050               BEQ     R16, L$3
...
...
             00F8       L$3:                                                                                                ; 000005
221FBFF6     00F8               MOV     -16394, R16
000000AA     00FC               GENTRAP
C3FFFFD4     0100               BR      L$28
Jag har inte kollat, men det är sannolikt "-16394" som genererar det aktuella
felmeddelandet ("%PAS-F-STRASGLEN - string assignment length error").

Om jag ändrar till "text : string(7);" i koden så blir det "CMPULE R19, 7, R16" ovan
så det verkar hänga ihop.

Som sagt, poängen är i alla fall att en del språk har mer inbyggda skydd mot
att "skjuta sig i foten", så att säga. I många fall gör det även exploits som
använder "buffer overflow" svårare.
Nerre
Inlägg: 27166
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Fråga om Strängar.

Inlägg av Nerre »

Men i ditt exempel använder du ju "riktiga" strängfunktioner. Det är ju fullt jämförbart med att använda strcat() i C.

C är ju ett språk på "lägre nivå" än Pascal, det går ju att gå åt andra hållet och titta på t.ex. perl (där det väl i princip är omöjligt att skriva utanför strängen, eftersom perl allokerar det utrymme som behövs automatiskt).

Hur blir det om du istället för en loop som indexerar strängen och lägger in ett tecken i taget?
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Fråga om Strängar.

Inlägg av johano »

TomasL skrev:Det måste betyda att Pascal inte kompilerar till exekverbar kod, utan till pseudokod, vilken sedan körs av en runtime-modul, på samma sätt som BASIC, JAVA .NET mfl.
Skillnaden är ju att C kompilerar till exekverbar kod, alltså finns det ingen runtime-modul som kan övervaka detta.
Sedan har jag en känsla av att varningar för sådana här saker är beroende på vilka verktyg man använder.
Öh nä, det betyder bara att Pascalkompilatorn lägger in lite extrakod för att kolla att tilldelningen är giltig, har ju absolut ingenting med pseudokod öht. att göra.

/johan
sodjan
EF Sponsor
Inlägg: 43240
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Fråga om Strängar.

Inlägg av sodjan »

> Det är ju fullt jämförbart med att använda strcat() i C.

Ja, jag insåg att det haltar lite där. :-)
Mitt C exempel skulle behöva justeras lite.

Men är det inte så att även strcat (och liknande) har problem
med att det kan "skriva utanför gränserna"? Kom det inte ett
antal alternativa rutiner ("safe"-någonting) får något tag sedan
som skulle göra det bättre?

Grundpoängen kvarstår dock, vissa programspråk har bättre
skydd mot skitfel än andra "by design". C är ett dåligt språk
i detta avseende (också :-) ).
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Fråga om Strängar.

Inlägg av johano »

sodjan skrev: Det är alltså Pascal runtime miljön som säger ifrån, inte OS'et i sig.
Om man har ett OS som inte har bra minnesskydd, där man t.ex kan skriva
till areaor som har exekverbar kod, så förvärras det hela. D.v.s att man inte
skulle få t.ex en ACCVIO som ovan utan det skulle krascha på ett mer
okontrollerat sätt. Eller så uppstår det en "exploit". C's perkare är en
annan källa till problem, men som sagt, så länge man bara inte kan skriva
till minnesareaor som har exekverbar kod, så är det rellativt lungt.
Nja, håller inte med. De värsta buggarna är ju inte de som får programmet att krascha, de upptäcker man ju rätt fort, det är värre med de som orsakar logiska fel och felaktiga data utan att krascha eller lämna varningar/felmeddelanden, de kan lurka kvar i åratal...

Och os:et kommer ju bara kunna fånga minnesfel när programmet skriver till minne det inte äger eller som är skyddat (readonly/executable). Men följande lilla kodsnutt visar ju en klassisk bugg som inte leder till en direkt krasch eller felmeddelande,bara att programmet inte gör som förväntat

Kod: Markera allt

{
char s[5];
char Status = 1;
 
 strcpy(s, "abcde");
 
 if(Status)
    printf("%s", s);
    
 return 0;
}
Här kommer då alltså variabeln Status skrivas över med Nullterminering i strcpy()-anropet med följd att if-satsen inte blir sann och inget skrivs ut.

/johan
Användarvisningsbild
ylle
Inlägg: 669
Blev medlem: 5 oktober 2006, 20:18:27
Ort: örebro

Re: Fråga om Strängar.

Inlägg av ylle »

Är det scanf_s och liknande du tänker på? http://msdn.microsoft.com/en-us/library/w40768et.aspx

"Reads formatted data from the standard input stream. These versions of scanf, _scanf_l, wscanf, _wscanf_l have security enhancements"
sodjan
EF Sponsor
Inlägg: 43240
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Fråga om Strängar.

Inlägg av sodjan »

> Men följande lilla kodsnutt visar ju en klassisk bugg...

Exakt! Det är det jag menar. :-) Strcpy skriver alltså *6* tecken till s, och
det hade (t.ex) Pascal larmat för. Dock i runtime, men i alla fall...

> Och os:et kommer ju bara kunna fånga minnesfel när programmet skriver till minne det inte äger eller som är skyddat (readonly/executable).

Allt minne som den *kan* skriva till bör vara "read-only non-executable" som default
oavsett om det "ägs" av processen eller inte. Om man vill skriva "self-modifed"
kod så får man kode specifikt för det (d.v.s skapa sections som är "read/write, execute").
Skriv svar